The Fastest Drupal Ever is Here!
Drupal 8
- Utilises BigPipe to send quick content (text, cached items) first. Slow content last.
- Page renders faster. Slow content filled in as/when ready.
- Similar technology, SmallPipe, works without JS.
Make the web fast
- Great user experience, pages load fast for 1 user
- Great user experience, pages load fast for [n] concurrent users
- Time to first byte + Asset loading + Rendering + JS exec time == minimal
Optimization
- Remove as much work as possible from the critical path
- ACD = Avoid, Cache, Defer
Cache invalidation
- Drupal 7 clears whole page cache when an element of the page changes
- Drupal 8 invalidates instantaneously
- Everything declares what it varies by
- Allows caching authenticated user content securely
D8 makes it simple
- Does all the caching logic internally
- If you give Drupal information then it can be smarter about is decisions
- Formalizes things in a “language” to make these things fast
- Potentially can be backported to D7
Dependencies
- D7 did not track dependencies
- e.g.
drupal_add_css()
, drupal_add_js()
- Global state: impossible to cache
#attached
asset libraries solves that
- e.g.
url()
output depends on
<front>
config
- HTTPS config
- Clean URL config
- Current site in multisite
- …
- Impossible to
cache invalidate
- To make it easier:
Renderer:addCacheableDependency($build, $dependency);
Correct invalidation in D8
- Cache tags (data dependencies)
- Cache contexts (context dependencies)
- Cache max-age (time dependencies)
- Cacheability bubbled during rendering!
Thought process
- I’m rendering something. That means I need to think about cacheability?
- Is this smething thats expensive to render, and therefore is worth caching?
- Does the representation of the thing I’m rendering vary per combination of permissions, per URL, per interface…
- If yes, cache context
$build['#cache']['contexts'][] = 'user.permissions';
$build['#cache']['contexts'][] = 'url';
- What causes the representation of the thing i’m rendering to become outdated
- When does the representation of the thing I’m rendering become outdated?
- If yes, cache max-age
$build['#cache']['max-age'][] = Cache::PERMANENT;
- All relevant objects provide cacheability metadata
Page cacheability
- Pages are static and dynamic
- Dynamic content slows the page down
- Gets slower with more content and more users. More unique data which is uncacheable.
- D8 solves this with placeholders (in core).
- Removes all dynamic content from page, placeholders there instead. Static content remains, as it is cacheable.
Lazy builder
$build['complex_thing'] = [
'#lazy_builder' => ['callback', [
'arg1',
'arg2',
]],
];
- Effective successor to
hook_pre_render()
- Builds a render array and returns it
- Output must solely depend on the input (arguments)
- Able to render in isolation
- This is what enables BigPipe
Pitfalls
- Don’t forget to add cache tags!
- Uncacheable? Don’t forget to set max-age to zero