One of the last blocks that needs to become cachable is SystemBreadcrumbBlock.

Updated: Comment #0

Problem/Motivation

The breadcrumbs block is currently not cacheable at all.

Proposed resolution

Cache breadcrumbs on a per-URL, per-role, per-language basis. This, combined with the fact that proper cache tags should be set by the used breadcrumb builder (BreadcrumbBuilderInterface::build()), would ensure that we can cache the breadcrumb block forever, since any change that could affect the breadcrumbs to be rendered would invalidate the corresponding render cache entries.

Unfortunately, all of the breadcrumb classes don't even comply with the interface they're implementing: they're returning an array of rendered links, not a render array! Therefore, it is currently impossible to set cache tags!

Remaining tasks

Allow breadcrumb builders to bubble up cache tags.

User interface changes

None.

API changes

None.

CommentFileSizeAuthor
#1 cacheable_breadcrumbs-2232609-1.patch2.22 KBWim Leers
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Wim Leers’s picture

Status: Active » Needs review
FileSize
2.22 KB
jibran’s picture

Unfortunately, all of the breadcrumb classes don't even comply with the interface they're implementing: they're returning an array of rendered links, not a render array! Therefore, it is currently impossible to set cache tags!

Maybe we can create a sub task for this issue and discuss. I can help in fixing the issue.

Wim Leers’s picture

Issue summary: View changes
Issue tags: -sprint
dawehner’s picture

  1. +++ b/core/modules/system/lib/Drupal/system/Plugin/Block/SystemBreadcrumbBlock.php
    @@ -35,4 +35,23 @@ public function build() {
    +   * {@inheritdoc}
    +   */
    +  public function defaultConfiguration() {
    +    // It's the responsibility of each breadcrumb builder to set the appropriate
    +    // cache tags.
    +    return array('cache' => array('max_age' => \Drupal\Core\Cache\Cache::PERMANENT));
    +  }
    +
    +  /**
    +   * {@inheritdoc}
    +   */
    +  protected function getRequiredCacheContexts() {
    +    // The 'Breadcrumbs' block must be cached per URL, role and language: the
    +    // breadcrumbs themselves depend on the current URL, may not be accessible
    +    // to users of a certain role, and may be translated.
    +    return array('cache_context.url', 'cache_context.user.roles', 'cache_context.language');
    +  }
    +
    

    Do we really want to cache it, even we know already that its existence depends on access? These links can use any route access checkers ...

  2. +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermBreadcrumbBuilder.php
    @@ -40,6 +40,14 @@ public function build(array $attributes) {
     
    +    // @todo BreadcrumbBuilderInterface::build() says:
    +    //   * @return array
    +    //   *   A render array for the breadcrumbs. Returning an empty array will
    +    //   *   suppress all breadcrumbs."
    +    //  BUT… as you can see above, we're actually returning an array of links.
    +    //  And that's in fact the only way this can work, because what we return
    +    //  here, is being assigned to '#breadcrumb', which may only contain links…
    +
    

    This certainly will be replaced by #2314599: Use title/url instead of l() for building breadcrumb

dawehner’s picture

Status: Needs review » Needs work

I really hope we don't treat performance over security here. In case we do, have fun with chx :P

Wim Leers’s picture

Sorry, this shouldn't be marked as needing review. That's why I removed the "sprint" tag. This was only a very rough, extremely outdated, first pass :)

Low priority for now.

Wim Leers’s picture

joelpittet’s picture

+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermBreadcrumbBuilder.php
@@ -40,6 +40,14 @@ public function build(array $attributes) {
+    //  here, is being assigned to '#breadcrumb', which may only contain links…

If we want a text, aka non-link breadcrumb, is that do-able?

fgm’s picture

joelpittet’s picture

@fgm merci bien;)

jibran’s picture

I think we can re-evaluate this once #2483183: Make breadcrumb block cacheable is in and decide whether it's a duplicate or maybe we can further improve the subsystem.

Wim Leers’s picture

Status: Needs work » Closed (duplicate)

AFAICT this is a duplicate of #2483183: Make breadcrumb block cacheable.