Needs work
Project:
Metatag
Version:
8.x-1.x-dev
Component:
Code
Priority:
Major
Category:
Task
Assigned:
Issue tags:
Reporter:
Created:
13 Mar 2019 at 06:06 UTC
Updated:
22 Jul 2025 at 00:14 UTC
Jump to comment: Most recent, Most recent file

Comments
Comment #2
larowlanA lot of the time is spent in token generation.
There is a static cache, so even if we don't generate these now, we're going to have to re-generate them later, but I wonder if those are cached in the page cache and these aren't because its running in a pre_render callback.
With this attached, metatag_entity_view_alter no longer shows up in my call stack
Comment #3
larowlanWith primed render cache, this no longer shows up at all.
Comment #5
larowlanComment #6
larowlanWill try to address the fails
Comment #7
larowlanah, so there is a plugin id/name mismatch so we just need to map canonical url
Comment #8
larowlanSo I think perhaps something in token generation was resulting in the render caching being bypassed for the entity view.
Because with this patch, the entity view alter hook doesn't seem to run at all on a warmed cache, before it did
Comment #10
larowlanComment #11
berdirwhy is the !duplicates check inside the foreach?
that doesn't seem right :) (null)
this gets $entity and $context, but the static cache doesn't consider those arguments.
Also, isn't renaming this function a BC break?
Ah, the old function is readed down here, that's a bit confusing, can we move this up to have an easier to read patch?
this seems like a pretty strange API, entity is passed in twice?
Comment #12
wim leers🥳
That's a very good hunch!!! See #2525910: Ensure token replacements have cacheability + attachments metadata and that it is bubbled in any case. That added
to
\Drupal\Core\Utility\Token::replace(), and as you can see, it automatically bubbles the cacheability to the global render context if the optional parameter is not provided.And …
\Drupal\metatag\MetatagManager::generateRawElements()does not provide it:Except that
$this->tokenServiceis not\Drupal\Core\Utility\Token, but\Drupal\metatag\MetatagToken, but that's effectively just a decorator:So, yes, I think your hunch was onto something 👏:
\Drupal\metatag\MetatagManager::generateRawElements()should be passing in that optional parameter.I don't have time to dig in more right now, but it's of course interesting that you solved your problem without addressing that. Perhaps that's because there's multiple invocations of that method and your static cache prevents the invocation that is happening in head while executing
\metatag_page_attachments(), hence indirectly also avoiding the bubbling onto the current render context?Comment #13
damienmckennaThis needs additional work, right? Reading #11 and #12 it seems like the test coverage might need to be expanded slightly to ensure that meta tags output correctly on the second page request, not just the first request, right?
Comment #14
larowlanYep, putting it back on my list
Comment #15
larowlangenerateRawElementsis public (probably shouldn't be, but that's a 2.x API break).So here's a go at handling the cache metadata properly, adds a BC layer in case there's someone calling that method somewhere.
Needs profiling to ensure the issue is fixed.
Comment #16
larowlanHere's a version against 8.x-1.11
Comment #18
larowlanwith bubbleablemetadata clobbers #attached
Comment #20
damienmckennaAny thoughts on the test failures?
Comment #21
wim leers#20: The test expectations are not yet cache-aware, and hence need updating.
Comment #22
larowlanworking on test changes
Comment #23
larowlanThis is actually pretty major, 8% performance hit on any site that has any tokens that use cache metadata. Coupled with up to 11% for sites with paragraphs (or any entity without a canonical route) we got in the other issue, these are some nice wins for a lot of Drupal sites out there.
Added a new test to go with it demonstrating what we didn't have here.
Comment #24
larowlanLooks like there is a fail in HEAD now, restui module isn't in the module's test dependencies
Comment #25
larowlanComment #27
larowlanThat's the same fail as in HEAD, so this is ready for 👀 now
Comment #28
damienmckennaI pushed up a fix for the restui thing, I must have committed the wrong patch or something as the one I uploaded to the issue (#3123578) didn't have that line. Sorry about that.
Comment #29
larowlanthanks! I'll kick off another run
Comment #30
larowlan🎉green
Comment #31
berdirI find deprecation messages for contrib hard as there are usualy no clear rules when and if at all there will be a 2.x branch :) Probably should be 2.0.0 now? And following the new naming, should this be metatag:8.x-1.13 and metatag:2.0.0 respectively?
I don't quite understand how this affects caching. I'll try to do some profiling on my own over the next days.
Comment #32
berdir@larowlan: Something just doesn't quite add up to me here :)
For me, despite having 45 calls to this function, it's only 3.6% (24ms) of the total page request with the current stable version of metatag. I see the red warning icon in your screenshot about xdebug being enabled, that *massively* slows down everything, the whole page was 2x as fast for me after disabling xdebug (this function was 38ms). Note that many small function calls also tend to be over-reported with blackfire, due to the overhead that each function call has.
What scenario are you measuring exactly, authenticated or not, render caches enabled?
Are you using any special tokens or so with special cacheability? Are you using property tokens ([node:field:value] instead of [node:field])? That can massively speed up token generation because the non-property tokens actually render the field into HTML through a formatter and then remove that again.
What I can reproduce on my site here is that the entity view alter hook *is* being called on what should be a render-cached page, so there is indeed something interesting going on.
But, I don't quite see why collecting the metadata like that would change whether or not elements are cached. We are currently in a pre render callback, so it should IMHO more or less end up in the same place. Unless we collect it but then lose the metadata as a result of this change, which would explain it being faster, but would also defeat the purpose of doing it :) Looking at it a bit closer, I'm pretty sure that's exactly what's happening. In _metatag_remove_duplicate_entity_tags(), it then has $metatag_attachments['#cache'] but the function has no return value, it only uses that to unset stuff in $build. If you'd actually merge things over into $build then I'm quite certain you'd end up right where you started.
I suspect that the reason you and I don't see render caching happening for the node is a different one. For you, it actually might be a token, and if that's the case, it would be the correct and expected behavior. For me, it's something else (possibly around access/translation stuff, aware of some issues there on this project), so this patch doesn't actually improve anything :)
What cacheability metadata do you see with this patch in your $cache? You might want to set a breakpoint on the foreach that does the token replace and detect which token causes that and make it use a different token :)
so, I'm reasonably certain this is a won't fix and your problem is somewhere else, in a specific token.
Comment #33
damienmckennaThank you for the really detailed review, Berdir.
Putting this back to Needs Work as it seems this needs some further analysis.
Comment #34
johnwebdev commentedOn cool cache the time spent in
metatag_entity_view_alterwas ~700ms for me. However, as suggested in #32That led to a 37% improvement. We also have a special token that I'll need to check as well. Will report back.
Comment #35
berdirYou could also try my patch in #2955407: Static caching for token processing; iconv_substr() is super slow
Comment #36
mbovan commentedAs suggested by @Berdir, I created a separate issue to focus on extending the
generateRawElements(). This includes related parts from #23.See #3175269: Pass optional bubbleable metadata parameter to generateRawElements to avoid issues with early rendering and JSON:API.
Comment #37
singularoRe-rolled patch to work with latest release.
Comment #38
kim.pepperComment #39
joseph.olstadComment #40
berdirSee #32, the patch isn't correct and shouldn't be used. No need to reroll and you shouldn't use it. See my suggestions and related issue if you're looking for a performance improvement around metatags.
Comment #41
hemlata99 commentedUpdated patch based on 8.x-1.x with correct bubbleable metadata handling.
Comment #42
hemlata99 commentedthis comment been deleted
Comment #43
hemlata99 commentedthis comment has been deleted
Comment #44
hemlata99 commentedUpdated patch based on 2.1.x with correct bubbleable metadata handling.