Javascript 是如何進行壓縮的?
「前端工程化」系列正在更新: 11/38。
通過 AST 分析,根據(jù)選項配置一些策略,來生成一顆更小體積的 AST 并生成代碼。
目前前端工程化中使用 terser 和 swc 進行 JS 代碼壓縮,他們擁有相同的 API。
長按識別二維碼查看原文
https://terser.org/docs/api-reference#compress-options
長按識別二維碼查看原文
https://swc.rs/docs/configuration/minification
常見用以壓縮 AST 的幾種方案如下:
1. 去除多余字符: 空格,換行及注釋
// 對兩個數(shù)求和
function sum (a, b) {
return a + b;
}
此時文件大小是 62 Byte, 「一般來說中文會占用更大的空間。」
多余的空白字符會占用大量的體積,如空格,換行符,另外注釋也會占用文件體積。當(dāng)我們把所有的空白符合注釋都去掉之后,代碼體積會得到減少。
「去掉多余字符之后,文件大小已經(jīng)變?yōu)?30 Byte。」 壓縮后代碼如下:
function sum(a,b){return a+b}
替換掉多余字符后會有什么問題產(chǎn)生呢?
「有,比如多行代碼壓縮到一行時要注意行尾分號。」
2. 壓縮變量名:變量名,函數(shù)名及屬性名
function sum (first, second) {
return first + second;
}
如以上 first 與 second 在函數(shù)的作用域中,在作用域外不會引用它,此時可以讓它們的變量名稱更短。但是如果這是一個 module 中,sum 這個函數(shù)也不會被導(dǎo)出呢?那可以把這個函數(shù)名也縮短。
// 壓縮: 縮短變量名
function sum (x, y) {
return x + y;
}
// 再壓縮: 去除空余字符
function s(x,y){return x+y}
在這個示例中,當(dāng)完成代碼壓縮 (compress) 時,代碼的混淆 (mangle) 也捎帶完成。「但此時縮短變量的命名也需要 AST 支持,不至于在作用域中造成命名沖突。」
3. 解析程序邏輯:合并聲明以及布爾值簡化
通過分析代碼邏輯,可對代碼改寫為更精簡的形式。
合并聲明的示例如下:
// 壓縮前
const a = 3;
const b = 4;
// 壓縮后
const a = 3, b = 4;
布爾值簡化的示例如下:
// 壓縮前
!b && !c && !d && !e
// 壓縮后
!(b||c||d||e)
4. 解析程序邏輯: 編譯預(yù)計算
在編譯期進行計算,減少運行時的計算量,如下示例:
// 壓縮前
const ONE_YEAR = 365 * 24 * 60 * 60
// 壓縮后
const ONE_YAAR = 31536000
以及一個更復(fù)雜的例子,簡直是殺手锏級別的優(yōu)化。
// 壓縮前
function hello () {
console.log('hello, world')
}
hello()
// 壓縮后
console.log('hello, world')
看到最后的小伙伴,是不每天都在堅持學(xué)習(xí)《前端工程化》系列文章呢,可以「留言打卡」或者討論問題,堅持打卡十次,可以由我提供「免費并不上傳嗶哩嗶哩」的模擬面試以及談薪技巧的交流。
「前端工程化」系列正在更新: 11/38
「每天三分鐘,半年大廠中」
