Render caching
Drupal 8
Sascha Grossenbacher
Caching?
Goal
Improve performance
How
Store the result of slow calculations so that they do not need to be executed again
API Basics
Set (Key, Data, Expiration, Tags)
Get (Key)
Delete (Key)
Invalidate (Tags)
Three types of caching
#1 Page cache
Every anonymous user sees exactly the same page.
The page cache stores full pages in the cache, with huge performance gains for anonymous users.
Internal vs. External Page Cache
Internal Page Cache
The internal page cache in Drupal 8 is a module
Page cache off: 13.11 requests / second
Page cache on: 280.09 requests / second
( Fresh installation, empty frontpage, PHP 5.6)
External Page Cache
Edge cache like Varnish or a Service like fastly, cloudfront
Thousands of requests / second, distributed
Expiration time setting in Drupal 8 only affects external caches, internal is always indefinite
#2 Data caching
Internal data, Direct usage of the Cache API
Module list, Configuration, Entity storage, Plugins
#3 Render Cache
Large parts of the website are the same for authenticated users
Comparable to D7 block caching, views/panel output cache
Render Caching
The challenge
There are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
http://martinfowler.com/bliki/TwoHardThings.html
The 4 Questions
Cache Key
Cache Tags
Cache Contexts
Max Age
https://www.drupal.org/developing/api/8/render/arrays/cacheability
Cache Key
Is my data worth caching?
If yes, what identifies my data?
Example: Displaying node 1 with the teaser view mode
Cache Contexts
Does my output vary?
Per theme, language, user, permissions, query arguments, timezone, ...
Cache contexts are hierachical: user, user.permissions
Danger: Not setting the correct contexts can result in sensitive data being shown to normal users
Example: Displaying a link based on a permission check for the current user
Cache Tags
What things does my data depend on?
What changes require that my data is regenerated?
Example: Displaying node 1 with the teaser view mode
Tags required for: the node, node author, image style, text format, ...
Max Age
When does my output become outdated?
Permanent vs. N seconds vs. Not cacheable
Objects know their tags/context
Displaying entities/views/... automatically adds the correct tags and contexts
Relevant when building your own render arrays:
hook_node_view()
Custom blocks
Metadata Bubbling
Cache Tags are Everywhere
... and awesome
The internal page cache respects cache tags too!
Even external caching can respect cache tags through a header
Invalidations can be implemented in Varnish and are supported by fastly.com
Views Custom Cache Tag (NP8)
Views cache plugin
Makes the used list cache tag configurable
Requires code to define/invalidate cache tags, for example:
node:$type
node:region:$region
node:section:$section
Invalidation example
Changes
- A new node (7) is created in the "Sport" section
Invalidations: node:sport, node_list - Node 2 is changed
Invalidations: node:2, node:sport, node_list
Next request
#post_render_cache (Placeholders)
Sometimes, small parts of e.g. a node vary for every user
Embedded forms, Personalized information, CSRF tokens
Example: Flag links inside nodes
Client side additions
Similar to #post_render_cache, but in JS
Works even with page cache, but requires additional requests (use Local Storage)
HTML 5 data attributes
Example: Paywall hints
<article data-paywall-entity-id="node/12"
Summary
Partial caching in Drupal 7 is usually time based and hard to invalidate. Creating/Changing content invalidates the whole page cache.
With Drupal 8, the render and cache usually has no expiration time and is immediately invalidated. With little to no custom code.
Questions?
Render Caching
By Sascha Grossenbacher
Render Caching
- 3,034