Closed (fixed)
Project:
Drupal core
Version:
8.0.x-dev
Component:
views.module
Priority:
Major
Category:
Bug report
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
27 May 2015 at 20:51 UTC
Updated:
30 Jun 2015 at 06:04 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
yched commentedLooks like we just need to merge BubbleableMetadata instead of CacheableMetadata ?
I'm not too fond of the
if (isset($build_list['#cache']) || isset($build_list['#attached']) || isset($build_list['#post_render_cache'])) {it feels like brittle abstraction leaking about what constitutes a bubbleable property.
I kind of fear the perf impact of unconditionally merging for each field in each row, tough :-/
Comment #2
dawehnerIs that the only property we care about? I'm curious whether we could sort of solve things generically
Comment #3
dawehnerInteresting fix!!
Comment #4
jibranLet's add tests as well.
Comment #5
yched commentedTurns out #2474121: CacheableMetadata should get BubbleableMetadata's merge/applyTo/createFromRenderArray/createFromObject methods switched from merging BubbleableMetadata to only merging CacheableMetadata, which is basically what the patch reverts. Asked for feedback over there.
Comment #6
yched commentedHard to tell, but I'd tend to think that if you chose to not render an element but only render children individually, then the only #properties you are interested in keeping are the bubbleable ones ? The other properties from the parent shouldn't affect the rendering of the children, right ?
Comment #7
fabianx commentedThis is fine, but needs tests.
#post_render_cache will be hopefully gone soon, then there is only #attached and #cache, which is way more sane.
Comment #8
yched commentedThinking about it a bit more, what I think happened is :
- #2099137: Entity/field access and node grants not taken into account with core cache contexts did :
if (isset($parent['#cache'])) {
BubbleableMetadata::createFromRenderArray($parent)->merge($children)->applyTo($children)
}
Meaning : it only bothered about #cache, and used BubbleableMetadata just because CacheableMetadata didn't have the proper create / merge / apply helper methods natively back then.
- #2474121: CacheableMetadata should get BubbleableMetadata's merge/applyTo/createFromRenderArray/createFromObject methods added those missing methods, and since the code snippet above only seemed to care about #cache, it moved it to CacheableMetadata ionstead it now had the create / merge / apply features
- We in fact do want to take care of anything bubbleable (#attached in addition to #cache), so should revert to BubbleableMetadata create / merge / apply, but updating the surrounding if() so that it doesn't only trigger if there's a #cache property
Comment #9
yched commentedWould be cleaner indeed. What do you guys think of adding BubbleableMetadata::hasMetadata($build) / CacheableMetadata::hasMetadata($build) ?
Tests : sure, but I won't be able to do that today - anyone feel free to beat me to it ;-)
Comment #10
yched commentedWith a test. Interdiff is the test-only.patch
Still interested in feedback from @Fabianx / @Wim Leers about #9 (adding BubbleableMetadata::hasMetadata($build) / CacheableMetadata::hasMetadata($build)) ?
Comment #11
yched commentedAs a side note:
The test formatter attaches 'foo/fake_library' on its render array.
When bubbled to the overall view render array rendering 5 entities, this results in:
$view_build['#attached']['library'] = ['foo/fake_library', 'foo/fake_library', ... 5 times]
I'm probably missing something, but I would have expected the bubbled ['#attached']['library'] to contain a merged de-duplicated list, instead of repeating a library once per child that attaches it ?
Comment #12
yched commentedComment #13
wim leersLet's instead do this:
isset()checksBubbleableMetadata::createFromRenderArray($build_list)out of the loopComment #16
yched commented@Wim : See #2 - I'm a bit worried about the perf cost of doing the merge for each delta in each column in each result row, while 95% formatters don't have anything to bubble anyway. That's why #2099137: Entity/field access and node grants not taken into account with core cache contexts added that isset() check in the first place before merging, I guess.
Will try to run a couple profiling runs.
For now, reuploading the patches from #10 for the bot hiccup.
Comment #17
wim leersIt's going to be render cached anyway, so … the amortized cost would be negligible.
Comment #18
yched commentedWith @Wim's proposal from #13.
Profiled a view listing 50 nodes, 10 number fields each (with a formatter that doesn't add any #attached or #cache), I couldn't get xhprof-kit to get consistent diffs (varied between +0.2% and +1.2% cpu, but more consistently towards the former). That was with render cache disabled, I'm fine with calling this a wash when bringing render cache in the mix :-)
Comment #20
dawehnerI think these numbers will get much better, once we have the optimization to not perform the heavy merging logic, as it will be much cheaper, but 500 times.
Comment #21
wim leersYep, #2483433: Optimize CacheableMetadata::merge() + BubbleableMetadata::merge() will make that 0.2–1.2% increase (pre-render caching) even smaller.
RTBC+1
Comment #22
yched commentedOh, I wasn't aware of #2483433: Optimize CacheableMetadata::merge() + BubbleableMetadata::merge(), so yeah, definitely +1 on the latest approach :-)
Comment #23
yched commentedAdded beta evaluation summary
Comment #24
yched commentedAaaand it seems I can't write basic HTML
Comment #26
yched commentedTestbot fluke ? Rebased on latest HEAD just in case.
Comment #27
yched commentedBack to RTBC
Comment #28
alexpottCommitted 46e2034 and pushed to 8.0.x. Thanks!
I agree with the beta evaluation this is a major bug.
Fixed on commit.
This looks funky that
foo/fake_libraryis added multiple times. I guess uniqueness is sorting out later. Not the fault of this patch though.Comment #30
yched commentedAgreed. I asked about that in #11 above, but got no answer :-)
@wim, what do you think ?
Comment #31
wim leersYes, uniqueness is applied at a later stage: when it is actually rendered. The code building render arrays generally just appends to
[#attached][library]. The only way to make it not have duplicates at that stage is by requiring the code building render arrays use a helper function. Which is too late to require at this stage, and goes against the ingrained habits for no good reason AFAICT :)Comment #32
yched commented@wim: Thanks, makes sense. I guess we don't deduplicate each time we merge/bubble up, but rather once just before attaching the actual assets at the page level, right ? That probably makes sense perf-wise :-)
I guess the test could explicitly call that deduplicate step to make the list of $expected libraries closer to what you'd intuitively expect, but I'm not sure there would be much sense in that.
Also, I have to confess when writing the test I didn't really figure out at which step in the Views pipeline the nested attachments got bubbled to the top-level of the render array. For the sake of the test, just obtaining a render array with the expected bubbled '#attach's on top was good enough for me.
Comment #33
wim leersYep, related to that is #2483433: Optimize CacheableMetadata::merge() + BubbleableMetadata::merge(). It moves the existing attachment merging tests from a KTB to a unit test, but one of the things it tests is that when attachments are merged, no deduplication is happening yet.