當前位置:
首頁 > 科技 > 高效壓縮CSS文件束的體積

高效壓縮CSS文件束的體積

前言

今日早讀文章由 @Asterisk 翻譯投稿分享。

正文從這開始~

今年年初我離開了資訊公司並開始搭建GO2CINEMA 站——一個英國的貓眼電影。我做了一系列優秀的工作來讓它更快更簡單更安全。而我的習慣是,追求極致的渲染優化。

我用ūsus(https://github.com/gajus/usus) 解決了HTML的預渲染,ūsus用單頁面HTML和內聯CSS來渲染頁面,而我不喜歡內聯70kb 的CSS在每個HTML文檔里,尤其是裡面大部分是CSS的選擇器類名。

就像谷歌做的那樣

你是否曾經瞄過一眼谷歌的頁面代碼,你第一件注意到的事就是CSS的選擇器名不會超過一對單詞的長度。

但是如何處理呢?

CSS壓縮工具的缺點

有一點是壓縮工具沒法做到的 改變選擇器的名字,這使得CSS的壓縮器沒法控制HTML的輸出。與此同時,CSS的名字會很長,如果你使用CSS模塊化開發,你的CSS模塊很有可能包括了 樣式表文件的名字、本地用於識別的獨立名稱和一串隨機哈希。css載入器的配置會修飾類名模板的名稱,舉個例子[name]___[local]___[hash:base64:5]。

因此,一個典型的類名會看起來像這樣:.MovieView___movie-title___yvKVV ;如果你很喜歡詳細描述類名,它有可能會變得更長,舉個例子.MovieView___movie-description-with-summary-paragraph___yvKVV .

在打包的時候對CSS的類名重命名

而好消息是,如果你用webpack和babel-plugin-react-css-modules,你可以在打包的時候用css-loader getLocalIdent (https://github.com/webpack-contrib/css-loader)或者babel-plugin-react-css-modules generateScopedName(https://github.com/gajus/babel-plugin-react-css-modules#configuration)重命名類名。

//webpack.configuration.js

/**

* @file Webpack configuration.

*/

constpath=require( path );

constgenerateScopedName=(localName,resourcePath)=>{

constcomponentName=resourcePath.split( / ).slice(-2,-1);

returncomponentName+ _ +localName;

};

module.exports={

module:{

rules:[

{

include:path.resolve(__dirname, ../app ),

loader: babel-loader ,

options:{

babelrc:false,

extends:path.resolve(__dirname, ../app/webpack.production.babelrc ),

plugins:[

[

react-css-modules ,

{

context:common.context,

filetypes:{

.scss :{

syntax: postcss-scss

}

},

generateScopedName,

webpackHotModuleReloading:false

}

]

]

},

test:/.js$/

},

{

test:/.scss$/,

use:[

{

loader: css-loader ,

options:{

camelCase:true,

getLocalIdent:(context,localIdentName,localName)=>{

returngenerateScopedName(localName,context.resourcePath);

},

importLoaders:1,

minimize:true,

modules:true

}

},

resolve-url-loader

]

}

]

},

output:{

filename: [name].[chunkhash].js ,

path:path.join(__dirname, ./.dist ),

publicPath: /static/

},

stats: minimal

};

縮短命名

通過使用babel-plugin-react-css-modules 和 css-loader的相同邏輯來命名,我們可以按我們自己的想法隨意改別類名,甚至是隨機哈希。而更進一步,我想要更短的選擇器類名來直接代替隨機哈希。為了改變類名,我創建了一個類名入口然後用incstr(https://github.com/grabantot/incstr)來改寫每個通過這個入口的不斷增加的 ID。

//createUniqueIdGenerator.js

constincstr=require( incstr );

constcreateUniqueIdGenerator=()=>{

constindex={};

constgenerateNextId=incstr.idGenerator({

// Removed "d" letter to avoid accidental "ad" construct.

// @see https://medium.com/@mbrevda/just-make-sure-ad-isnt-being-used-as-a-class-name-prefix-or-you-might-suffer-the-wrath-of-the-558d65502793

alphabet: abcefghijklmnopqrstuvwxyz0123456789

});

return(name)=>{

if(index[name]){

returnindex[name];

}

letnextId;

do{

// Class name cannot start with a number.

nextId=generateNextId();

}while(/^[0-9]/.test(nextId));

index[name]=generateNextId();

returnindex[name];

};

};

constuniqueIdGenerator=createUniqueIdGenerator();

constgenerateScopedName=(localName,resourcePath)=>{

constcomponentName=resourcePath.split( / ).slice(-2,-1);

returnuniqueIdGenerator(componentName)+ _ +uniqueIdGenerator(localName);

};

這樣就能改造出既短又唯一的類名。現在.a_a, .b_a 諸如此類的類名會代替

.MovieView___movie-title___yvKVV 和 .MovieView___movie-description-with-summary-paragraph___yvKVV

這使得GO2CINEMA的css文件束從140kb壓縮到53kb

使用作用域隔離進一步壓縮文件束體積

我會加下劃線_在CSS類名里去分割組件名和識別名稱——這種區分方法有助於壓縮。

csso(CSS壓縮工具)有作用域設置。作用域里定義了一個類名列表用於做一些專門的標記,即不同作用域的選擇器不會選中污染同一個元素,這使得優化方案能更規範地修改規則。利用這個,使用csso-webpack-plugin(https://github.com/zoobestik/csso-webpack-plugin)來後期處理CSS的文件束。

//getScopes.js

constgetScopes=(ast)=>{

constscopes={};

constgetModuleID=(className)=>{

consttokens=className.split( _ )[];

if(tokens.length!==2){

return default ;

}

returntokens[];

};

csso.syntax.walk(ast,node=>{

if(node.type=== ClassSelector ){

constmoduleId=getModuleID(node.name);

if(moduleId){

if(!scopes[moduleId]){

scopes[moduleId]=[];

}

if(!scopes[moduleId].includes(node.name)){

scopes[moduleId].push(node.name);

}

}

}

});

returnObject.values(scopes);

};

是否值得

第一個爭議是這種壓縮本身壓縮演算法就可以幫你做到。GO2CINEMA的CSS文件束壓縮使用的是Brotli演算法,比起原來的長類名的文件束只節省了1kb的體積。另一方面,設置這種壓縮只是一次性投資並且這樣減少的文檔體積需要被解析。它有另一種好處,可以有效阻止那些通過CSS類名來掃描廣告的反廣告屏蔽插件。

關於本文

譯者:@Asterisk

作者:@Gajus Kuizinas

原文:https://medium.freecodecamp.org/reducing-css-bundle-size-70-by-cutting-the-class-names-and-using-scope-isolation-625440de600b

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端早讀課 的精彩文章:

深入PostCSS Web設計
【第1006期】ECMAScript 6 新特性
從移動端click到搖一搖
你不應該錯過的前端技術會議
Nodejs cluster模塊深入探究

TAG:前端早讀課 |

您可能感興趣

七牛雲CDN鏡像存儲加快圖片/CSS/JS文件訪問速度,支持申請免費SSL
IBM存儲大舉強化文件存儲軟體和NVMeoF支持
PHP 生成 CSV 文件
如何在 Linux 中壓縮和解壓縮文件
文件存儲CFS
利用MATLAB批量對文件重命名
ASP 引用文件
CSV配置文件的優化策略
超全實用簡約的一套素材包PSD和Sketch源文件下載
JSP 文件上傳
GMP文件體系需要不斷的完善
在CDR軟體中導入 AI、PS和PDF 文件的方法
ISO鏡像文件中發現惡意軟體
Excel文件加圖片後體積爆表?一招壓縮二十倍
Finder新功能:對桌面文件進行高效整合
Excel文件加圖片後體積爆表?一招壓縮到5%
域滲透——獲得域控伺服器的NTDS.dit文件
SSM框架整合裡面的一些配置文件
WinRAR漏洞曝光:可植入惡意文件 需儘快升級
ZStack無縫融合阿里雲NAS模塊,文件存儲服務再升級!