溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS加載性能Tree?Shaking優(yōu)化的方法是什么

發(fā)布時間:2022-11-15 09:27:01 來源:億速云 閱讀:88 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹了JS加載性能Tree Shaking優(yōu)化的方法是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇JS加載性能Tree Shaking優(yōu)化的方法是什么文章都會有所收獲,下面我們一起來看看吧。

什么是 Tree Shaking

您可以將應用程序想象成一棵樹。您實際使用的源代碼和庫表示樹中綠色的活葉子,死代碼表示秋天時樹上棕色的枯葉,為了除掉枯葉,你必須搖動樹,讓它們掉下。Tree Shaking 是指消除死代碼,下面通過一個應用程序演示了這個概念。使用 ES6 靜態(tài)模塊語法導入依賴項:

// 在這里導入了所有的數(shù)組處理方法
import arrayUtils from "array-utils";

在應用最初的時候,依賴項可能很少,隨著功能逐漸增加,依賴項也會增加,更糟糕的是,舊的依賴項不再使用,但可能不會從代碼庫中刪除,最終的結果是,應用程序帶有大量未使用的 JS 代碼,Tree Shaking 解決了這個問題,它通過分析我們在文件中使用的 ES6 靜態(tài)模塊語句來分析哪些模塊被導入了:

// 只導入部分方法
import { unique, implode, explode } from "array-utils";

這個導入示例與前一個示例的區(qū)別在于,本示例只導入模塊的特定部分,而不是從“array-utils”模塊導入所有內容。

尋找 Tree Shaking 的機會

為了便于說明,這里有一個使用 webpack 的單頁應用程序示例來演示 Tree Shaking 是如何工作的。界面如下:

這個程序打包之后的代碼被分為兩文件,如下:

在任何應用程序中,你需要從靜態(tài)導入語句尋找 Tree Shaking 的機會,在示例程序中(FilterablePedalList.js)你將看到這樣一行導入語句:

import * as utils from "../../utils/utils";

在文件中這樣的導入語句應該引起你的注意,它的意思是:從 utils 模塊導入所有內容。問題是:你真的用到所有的內容了嗎?現(xiàn)在我們來檢查 FilterablePedalList.js 中究竟使用了 utils 模塊中的那些方法,通過檢索發(fā)現(xiàn)只使用了 utils.simpleSort:

if (this.state.sortBy === "model") {
  // Simple sort gets used here...
  json = utils.simpleSort(json, "model", this.state.sortOrder);
} else if (this.state.sortBy === "type") {
  // ..and here...
  json = utils.simpleSort(json, "type", this.state.sortOrder);
} else {
  // ..and here.
  json = utils.simpleSort(json, "manufacturer", this.state.sortOrder);
}

我們現(xiàn)在開始做 Tree Shaking 優(yōu)化

防止 Babel 將 ES6 模塊轉換為 CommonJS 模塊

在大型應用中 Babel 是不可或缺的工具,但是它會讓 Tree Shaking 變得困難。如果你正在使用 babel-preset-env,它會自動為你將 ES6 模塊轉換為更廣泛兼容的 CommonJS 模塊,即:用 require 代替 import。對于 CommonJS 模塊而言做 Tree Shaking 優(yōu)化非常困難,這是因為 CommonJS 模塊是動態(tài)的,在構建階段 bundlers 不容易分析出 CommonJS 模塊導出了什么和導入了什么。為了避免 babel-preset-env 將 ES6 模塊轉換成 CommonJS 模塊,我們可以這么做:

{
  "presets": [
    ["env", {
      "modules": false
    }]
  ]
}

在你的 Babel -preset-env 配置中簡單指定"modules": false 就可以讓 Babel 按照我們想要的方式運行,這允許 webpack 分析你的依賴樹并擺脫那些未使用的依賴。

留意 side effects

當函數(shù)修改了它作用域之外的內容,我們就認為這個函數(shù)有 side effects。side effects 也適用于ES6模塊,在你做 Tree Shaking 的時候你需要留意你的模塊是否有 side effects(副作用),如果模塊接受可預測的輸入,并輸出同樣可預測的輸出,而不修改其自身范圍之外的任何內容,我們就認為這個模塊沒有 side effects,對于沒有 side effects 的模塊你可以放心的做 Tree Shaking。在這里我舉兩個 side effects 例子:

import './index.module.scss';
import './assets/shoot.svg';

如果在某個模塊中出現(xiàn)了上面這樣的 import 語句,則認為這個模塊有 side effects,這時在做 Tree Shaking 的時候你需要小心一些。默認情況下,webpack 在做 Tree Shaking 的時候,會認為 index.module.scss 與 assets/shoot.svg 沒有被用到,所以它們會被移除,如果不想被移除,可以告訴 webpack 它們是 side effects:

{
  "name": "webpack-tree-shaking-example",
  "version": "1.0.0",
  "sideEffects": [
    "./index.module.scss",
    "./assets/shoot.svg"
  ]
}

在項目的 package.json 中配置 sideEffects 字段。sideEffects 字段也能為 false,這表示項目中不存在有 side effects 的模塊。

只導入你需要的

現(xiàn)在我們已經(jīng)告訴 babel 不要將 ES6 模塊轉成 CommonJS 模塊,現(xiàn)在我們需要對導入語法做一點微調,只從 utils 模塊中引入我們需要的函數(shù)嗎,在本指南的例子中,我們只需要 simpleSort:

import { simpleSort } from "../../utils/utils";
if (this.state.sortBy === "model") {
  json = simpleSort(json, "model", this.state.sortOrder);
} else if (this.state.sortBy === "type") {
  json = simpleSort(json, "type", this.state.sortOrder);
} else {
  json = simpleSort(json, "manufacturer", this.state.sortOrder);
}

現(xiàn)在我們已經(jīng)完成了 Tree Shaking 的工作,下面是 Tree Shaking 之前 webpack 打包生成的 js 包大小:

                 Asset      Size  Chunks             Chunk Names
js/vendors.16262743.js  37.1 KiB       0  [emitted]  vendors
   js/main.797ebb8b.js  20.8 KiB       1  [emitted]  main

下面是 Tree Shaking 之后 webpack 打包生成的 js 包大?。?/p>

                 Asset      Size  Chunks             Chunk Names
js/vendors.45ce9b64.js  36.9 KiB       0  [emitted]  vendors
   js/main.559652be.js  8.46 KiB       1  [emitted]  main

main 的文件大小下降比較明顯,這是因為 webpack 移除了不需要的 utils 方法。

更復雜的情況

在有些情況你按照上面的步驟進行 Tree Shaking,但是 webpack 還是將模塊的所有內容都打包到最終的 Chunk 中了,例如:lodash。

// 仍然會導入所有的內容
import { sortBy } from "lodash";
// 這只會導入 sortBy
import sortBy from "lodash/sortBy";

如果你想要使用第一種寫法,那么你還需要安裝 babel-plugin-lodash。如果你使用了第三方庫,你可以看一下這個庫的導出是否使用了 ES6 語法,如果它的導出用的是 CommonJS 語法,例如:module.exports,那么 webpack 不能對它進行 Tree Shaking 優(yōu)化。有些插件,例如:webpack-common-shake,提供了對 CommonJS 模塊進行 Tree Shaking 的能力,但是它有一些限制。

關于“JS加載性能Tree Shaking優(yōu)化的方法是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“JS加載性能Tree Shaking優(yōu)化的方法是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI