Verified Commit b957382d authored by Alex Pott's avatar Alex Pott
Browse files

Issue #1014086 by catch, nod_, martin107, quietone, dww, mariacha1, Spokje,...

Issue #1014086 by catch, nod_, martin107, quietone, dww, mariacha1, Spokje, yogeshmpawar, pounard, Wim Leers, mfer, mikeytown2, mbutcher, moshe weitzman, Fabianx, borisson_, alexpott, donquixote, sun, andypost, dawehner: Stampedes and cold cache performance issues with css/js aggregation
parent 047faa3e
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -1218,10 +1218,10 @@ services:
    arguments: ['@current_user']
  ajax_response.attachments_processor:
    class: Drupal\Core\Ajax\AjaxResponseAttachmentsProcessor
    arguments: ['@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler']
    arguments: ['@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler', '@language_manager']
  html_response.attachments_processor:
    class: Drupal\Core\Render\HtmlResponseAttachmentsProcessor
    arguments: ['@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler']
    arguments: ['@asset.resolver', '@config.factory', '@asset.css.collection_renderer', '@asset.js.collection_renderer', '@request_stack', '@renderer', '@module_handler', '@language_manager']
  html_response.subscriber:
    class: Drupal\Core\EventSubscriber\HtmlResponseSubscriber
    tags:
@@ -1480,8 +1480,8 @@ services:
    class: Drupal\Core\Asset\CssCollectionRenderer
    arguments: [ '@state', '@file_url_generator' ]
  asset.css.collection_optimizer:
    class: Drupal\Core\Asset\CssCollectionOptimizer
    arguments: [ '@asset.css.collection_grouper', '@asset.css.optimizer', '@asset.css.dumper', '@state', '@file_system']
    class: Drupal\Core\Asset\CssCollectionOptimizerLazy
    arguments: [ '@asset.css.collection_grouper', '@asset.css.optimizer', '@theme.manager', '@library.dependency_resolver', '@request_stack', '@file_system', '@config.factory', '@file_url_generator', '@datetime.time', '@language_manager', '@state']
  asset.css.optimizer:
    class: Drupal\Core\Asset\CssOptimizer
    arguments: ['@file_url_generator']
@@ -1494,8 +1494,8 @@ services:
    class: Drupal\Core\Asset\JsCollectionRenderer
    arguments: [ '@state', '@file_url_generator' ]
  asset.js.collection_optimizer:
    class: Drupal\Core\Asset\JsCollectionOptimizer
    arguments: [ '@asset.js.collection_grouper', '@asset.js.optimizer', '@asset.js.dumper', '@state', '@file_system']
    class: Drupal\Core\Asset\JsCollectionOptimizerLazy
    arguments: [ '@asset.js.collection_grouper', '@asset.js.optimizer', '@theme.manager', '@library.dependency_resolver', '@request_stack', '@file_system', '@config.factory', '@file_url_generator', '@datetime.time', '@language_manager', '@state']
  asset.js.optimizer:
    class: Drupal\Core\Asset\JsOptimizer
  asset.js.collection_grouper:
