Sites which run the Metatag module end up parsing tokens an awful lot each page request. It has been reported that for one site that enabling Metatag (with a number of meta tags being output) causes the page request to jump from a few hundred milliseconds to over eight seconds.

Looking at the stats on the page request, most of the processing is happening while processing the tokens, specifically iconv_substr():
Most of the processing happens in iconv_substr()

I'd like to suggest some sort of optional static caching be added to the token generation system, so that it doesn't end up processing the same "[node:summary]" token for a single entity five+ times on the same page request, that instead it is executed once and then statically cached.

Comments

DamienMcKenna created an issue. See original summary.

berdir’s picture

Status: Active » Closed (won't fix)

The token replacement is in core, node_tokens() is in core too. And static caching is tricky, because based on what/how do you invalidate it exactly? the same node could suddenly have different values?

Maybe it's metatag module that should do the caching here? You're the one calling get_tags_from_node() twice for the same node? :)

Also, it looks like you're relying on the symfony mb_strlen() polyfill, which certainly isn't going to help with performance. You should enable the mbstring extension.

Feel free to raise the issue in core, but I think this is up to the caller, aka you.

damienmckenna’s picture

Project: Token » Metatag
Status: Closed (won't fix) » Active
Issue tags: -metatag

That's fair enough, lets add the static caching to Metatag.

We'll also document that the mbstring extension should be enabled in PHP.

kkohlbrenner’s picture

Hi @DamienMcKenna,

I am curious the status of this issue? I see not much activity has occurred here, too.

damienmckenna’s picture

The solution is to enable mbstring in your server's PHP confguration, other things are work-arounds that haven't been worked on yet.

berdir’s picture

Status: Active » Needs review
StatusFileSize
new1.86 KB
new42.12 KB

Here's a simple patch that adds static caching for each unique value that is passed to Token::replace().

In my case, that's saving 12 Token::replace() calls, although not all of them actually have tokens.

Savings aren't huge, but if you have more identical tokens they could easily be bigger. It's fairly common to reuse the same tokens many times, e.g. for title, og title, twitter title.

Status: Needs review » Needs work

The last submitted patch, 6: metatag-token-cache-2955407-6.patch, failed testing. View results

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new1.92 KB
new643 bytes

Didn't check for $entity being NULL.

johnwebdev’s picture

StatusFileSize
new111.71 KB
new112.57 KB

Here's another profiling.

Before:

After:

51ms.

moshe weitzman’s picture

Token generation leads the mass.gov performance report (and thats not a good place to be). I cant say if this patch is a good idea but I do know the need is large.

berdir’s picture

That's not exactly very useful feedback :)

Do you have any numbers on how much "leading" exactly is, how much this patch helps and also, have you seen my comments on e.g. #2935187: Token parsing massively slows down Drupal 8; document that mbstring is recommended and #3039650: Metatag discards cacheability metadata, results in a performance hit on how to speed up token generation? one of the most important things is to use property tokens, so :value and so on, that apparently saved 37% for @johnwebdev.

How much this patch benefits will depend directly on how many duplicated metatag tokens you're using.

sime’s picture

StatusFileSize
new317.5 KB

newrelic token pressure

sime’s picture

I'm not following this issue closely (i'm just trying to reduce the number of fields we have, which impacts this problem), but I'd be happy to follow direction and start testing patches.

sylus’s picture

Just rerolling the patch.

damienmckenna’s picture

Moshe: any updates on the performance testing from mass.gov?

moshe weitzman’s picture

Sorry, no time for additional profiling. We plan to get rid of metatag one day. Its not metatag's fault per se. Token processing is slow, and we have way too many fields. Its hard to know what fields are unused, after a site has been active for a few years.

joseph.olstad’s picture

Apparently there's also performance differences depending on how the tokens are used.
#3162152: Document performance gains from property tokens

joseph.olstad’s picture

patch no longer applies against the latest release. Is this patch now deprecated? I looked at the conflict it's pretty significant.

andypost’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
sylus’s picture

I could be wrong but i think this isn't needed anymore since metatag is roughly doing same logic now.

    if (!isset($this->processedTokenCache[$entity_identifier])) {
      $metatag_tags = $this->tagPluginManager->getDefinitions();
      foreach ($tags as $tag_name => $value) {
          ...
          $this->processedTokenCache[$entity_identifier][$tag_name] = $tag->multiple() ? explode(',', $value) : $value;
        }
    }
berdir’s picture

Status: Needs work » Closed (duplicate)

Yes, #2862747-16: Tokens to access individual meta tag values confirms that it basically took this patch and merged it into that issue over there.