Problem/Motivation

See parent issue's issue summary.

Proposed resolution

Automatically set #create_placeholder (added by #2478483: Introduce placeholders (#lazy_builder) to replace #post_render_cache) whenever max-age = 0 is bubbled up.

This will be based on Fabianx' prototype/PoC work over at #2478483-8: Introduce placeholders (#lazy_builder) to replace #post_render_cache and #2469431-31: BigPipe for auth users: first send+render the cheap parts of the page, then the expensive parts.

Remaining tasks

  1. Required base API: First get #2478483: Introduce placeholders (#lazy_builder) to replace #post_render_cache in.
  2. Auto-placeholdering for #lazy_builder without bubbling: #2543332: Auto-placeholdering for #lazy_builder without bubbling
    1. Auto-placeholdering for #lazy_builder with bubbled cache contexts and cache tags: #2543334: Auto-placeholdering for #lazy_builder with bubbling of contexts and tags
      1. Auto-placeholdering for #lazy_builder with bubbled max-age: #2559847: Auto-placeholdering for #lazy_builder with bubbling of max-age.
      2. Auto-placeholdering without #lazy_builder: #2543336: Auto-placeholdering without #lazy_builder
  3. Conversions:
    1. #2543554: Clean up Help & Statistics blocks
    2. Convert BlockViewBuilder to use #lazy_builder: #2543340: Convert BlockViewBuilder to use #lazy_builder (but don't yet let context-aware blocks be placeholdered)

User interface changes

None.

API changes

TBD, but likely none.

Comments

Wim Leers’s picture

Title: [PP-1] Auto-placeholdering » Auto-placeholdering
Wim Leers’s picture

Issue summary: View changes

Clarifying tasks and why they're not API changes.

Fabianx’s picture

In the best case here or in follow-ups we do:

- #2469431-31: BigPipe for auth users: first send+render the cheap parts of the page, then the expensive parts (comment 31)

I outlined the 4 cases there that need to be supported for auto-placeholdering to be the most effective and especially not needing to rely on lazy builders, when the information is cacheable.

Wim Leers’s picture

Title: Auto-placeholdering » [meta] Auto-placeholdering
Issue summary: View changes

Attribution & process

I've drawn from Fabianx' prototype/PoC work over at #2478483-8: Introduce placeholders (#lazy_builder) to replace #post_render_cache and #2469431-31: BigPipe for auth users: first send+render the cheap parts of the page, then the expensive parts. But, only for general/initial guidance: I've gone my own way, for two reasons:

  1. independently coming to the same conclusions is an important validation factor
  2. aggressively simplifying the difficult-to-understand-because-PoC code is essential, for this to qualify to be committed to core

In the past two weeks, I've spent many, many hours on this. Since it is crucial for both #2429617: Make D8 2x as fast: Dynamic Page Cache: context-dependent page caching (for *all* users!) and #2469431: BigPipe for auth users: first send+render the cheap parts of the page, then the expensive parts, both of which are able to deliver massive speed-ups. This issue (auto-placeholdering), just like those two (SmartCache & BigPipe) heavily exploit cacheability metadata.

