天天看點

c++代碼大全_Javascript 代碼是如何被壓縮的

(給前端大全加星标,提升前端技能)

作者:全棧成長之路 公号 / 山月行

随着前端的發展,特别是 

React

Vue

 等構造單頁應用的興起,前端的能力得以很大提升,随之而來的是項目的複雜度越來越大。此時的前端的靜态資源也越來越龐大,而毫無疑問 

javascript

 資源已是前端的主體資源,對于壓縮它的體積至為重要。

為什麼說更小的體積很重要呢:更小的體積對于使用者體驗來說意味着更快的加載速度以及更好的使用者體驗,這也能早就企業更大的利潤。另外,更小的體積對于伺服器來說也意味更小的帶寬以及更少的伺服器費用。

前端建構編譯代碼時,可以使用 

webpack

 中的 

optimization.minimizer

 來對代碼進行壓縮優化。但是我們也需要了解如何它是壓縮代碼的,這樣當在生産環境的控制台調試代碼時對它也有更深刻的了解。

如何檢視資源的體積

對于我們所編寫的代碼,它在作業系統中是一個檔案,根據檔案系統中的 

stat

 資訊我們可以檢視該檔案的大小。

stat

 指令用來列印檔案系統的資訊:

stat

 列印的資訊過大,如果隻用來衡量體積,可以使用 

wc -c

如何壓縮代碼體積?

去除多餘字元: 空格,換行及注釋

先把一個抽象的問題給具體化,如果是以上一段代碼,那如何壓縮它的體積呢:

此時檔案大小是 

62 Byte

, 一般來說中文會占用更大的空間。

多餘的空白字元會占用大量的體積,如空格,換行符,另外注釋也會占用檔案體積。當我們把所有的空白符合注釋都去掉之後,代碼體積會得到減少。

去掉多餘字元之後,檔案大小已經變為 

30 Byte

。 壓縮後代碼如下:

替換掉多餘字元後會有什麼問題産生呢?

有,比如多行代碼壓縮到一行時要注意行尾分号。 這就需要通過以下介紹的 AST 來解決。

壓縮變量名:變量名,函數名及屬性名

如以上 

first

 與 

second

 在函數的作用域中,在作用域外不會引用它,此時可以讓它們的變量名稱更短。但是如果這是一個 

module

 中,

sum

 這個函數也不會被導出呢?那可以把這個函數名也縮短。

在這個示例中,當完成代碼壓縮 (

compress

) 時,代碼的混淆 (

mangle

) 也捎帶完成。但此時縮短變量的命名也需要 AST 支援,不至于在作用域中造成命名沖突。

更簡單的表達:合并聲明以及布爾值簡化

合并聲明的示例如下:

布爾值簡化的示例如下:

這個示例更是需要解析 AST 了

AST

AST

,抽象文法樹,js 代碼解析後的最小詞法單元,而這個過程就是通過 Parser 來完成的。

那麼 AST 可以做什麼呢?

  • eslint: 校驗你的代碼風格
  • babel: 編譯代碼到 ES 低版本
  • taro/mpvue: 各種可以多端運作的小程式架構
  • GraphQL: 解析用戶端查詢

我們在日常工作中經常會不經意間與它打交道,如 

eslint

 與 

babel

,都會涉及到 

js

 與代碼中遊走。不同的解析器會生成不同的 AST,司空見慣的是 babel 使用的解析器 

babylon

,而 

uglify

 在代碼壓縮中使用到的解析器是 

UglifyJS

你可以在 AST Explorer[3] 中直覺感受到,如下圖:

c++代碼大全_Javascript 代碼是如何被壓縮的

那壓縮代碼的過程:code -> AST -> (transform)一顆更小的 AST -> code,這與 

babel

 和 

eslint

 的流程一模一樣。

c++代碼大全_Javascript 代碼是如何被壓縮的

UglifyJS

不要重複造輪子!

于是我找了一個久負盛名的關于代碼壓縮的庫: UglifyJS3[4],一個用以代碼壓縮混淆的庫。那它是如何完成一些壓縮功能的,比如替換空白符,答案是 AST。

webpack

 中内置的代碼壓縮插件就是使用了它,它的工作流程大緻如下:

而當你真正使用它來壓縮代碼時,你隻需要面向配置程式設計即可,文檔參考 uglify 官方文檔[5]

在 webpack 中壓縮代碼

在知道代碼壓縮是怎麼完成的之後,我們終于可以把它搬到生産環境中去壓縮代碼。終于到了實踐的時候了,雖然它隻是簡單的調用 API 并且調調參數。

一切與性能優化相關的都可以在 

optimization

 中找到,

TerserPlugin

 是一個底層基于 

uglifyjs

 的用來壓縮 JS 的插件。

optimization: {
minimize: isEnvProduction,
minimizer: [
new TerserPlugin({
terserOptions: {
parse: {
ecma: 8,
        },
compress: {
ecma: 5,
warnings: false,
comparisons: false,
inline: 2,
        },
output: {
ecma: 5,
comments: false,
ascii_only: true,
        },
      },
sourceMap: true
    })
  ]
}
           

推薦閱讀   點選标題可跳轉

前端如何在繁忙的業務中提升自己

當浏覽器全面禁用三方 Cookie

在生産環境中使你的 npm i 速度提升 50%

覺得本文對你有幫助?請分享給更多人

關注「前端大全」加星标,提升前端技能

c++代碼大全_Javascript 代碼是如何被壓縮的

好文章,我在看❤️

繼續閱讀