Commit 6951f4d7 authored by catch's avatar catch
Browse files

Issue #3225328 by mxr576, Berdir, longwave: Improve page performance by...

Issue #3225328 by mxr576, Berdir, longwave: Improve page performance by sorting cache contexts/tags on-demand
parent e4ce9936
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -28,8 +28,7 @@ class Cache {
   */
  public static function mergeContexts(array ...$cache_contexts) {
    $cache_contexts = array_unique(array_merge(...$cache_contexts));
    assert(\Drupal::service('cache_contexts_manager')->assertValidTokens($cache_contexts));
    sort($cache_contexts);
    assert(\Drupal::service('cache_contexts_manager')->assertValidTokens($cache_contexts), sprintf('Failed to assert that "%s" are valid cache contexts.', implode(', ', $cache_contexts)));
    return $cache_contexts;
  }

@@ -53,7 +52,6 @@ public static function mergeContexts(array ...$cache_contexts) {
  public static function mergeTags(array ...$cache_tags) {
    $cache_tags = array_unique(array_merge(...$cache_tags));
    assert(Inspector::assertAllStrings($cache_tags), 'Cache tags must be valid strings');
    sort($cache_tags);
    return $cache_tags;
  }

+5 −0
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@ class ContextCacheKeys extends CacheableMetadata {
   *   The cache context keys.
   */
  public function __construct(array $keys) {
    // Domain invariant: cache keys must be always sorted.
    // Sorting keys warrants that different combination of the same keys
    // generates the same cache cid.
    // @see \Drupal\Core\Render\RenderCache::createCacheID()
    sort($keys);
    $this->keys = $keys;
  }

+6 −2
Original line number Diff line number Diff line
@@ -159,8 +159,12 @@ public function onRespond(ResponseEvent $event) {
      // Expose the cache contexts and cache tags associated with this page in a
      // X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags header respectively.
      $response_cacheability = $response->getCacheableMetadata();
      $response->headers->set('X-Drupal-Cache-Tags', implode(' ', $response_cacheability->getCacheTags()));
      $response->headers->set('X-Drupal-Cache-Contexts', implode(' ', $this->cacheContextsManager->optimizeTokens($response_cacheability->getCacheContexts())));
      $cache_tags = $response_cacheability->getCacheTags();
      sort($cache_tags);
      $response->headers->set('X-Drupal-Cache-Tags', implode(' ', $cache_tags));
      $cache_contexts = $this->cacheContextsManager->optimizeTokens($response_cacheability->getCacheContexts());
      sort($cache_contexts);
      $response->headers->set('X-Drupal-Cache-Contexts', implode(' ', $cache_contexts));
      $max_age_message = $response_cacheability->getCacheMaxAge();
      if ($max_age_message === 0) {
        $max_age_message = '0 (Uncacheable)';
+5 −5
Original line number Diff line number Diff line
@@ -296,8 +296,8 @@ protected function assertBlockRenderedWithExpectedCacheability(array $expected_k
    // - the built render array;
    $build = $this->getBlockRenderArray();
    $this->assertSame($expected_keys, $build['#cache']['keys']);
    $this->assertSame($expected_contexts, $build['#cache']['contexts']);
    $this->assertSame($expected_tags, $build['#cache']['tags']);
    $this->assertEqualsCanonicalizing($expected_contexts, $build['#cache']['contexts']);
    $this->assertEqualsCanonicalizing($expected_tags, $build['#cache']['tags']);
    $this->assertSame($expected_max_age, $build['#cache']['max-age']);
    $this->assertFalse(isset($build['#create_placeholder']));
    // - the rendered render array;
@@ -307,9 +307,9 @@ protected function assertBlockRenderedWithExpectedCacheability(array $expected_k
    $cid = implode(':', $expected_keys) . ':' . implode(':', \Drupal::service('cache_contexts_manager')->convertTokensToKeys($final_cache_contexts)->getKeys());
    $cache_item = $this->container->get('cache.render')->get($cid);
    $this->assertNotEmpty($cache_item, 'The block render element has been cached with the expected cache ID.');
    $this->assertSame(Cache::mergeTags($expected_tags, ['rendered']), $cache_item->tags);
    $this->assertSame($final_cache_contexts, $cache_item->data['#cache']['contexts']);
    $this->assertSame($expected_tags, $cache_item->data['#cache']['tags']);
    $this->assertEqualsCanonicalizing(Cache::mergeTags($expected_tags, ['rendered']), $cache_item->tags);
    $this->assertEqualsCanonicalizing($final_cache_contexts, $cache_item->data['#cache']['contexts']);
    $this->assertEqualsCanonicalizing($expected_tags, $cache_item->data['#cache']['tags']);
    $this->assertSame($expected_max_age, $cache_item->data['#cache']['max-age']);

    $this->container->get('cache.render')->delete($cid);
+2 −4
Original line number Diff line number Diff line
@@ -92,8 +92,7 @@ public function testCacheTags() {
      'config:field.storage.comment.comment_body',
      'config:user.settings',
    ];
    sort($expected_cache_tags);
    $this->assertEquals($expected_cache_tags, $build['#cache']['tags']);
    $this->assertEqualsCanonicalizing($expected_cache_tags, $build['#cache']['tags']);

    // Create a comment on that entity. Comment loading requires that the uid
    // also exists in the {users} table.
@@ -140,8 +139,7 @@ public function testCacheTags() {
      'config:field.storage.comment.comment_body',
      'config:user.settings',
    ];
    sort($expected_cache_tags);
    $this->assertEquals($expected_cache_tags, $build['#cache']['tags']);
    $this->assertEqualsCanonicalizing($expected_cache_tags, $build['#cache']['tags']);

    // Build a render array with the entity in a sub-element so that lazy
    // builder elements bubble up outside of the entity and we can check that
Loading