83. 资源css与js优化处理

为了提高页面加载性能,drupal可以开启资源优化处理,这将在不影响加载顺序及加载条件的情况下,将可聚合的资源文件合并在一起,多个文件变成一个文件,这样就减少了浏览器下载次数,同时还对资源进行缩小化处理,去掉注释、空行、空格、BOM,以及纠正资源编码等,优化器的调用入口是在资源解析器(服务名:asset.resolver

)中进行的,本主题讲解资源如何优化。

 

Css集优化器:

对页面css文件集进行优化处理

服务名:asset.css.collection_optimizer

类:Drupal\Core\Asset\CssCollectionOptimizer

该服务需要css集分组器、优化器、导出器三个服务协助,见下文。

调用方式:

\Drupal::service('asset.css.collection_optimizer')->optimize($css);

参数$css是一个数组,键名为资源路径,键值为选项数组,该数组须已排序,后面的后加载。

该方法返回一个数组,键名是从0开始递增的数字,代表加载顺序,越靠后越后加载,键值是一个选项数组。

 

在返回的数组中每个元素代表着一个css资源文件,可能是一个外部css,或内部不可聚合的css文件,或是一个可聚合资源组经过聚合的css文件,聚合是指按加载顺序将相邻可合并的css文件划分到一个组,将组内多个css文件缩小并合并到一个文件中,在页面打开时只进行一次下载即可,提高性能,如果是经过聚合的资源,那么元素数组中会存在preprocessed键,其值为true

聚合结果被资源导出器保存到文件系统中,系统在以下位置保存着被聚合css文件集到聚合结果文件的映射:

\Drupal::state()->get('drupal_css_cache_files')

是一个数组,键名为哈希值,由可聚合资源组内源css文件地址构成数组经过sha256运算得到,键值为被聚合得到的文件的uri地址,该地址由资源导出器返回,以“public://”开头,见资源导出器。

 

外部文件不会被聚合,内部文件须可聚合且开启聚合配置时才聚合,是否可聚合与库定义中css文件选项preprocess、路径是否带参数等有关,开启聚合配置的后台地址是:

/admin/config/development/performance

程序方式为:

\Drupal::config ('system.performance')->get('css.preprocess');

 

css聚合前需要先分组,只有同一个组内的css才能聚合,分组工作由css分组器进行,见下。

 

W3Ccss规范中指定了@import的使用规则,她必须在本表单的任何规则之前,因此该服务在聚合后做了相应处理,见:

https://www.w3.org/TR/REC-CSS2/cascade.html#at-import

 

Css集分组器grouper

服务idasset.css.collection_grouper

类:Drupal\Core\Asset\CssCollectionGrouper

在保证css集内加载顺序不变的情况下,将css集内css划分成多个逻辑组,调用方式:

\Drupal::service('asset.css.collection_grouper')->group($css_assets);

参数$css_assets是一个数组,键名为css路径,键值为选项数组,返回一个数组,键名是从0开始递增的数字,这代表逻辑组的编号(这里讲的组是指可聚合资源组,和库定义选项里面的group是不同的概念),同一个组内的css一定是传入数组中相邻的css,且保持顺序不变,每个组至少一个css成员,且组内css成员的以下信息是完全相同的:

preprocesstypegroupmediabrowsers

只有这些信息相同才能被聚合,如果选项值preprocessfalse或者typeexternal,那么该css将自成一组,且组内只有她一个成员

返回的组数组($groups[$i])中,有如下键名:

Items:值为一个数组,保存成员的选项数组

media

browsers

preprocess

type

group

后五个键名的值来自选项数组,相同组内的css资源她们的这些信息是相同的,

 

在代码中你会看到'basename'选项,这在单元测试中用到,不必理会

在该服务中可以看出目前的实现(drupal8.5)中没有支持css压缩选项minified。如果支持那么不应该放入组信息里

 

css优化器optimizer

用于压缩优化单个css文件,删除注释、空格、换行,BOM,替换@import,以utf8输出内容

服务:asset.css.optimizer

类:Drupal\Core\Asset\CssOptimizer

调用如下:

\Drupal::service('asset.css.optimizer')->optimize($css_asset);

参数$css_asset是经过内部处理的选项数组,其中data键保存了文件路径(可以是流路径,也可以是相对于系统根目录的路径,此时无前缀“/”),可在控制器中执行以下代码测试该服务的输出:

        $css_asset = ['type'       => 'file',

                   'preprocess'  => true,

                   'data'       => 'core/themes/bartik/css/components/form.css'

        ];

        $data = \Drupal::service('asset.css.optimizer')->optimize($css_asset);

        print_r($data);

        die;

 

 

资源导出器dumper

用于将一个组内聚合优化后的cssjs资源保存到一个文件中,并返回文件uri

服务:asset.css.dumper

类:Drupal\Core\Asset\AssetDumper

调用方式:

$uri = \Drupal::service('asset.css.dumper')->dump($data, $file_extension);

参数$data是要保存的资源数据,$file_extension是要保存的资源类型,css或者js,内部使用她做子目录和文件扩展名

该服务采用流包装器“public://”,关于流包装器请见本系列《云客Drupal8源码分析之phpStreams、公共文件、私有文件》主题,“public://”的默认位置为:sites/default/files/

文件名采用sha256Base64编码,如下所示:

$filename = $file_extension . '_' . Crypt::hashBase64($data) . '.' . $file_extension;

如果php存在zlib扩展,且以下配置为true

\Drupal::config('system.performance')->get($file_extension . '.gzip')

那么还会产生压缩文件,在浏览器支持时进一步提高传输性能,你可以使用配置系统或配置文件关闭该行为。

文件操作请见本系列文件系统相关主题。

该服务返回文件的uri,类似如下:

public://css/ css_mMHZVBWrcsPaqRLbvud1u1JSon5n08FZbS-IBt37v0Q.css

在最终页面上这种采用流协议的uri将被替换为服务器绝对路径,如:

/sites/default/files/css/ css_mMHZVBWrcsPaqRLbvud1u1JSon5n08FZbS-IBt37v0Q.css

 

js集优化器:

用于对页面加载的多个js文件进行优化

服务名:asset.js.collection_optimizer

类:Drupal\Core\Asset\JsCollectionOptimizer

css集优化器大同小异,不再多讲,相关数据被缓存在如下位置:

\Drupal::state()->get('system.js_cache_files');

 

 

js集分组器:

服务名:asset.js.collection_grouper

类:Drupal\Core\Asset\JsCollectionGrouper

css的分组器几乎相同,都是在保证集内资源加载顺序不变的情况下,将资源划分成多个逻辑组,调用如下:

\Drupal::service(' asset.js.collection_grouper ')->group($js_assets);

唯一区别仅是不考虑媒体查询参数

 

js优化器:

服务名:asset.js.optimizer

类:Drupal\Core\Asset\JsOptimizer

优化单个js文件,和css的优化器相比,它简单许多,只是进行简单的编码转换、移除bom

 

js导出器:

服务idasset.js.dumper

类:Drupal\Core\Asset\AssetDumper

css完全相同,共享同一个类文件

 

补充:

drupal中没有对css文件的编码做任何限制,有无bom均可,最终被聚合的css将采用没有bomutf8编码

本书共94小节:

评论 (写第一个评论)