You are here

public function JsCollectionOptimizer::optimize in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Asset/JsCollectionOptimizer.php \Drupal\Core\Asset\JsCollectionOptimizer::optimize()

The cache file name is retrieved on a page load via a lookup variable that contains an associative array. The array key is the hash of the names in $files while the value is the cache file name. The cache file is generated in two cases. First, if there is no file name value for the key, which will happen if a new file name has been added to $files or after the lookup variable is emptied to force a rebuild of the cache. Second, the cache file is generated if it is missing on disk. Old cache files are not deleted immediately when the lookup variable is emptied, but are deleted after a configurable period (

system . performance . stale_file_threshold;

) to ensure that files referenced by a cached page will still be available.

Overrides AssetCollectionOptimizerInterface::optimize

File

core/lib/Drupal/Core/Asset/JsCollectionOptimizer.php, line 84

Class

JsCollectionOptimizer
Optimizes JavaScript assets.

Namespace

Drupal\Core\Asset

Code

public function optimize(array $js_assets) {

  // Group the assets.
  $js_groups = $this->grouper
    ->group($js_assets);

  // Now optimize (concatenate, not minify) and dump each asset group, unless
  // that was already done, in which case it should appear in
  // system.js_cache_files.
  // Drupal contrib can override this default JS aggregator to keep the same
  // grouping, optimizing and dumping, but change the strategy that is used to
  // determine when the aggregate should be rebuilt (e.g. mtime, HTTPS …).
  $map = $this->state
    ->get('system.js_cache_files', []);
  $js_assets = [];
  foreach ($js_groups as $order => $js_group) {

    // We have to return a single asset, not a group of assets. It is now up
    // to one of the pieces of code in the switch statement below to set the
    // 'data' property to the appropriate value.
    $js_assets[$order] = $js_group;
    unset($js_assets[$order]['items']);
    switch ($js_group['type']) {
      case 'file':

        // No preprocessing, single JS asset: just use the existing URI.
        if (!$js_group['preprocess']) {
          $uri = $js_group['items'][0]['data'];
          $js_assets[$order]['data'] = $uri;
        }
        else {
          $key = $this
            ->generateHash($js_group);
          $uri = '';
          if (isset($map[$key])) {
            $uri = $map[$key];
          }
          if (empty($uri) || !file_exists($uri)) {

            // Concatenate each asset within the group.
            $data = '';
            foreach ($js_group['items'] as $js_asset) {

              // Optimize this JS file, but only if it's not yet minified.
              if (isset($js_asset['minified']) && $js_asset['minified']) {
                $data .= file_get_contents($js_asset['data']);
              }
              else {
                $data .= $this->optimizer
                  ->optimize($js_asset);
              }

              // Append a ';' and a newline after each JS file to prevent them
              // from running together.
              $data .= ";\n";
            }

            // Remove unwanted JS code that cause issues.
            $data = $this->optimizer
              ->clean($data);

            // Dump the optimized JS for this group into an aggregate file.
            $uri = $this->dumper
              ->dump($data, 'js');

            // Set the URI for this group's aggregate file.
            $js_assets[$order]['data'] = $uri;

            // Persist the URI for this aggregate file.
            $map[$key] = $uri;
            $this->state
              ->set('system.js_cache_files', $map);
          }
          else {

            // Use the persisted URI for the optimized JS file.
            $js_assets[$order]['data'] = $uri;
          }
          $js_assets[$order]['preprocessed'] = TRUE;
        }
        break;
      case 'external':

        // We don't do any aggregation and hence also no caching for external
        // JS assets.
        $uri = $js_group['items'][0]['data'];
        $js_assets[$order]['data'] = $uri;
        break;
    }
  }
  return $js_assets;
}