+10 −3
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
use Drupal\Core\Asset\AttachedAssets;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Render\AttachmentsInterface;
use Drupal\Core\Render\AttachmentsResponseProcessorInterface;
use Drupal\Core\Render\RendererInterface;
@@ -87,8 +88,10 @@ class AjaxResponseAttachmentsProcessor implements AttachmentsResponseProcessorIn
   *   The renderer.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler.
   * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
   *   The language manager.
   */
  public function __construct(AssetResolverInterface $asset_resolver, ConfigFactoryInterface $config_factory, AssetCollectionRendererInterface $css_collection_renderer, AssetCollectionRendererInterface $js_collection_renderer, RequestStack $request_stack, RendererInterface $renderer, ModuleHandlerInterface $module_handler) {
  public function __construct(AssetResolverInterface $asset_resolver, ConfigFactoryInterface $config_factory, AssetCollectionRendererInterface $css_collection_renderer, AssetCollectionRendererInterface $js_collection_renderer, RequestStack $request_stack, RendererInterface $renderer, ModuleHandlerInterface $module_handler, protected LanguageManagerInterface $languageManager) {
    $this->assetResolver = $asset_resolver;
    $this->config = $config_factory->get('system.performance');
    $this->cssCollectionRenderer = $css_collection_renderer;
@@ -96,6 +99,10 @@ public function __construct(AssetResolverInterface $asset_resolver, ConfigFactor
    $this->requestStack = $request_stack;
    $this->renderer = $renderer;
    $this->moduleHandler = $module_handler;
    if (!isset($languageManager)) {
      @trigger_error('Calling ' . __METHOD__ . '() without the $language_manager argument is deprecated in drupal:10.1.0 and will be required in drupal:11.0.0', E_USER_DEPRECATED);
      $this->languageManager = \Drupal::languageManager();
    }
  }

  /**
@@ -141,8 +148,8 @@ protected function buildAttachmentsCommands(AjaxResponse $response, Request $req
    $assets->setLibraries($attachments['library'] ?? [])
      ->setAlreadyLoadedLibraries(isset($ajax_page_state['libraries']) ? explode(',', $ajax_page_state['libraries']) : [])
      ->setSettings($attachments['drupalSettings'] ?? []);
    $css_assets = $this->assetResolver->getCssAssets($assets, $optimize_css);
    [$js_assets_header, $js_assets_footer] = $this->assetResolver->getJsAssets($assets, $optimize_js);
    $css_assets = $this->assetResolver->getCssAssets($assets, $optimize_css, $this->languageManager->getCurrentLanguage());
    [$js_assets_header, $js_assets_footer] = $this->assetResolver->getJsAssets($assets, $optimize_js, $this->languageManager->getCurrentLanguage());

    // First, AttachedAssets::setLibraries() ensures duplicate libraries are
    // removed: it converts it to a set of libraries if necessary. Second,
+23 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Core\Asset;

/**
 * Interface defining a service that optimizes a collection of assets.
 *
 * Contains an additional method to allow for optimizing an asset group.
 */
interface AssetCollectionGroupOptimizerInterface extends AssetCollectionOptimizerInterface {

  /**
   * Optimizes a specific group of assets.
   *
   * @param array $group
   *   An asset group.
   *
   * @return string
   *   The optimized string for the group.
   */
  public function optimizeGroup(array $group): string;

}
+3 −1
Original line number Diff line number Diff line
@@ -12,11 +12,13 @@ interface AssetCollectionOptimizerInterface {
   *
   * @param array $assets
   *   An asset collection.
   * @param array $libraries
   *   An array of library names.
   *
   * @return array
   *   An optimized asset collection.
   */
  public function optimize(array $assets);
  public function optimize(array $assets, array $libraries);

  /**
   * Returns all optimized asset collections assets.
+10 −3
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
/**
 * Dumps a CSS or JavaScript asset.
 */
class AssetDumper implements AssetDumperInterface {
class AssetDumper implements AssetDumperUriInterface {

  /**
   * The file system service.
@@ -36,12 +36,19 @@ public function __construct(FileSystemInterface $file_system) {
   * browsers to download new CSS when the CSS changes.
   */
  public function dump($data, $file_extension) {
    $path = 'public://' . $file_extension;
    // Prefix filename to prevent blocking by firewalls which reject files
    // starting with "ad*".
    $filename = $file_extension . '_' . Crypt::hashBase64($data) . '.' . $file_extension;
    // Create the css/ or js/ path within the files folder.
    $path = 'public://' . $file_extension;
    $uri = $path . '/' . $filename;
    return $this->dumpToUri($data, $file_extension, $uri);
  }

  /**
   * {@inheritdoc}
   */
  public function dumpToUri(string $data, string $file_extension, string $uri): string {
    $path = 'public://' . $file_extension;
    // Create the CSS or JS file.
    $this->fileSystem->prepareDirectory($path, FileSystemInterface::CREATE_DIRECTORY);
    try {
Loading