Drupal 8. BigPipe

Vitalii Zinenko

vzinenko@adyax.com

  1. What is BigPipe
  2. BigPipe in Drupal 8
  3. Drupal BigPipe capability
  4. How to Use
  5. How to Code
  6. Results
  7. Turbolinks

What is Big Pipe?

google answer

Drupal 8 caching

  1. Pages without cache (very slow)
  2. Page cache (unpersonalized pages)
  3. Dynamic Page cache (personalized pages)
  4. BigPipe

 

BigBipe

Included in Drupal 8.1!

authored Wim Leers (Acquia — @wimleers — wimleers.com)

BigPipe environment requirements

  • Apache

    • Apache with mod_php

    • Apache with PHP-FPM (FastCGI)

      • disable FastCGI buffering

  • Nginx with PHP-FPM

    • disable FastCGI buffering
  • IIS

  • Varnish

    • disables buffering only for BigPipe responses

How it works in Drupal 8

Cacheability metadata

tags, contexts, max-age + bubbling

Isolated rendering

#lazy_builder callbacks (guarantee isolation)

Auto-placeholdering

if poorly cacheable and renderable in isolation

Placeholder strategies

default = replace before sending complete response (1 flush)

BigPipe = replace after sending unpersonalized response (N flushes)

How it works in Drupal 8

BigPipe sends:

  • initial page directly from Dynamic Page Cache
  • rendered BigPipe placeholders, in DOM order

PAGE
  |- BLOCK A (max-age = infinite, tags = [x], contexts = ['user.permissions'])
  |- BLOCK B (max-age = infinite, tags = [y], contexts = ['user.permissions'])
  |- BLOCK C (max-age = 0)
  |- BLOCK D (max-age = infinite, tags = [], contexts = ['user'])
  |- BLOCK E (max-age = infinite, tags = [z], contexts = ['user.roles'])

How it works in Drupal 8

IMPROVED RENDER API

 

rendering in isolation: "lazy builders"

auto-placeholdering

  renderer.config:
     auto_placeholder_conditions:
       max-age: 0
       contexts: ['session', 'user']
       tags: []

How it works in Drupal 8

1. I'm rendering something. That means I must think of cacheability.

Cacheability of render arrays

 

2. Is this something that's expensive to render, and therefore is worth caching?
If the answer is "yes", then what identifies this particular representation of the thing I'm rendering? Those are the cache keys.

How it works in Drupal 8

Cacheability of render arrays

 

3. Does the representation of the thing I'm rendering vary per combination of permissions, per URL, per interface language, per … something? Those are the cache contexts.
Note: cache contexts are completely analogous to HTTP's Vary header.

How it works in Drupal 8

Cacheability of render arrays

 

4. What causes the representation of the thing I'm rendering become outdated?
I.e. which things does it depend upon, so that when those things change, so should my representation? Those are the cache tags.

How it works in Drupal 8

Cacheability of render arrays

 

5. When does the representation of the thing I'm rendering become outdated?
I.e. is the data valid for a limited period of time only?
That is the max-age (maximum age). It defaults to "permanently (forever) cacheable" (Cache::PERMANENT). When the representation is only valid for a limited time, set a max-age, expressed in seconds. Zero means that it's not cacheable at all.

How it works in Drupal 8

Cacheability of render arrays

 

" Cache contexts, tags and max-age must always be set, because they affect the cacheability of the entire response. Therefore they "bubble": parents automatically receive them.

Cache keys must only be set if the render array should be cached. "

Animation by @shawnmmccabe

How to use

  • Install BigPipe module for Drupal 8.0.*
  • Drupal 8.1 included as experimental module

 

no configurations

Try online Demo

BigPipe demo site

Code

Cacheability metadata

 

 

cache keys - ['node', 5, 'teaser']

cache contexts ['timezone']['currency']

cache tags ['node:5', 'user:3', 'file:4', 

                                'config:filter.format.basic_html']

cache max-age

Code

// Drupal 7.
function current_currency() {
  return [
    '#markup' => get_currency('uah','usd'),
  ];
}
// Drupal 8: now with cacheability metadata.
function current_currency() {
  return [
    '#cache' => ['max-age' => 5], //→ cacheable for 5 seconds
    '#markup' => get_currency('uah','usd'),
  ];
}

Code

function current_currency() {
 return [
   '#cache' => [
     'keys' => ['temperature'], //→ triggers render caching
     'max-age' => 5,
   ],
   '#currency' => array('uah', 'usd'),//→ used in #pre_render
   '#pre_render' => [
     ['current_curr_pre_render'], //→ does not run on cache hit
   ],
 ];
}

function current_curr_pre_render($build) {
  $build['#markup'] = get_currency($build['#latlong']);
  return $build;
}

Code

function current_currency() {
 return [
   '#cache' => [
     'keys' => ['currency'],
     'max-age' => 5,
   ],
   '#lazy_builder' => [
     'current_currenct_lazy_builder', //→ callback
     ['uah', 'usd'],               //→ primitive args for callback
   ],
 ];
}

function current_currenct_lazy_builder($curr_1, $curr_2) {
  $latlong = new LatLong($country, $city));
  return ['#markup' => get_currency($country, $city)];
}

RENDER CACHEABLE & ISOLATED

 No cache

BigPipe + cache blocks enabled

BigPipe + cache blocks enabled

stop near ~ 0.1 sec

BigPipe.

no accelerators. no improvenments

Must also to see

Turbolinks

RefreshLess

https://www.drupal.org/project/refreshless

need to apply patch (included in module)

RefreshLess

Developer tool Renderviz

Questions?

Vitalii Zinenko

vzinenko@adyax.com

Links:

Kyiv Drupal Camp 2016

By Vitali Zinenko

Kyiv Drupal Camp 2016

  • 1,750