Problem/Motivation

A number of things happened in core, especially the cacheablity of block access and visibility conditions so that page manager can cache the whole page including access checks *and* become compatible with smartcache.

Proposed resolution

Simplify the cache metadata building, no longer add every visible block to the page cache tag.

Additionally, we'll also need to somehow add the cacheablity metadata of visiblity conditions, similar to BlockAccessControlHandler (both for the display selection and for block access when it is added back).

Remaining tasks

User interface changes

API changes

Data model changes

Comments

berdir’s picture

Status: Active » Needs review
StatusFileSize
new4.13 KB

Here's a POC patch, haven't updated the tests yet.

Status: Needs review » Needs work

The last submitted patch, 1: simplify-caching-access-2528370-1.patch, failed testing.

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 1: simplify-caching-access-2528370-1.patch, failed testing.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new14.96 KB
new12.61 KB

I'm so glad I waited for the prophesize patch :) This was a million times easier to debug and fix. Someone needs to update EntityManagerTest to use this :)

This patch
* Fixes the unit tests.
* Since the big if is gone, merges the two test methods together again and makes one block accessible and the other one not.
* Uses the new and awesome addCacheableDependency()
* Optimizes page cacheability metadata by merging block cacheability metadata to avoid cache redirects.
* Adds a bunch of comments, mostly in the test to explain what's going on and why things are expected the way they are.

Status: Needs review » Needs work

The last submitted patch, 5: simplify-caching-access-2528370-5.patch, failed testing.

berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new14.94 KB
new2.15 KB

That's why we need integration tests :p such stupid. As I said, never actually tried this ;)

wim leers’s picture

  1. +++ b/src/Plugin/DisplayVariant/BlockDisplayVariant.php
    @@ -126,15 +127,13 @@ class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInte
    +    // @todo Make the whole display a pre_render callback to fully benefit from
    +    //   render caching and avoid to re-calculate contexts and access for all
    +    //   blocks.
    

    Sounds great :)

  2. +++ b/src/Plugin/DisplayVariant/BlockDisplayVariant.php
    @@ -142,7 +141,9 @@ class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInte
    +    $cacheability = CacheableMetadata::createFromRenderArray($build['regions'])
    +      ->addCacheableDependency($page);
    
    @@ -160,12 +161,12 @@ class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInte
    +        $cacheability->addCacheableDependency($access);
    
    @@ -183,39 +184,25 @@ class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInte
    +        $cacheability->addCacheableDependency($block);
    

    Why have a $cacheability variable if you can just apply it to the underlying render array?

    Every one of these should become:

    $this->renderer->addCacheableDependency($build, $dependency);
    

    What am I missing?

  3. +++ b/tests/src/Unit/BlockDisplayVariantTest.php
    @@ -200,15 +80,17 @@ class BlockDisplayVariantTest extends UnitTestCase {
    +    $block2->getCacheContexts()->shouldNotBeCalled();
    +    $block2->getCacheMaxAge()->shouldNotBeCalled();
    +    $block2->getCacheTags()->shouldNotBeCalled();
    

    <3

    +1000 for prophesize()!

  4. +++ b/tests/src/Unit/BlockDisplayVariantTest.php
    @@ -257,35 +145,32 @@ class BlockDisplayVariantTest extends UnitTestCase {
    +    // metadata is accessible blocks is merged into to avoid cache redirects
    

    s/is/of/

    "merged into" -> into what?

berdir’s picture

2. As discussed, one important reason is unit tests. We'd have to mock that whole method to work like it really does. Also, I simply don't like that API, it creates two cacheability metadata objects, clones one and then merges everything together. addCacheableDependency() is so much nicer and faster. And we're possibly creating a quite a lot of blocks here.

3. Slightly improved the comment. It is merged into the page-level #cache array, which is "page cacheability metadata", would like to avoid repeating that.

berdir’s picture

berdir’s picture

Opened a follow-up: #2558261: Move code in BlockDisplayVariant::build() to a #pre_render.

Would be nice to get this in so I can work on that. As commented there, this would give me a 20% performance improvement for a specific page in a project.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
  1. +++ b/src/Plugin/DisplayVariant/BlockDisplayVariant.php
    @@ -126,15 +127,13 @@ class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInte
    +    // @todo Make the whole display a pre_render callback to fully benefit from
    

    Nit: By "the whole display", you really mean "this entire function", right? Perhaps the @todo really belongs in build()'s docs?

  2. +++ b/src/Plugin/DisplayVariant/BlockDisplayVariant.php
    @@ -142,7 +141,9 @@ class BlockDisplayVariant extends VariantBase implements ContextAwareVariantInte
    +    $cacheability = CacheableMetadata::createFromRenderArray($build['regions'])
    

    s/$cacheability/$page_cacheability/, to make it clearer what you're calculating the cacheability of?


Would be nice to get this in so I can work on that. As commented there, this would give me a 20% performance improvement for a specific page in a project.

Sounds awesome!

dsnopek’s picture

I haven't tested this but a quick read through the patch looks great! I think this will also simplify the patch on #2511570: Remove Drupal\page_manager\Plugin\PageAwareVariantInterface. So, RTBC+1!

tim.plunkett’s picture

Status: Reviewed & tested by the community » Needs work
berdir’s picture

Status: Needs work » Needs review
StatusFileSize
new14.69 KB

With pleasure! ;)

The other test method was between the two that were merged together again here. That confused git quite a bit ;)

tim.plunkett’s picture

Status: Needs review » Fixed

Thanks!

  • tim.plunkett committed 8b8a495 on 8.x-1.x authored by Berdir
    Issue #2528370 by Berdir: Simplify block caching and allow to cache the...

The last submitted patch, 16: , failed testing.

Status: Fixed » Needs work

The last submitted patch, 16: simplify-caching-access-2528370-16.patch, failed testing.

tim.plunkett’s picture

Status: Needs work » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.