Cache in Drupal 8

Cache is the important part of a development process. Everybody uses cache, but not everybody is able to manage it. Let’s have a look at what a cache is and how you can use it for your site on Drupal 8. We will also go into details and talk about Cache API, auto-placeholdering, and the BigPipe module.

→ This post is about an older version of Drupal. It can still be useful to you but you can also check out our latest article about Drupal 10 here: What Do You Need to Know About Drupal 10?

About cache

A сache is a hardware or a software component that stores frequently requested pages or the parts of the pages, and these pages can be shown to users with fewer resources and with a faster speed than usual.

What happens to the page while it’s loading? System functions and files of all modules are turned on, settings and variables are initialized, a theme is loaded and hooks are implemented. When the cache is enabled, basic system settings load and the page loads from the cache. Obviously, in this case, page loads faster.

The cache is the important component of site optimization. It’s one of the key items in the assessment of Google PageSpeed application.

Cache in Drupal 8 1

Cache in Drupal 8

What about cache and optimization in Drupal 8?

By default, Drupal 8 enables two modules: Internal Page Cache and Internal Dynamic Page Cache. Internal Page Cache caches pages for anonymous users. Internal Dynamic Page Cache caches contents of the page except for the personalized pieces, so they can be used for the anonymous and authorized users. Each object of the page contains metadata, and this piece of metadata tells the Internal Dynamic Page Cache module if it has to cache the page or not. You can change default metadata by Cache API.

Cache API

Сaching properties could be set to any object. A cache has 3 properties. If you want to change default cache settings you can use them. These properties are the following.

Context is a cache dependency on context, that creates variations when the render arrays are being generated. For example, one page for two different users may look different. In this case, the context is the user. These contexts may be the user permissions,  language settings or URL parameters.

Tags define what object the cache depends on. Using cache tags you can automatically invalidate cached pages.

Max-age is the maximum time that the cache is stored.

'#cache' => [
   'contexts' => ['languages', 'timezone'],
   'tags' => ['node:5', 'user:3'],
   'max-age' => Cache::PERMANENT,
 ],

Constructing any object, you can change the cache settings to make it more flexible. You need to set your settings in rendering. In practice, it looks like that:

$renderer = \Drupal::service('renderer');

$config = \Drupal::config('system.site');
$current_user = \Drupal::currentUser();

$build = [
 '#prefix' => '',
 '#markup' => t('Hi, %name, welcome back to @site!', [
   '%name' => $current_user->getUsername(),
   '@site' => $config->get('name'),
 ]),
 '#suffix' => '',
 '#cache' => [
   'contexts' => [
     'user',
   ],
 ],
];
$renderer->addCacheableDependency($build, $config);
$renderer->addCacheableDependency($build, \Drupal\user\Entity\User::load($current_user->id()));

Besides, you can get caching parameters of an entity by using a standard method:

\Drupal::entityManager()->getDefinition('node')->getListCacheContexts();
$view->getEntityType()->getListCacheTags();
$node->getEntityType()->isRenderCacheable();

Auto-placeholdering

For the best possible cacheability of the highly dynamic parts of a page, you can use auto-placeholdering. For that use a #lazy_builder callback:

$build[$id]['links'] = array(
 '#lazy_builder' => [
   'comment.lazy_builders:renderLinks',
   [
     $entity->id(),
     $view_mode,
     $entity->language()->getId(),
     !empty($entity->in_preview),
   ]
 ],
 '#create_placeholder' => TRUE,
);

Drupal generates placeholders for dynamic content, and only at the very last moment, it is replaced with actual content. This allows Internal Dynamic Page Cache module to render the cache fragments except for the parts of the page that are too dynamic for caching.

BigPipe

But we have one problem - Drupal shows a whole page at once, i. e. a user waits for all the parts of the page to be loaded. For solving this problem BigPipe has been developed. It’s an experimental module, which you can see in version 8.1 of Drupal.

As you saw in the video, the magic BigPipe does is the speed increase through the loading of the cached parts of the page first and displaying them as soon as they are ready. The last to load are the dynamic parts of the page. 

Conclusion

A cache is the important part of website optimization. If you want your users to get pages as quickly as possible, then enable the cache. In Drupal 8 caching has been considerably improved. If you want your site to work more quickly and you know how do it, then join the development of the BigPipe module, write your issue on drupal.org about the cache, become an active member of the community. Together we are stronger and could contribute more significantly.

You might also like