(I just want to mention again that I now believe even more that a tool like http://wimleers.com/blog/renderviz-prototype will both be A) crucial for efficient Drupal 8 development, B) put Drupal 8 miles ahead of other frameworks. I think/hope I'll be able to work on that as the next big thing after SmartCache/BigPipe.)

Overview & recap

Now, let's get down to business. Auto-placeholdering is conceptually trivial: any render array that has a #lazy_builder (meaning it can be built in isolation) and that has poor cacheability (max-age=0 or high-cardinality cache contexts such as user or session), is turned into a placeholder. As a (intended) consequence, this means that poor cacheability is cordoned off: it does not "poison" its containing elements (its parents), and therefore does not poison the rest of the page/response. Which then means that SmartCache can effectively cache the skeleton (the entire HTML response minus the parts that are placeholdered) of … pretty much every HTML response in Drupal! That then also has as a consequence that BigPipe will be able to just get entire skeletons directly from SmartCache, then just needing to render the placeholders and stream them to the user. In other words: this issue is crucial for both SmartCache & BigPipe.

But … some parts of it implementation are not at all trivial, because to have auto-placeholdering work for every use case, we need it to also work for both bubbled high-cardinality cache contexts (#2429257: Bubble cache contexts) and bubbled max-age=0. This means that we need to make the RenderCache service smarter: if a render cached element is noticed to have poor cacheability, and it is for an element with a #lazy_builder, then it can choose to return a placeholder instead of the render cached element. Which means that the system automatically learns which parts of the page are uncacheable.

Finally, it is actually technically possible to remove the #lazy_builder requirement. Which means all of the above applies to anything that is render cacheable. But, there are some caveats here: race conditions (what if the render cache item is invalidated after we already determined it is available and therefore safe to placeholder?) that can only be resolved with fairly complex solutions (if the render cache item disappeared, we'll have to re-execute the original request to regenerate the render cache item — yes that's scary). So we'll leave that for a follow-up. For now, the above should suffice.

Results

I've split it up into four issues.

  1. Auto-placeholdering for #lazy_builder without bubbling: #2543332: Auto-placeholdering for #lazy_builder without bubbling
    1. Auto-placeholdering for #lazy_builder with bubbled cache contexts (and max-age=0, though we may want to split that part off): #2543334: Auto-placeholdering for #lazy_builder with bubbling of contexts and tags
      1. Auto-placeholdering without #lazy_builder: #2543336: Auto-placeholdering without #lazy_builder
  2. Convert BlockViewBuilder to use #lazy_builder: #2543340: Convert BlockViewBuilder to use #lazy_builder (but don't yet let context-aware blocks be placeholdered)

Issues 1 (without bubbling) and 2 (blocks) can be done in parallel. Issue 1.1 (with bubbling) is blocked on 1, and 1.1.1 is blocked on 1.1. Issue 1.1.1 can be postponed to 8.1.

Wim Leers’s picture

Category: Task » Plan
Wim Leers’s picture

#2543332: Auto-placeholdering for #lazy_builder without bubbling and #2543340: Convert BlockViewBuilder to use #lazy_builder (but don't yet let context-aware blocks be placeholdered) — which can happen in parallel — now both have green patches.

In doing the latter, we also discovered the need for #2543554: Clean up Help & Statistics blocks, which also has a green patch.

Patch for #2543334: Auto-placeholdering for #lazy_builder with bubbling of contexts and tags is coming up next, have it working locally already.

Wim Leers’s picture

Wim Leers’s picture

Issue summary: View changes

#2543554: Clean up Help & Statistics blocks also landed.

IS updated to more clearly show remaining tasks.

Wim Leers’s picture

Issue summary: View changes
Wim Leers’s picture

#2543340: Convert BlockViewBuilder to use #lazy_builder (but don't yet let context-aware blocks be placeholdered) and #2543334: Auto-placeholdering for #lazy_builder with bubbling of contexts and tags are now blocked on review. Both have green patches and have already gotten some reviews. We just need to push them to the finish line.

If the first lands, we'll already have basic auto-placeholdering of blocks in D8 core, which will be sufficient for SmartCache to land: #2429617: Make D8 2x as fast: Dynamic Page Cache: context-dependent page caching (for *all* users!) :)

Wim Leers’s picture

Issue summary: View changes

Split off the portion of #2543334: Auto-placeholdering for #lazy_builder with bubbling of contexts and tags that handled bubbled max-age to a separate issue: #2559847: Auto-placeholdering for #lazy_builder with bubbling of max-age — like originally predicted when I wrote this issue summary :)

Wim Leers’s picture

joelpittet’s picture

Version: 8.0.x-dev » 8.1.x-dev

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.