最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS?加載性能Tree?Shaking優(yōu)化詳解

 更新時(shí)間:2022年11月14日 11:38:54   作者:何遇er  
這篇文章主要為大家介紹了JS?加載性能Tree?Shaking優(yōu)化詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

隨著 web 應(yīng)用復(fù)雜性增加,JS 代碼文件的大小也在不斷的攀升,截住 2021年9月,在 httparchive 上有統(tǒng)計(jì)顯示——在移動(dòng)設(shè)備上 JS 傳輸大小大約為 447 KB,桌面端 JS 傳輸大小大約為 495 KB,注意這僅僅是在網(wǎng)絡(luò)中傳輸?shù)?JS 文件大小,JS 的實(shí)際大小要比傳輸大小大很多。

上圖是下載和運(yùn)行JavaScript的過(guò)程。

即使 JS 的傳輸大小被壓縮為 300 KB,但仍然有 900 KB 的 JS 代碼需要被瀏覽器解析、編譯和執(zhí)行。圖像一旦被下載,瀏覽器只需要花費(fèi)相對(duì)瑣碎的解碼時(shí)間,與圖像不同的是,JS 必須被解析、編譯,最終執(zhí)行,這使得處理 JS 比處理其他類型的資源更耗時(shí)。

上圖是瀏覽器解析/編譯 170 KB的 JS 的處理成本與同等大小的 JPEG 的解碼時(shí)間。JS 引擎的性能在不斷被改進(jìn),改進(jìn)網(wǎng)站 JS 性能也是開(kāi)發(fā)者要做的事情。Code Splitting 是優(yōu)化 JS 性能的技術(shù)之一,但是它不能減少應(yīng)用程序的 JS 代碼的總大小,在這里我們使用 Tree Shaking 來(lái)減小 js 代碼的大小。

什么是 Tree Shaking

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

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

在應(yīng)用最初的時(shí)候,依賴項(xiàng)可能很少,隨著功能逐漸增加,依賴項(xiàng)也會(huì)增加,更糟糕的是,舊的依賴項(xiàng)不再使用,但可能不會(huì)從代碼庫(kù)中刪除,最終的結(jié)果是,應(yīng)用程序帶有大量未使用的 JS 代碼,Tree Shaking 解決了這個(gè)問(wèn)題,它通過(guò)分析我們?cè)谖募惺褂玫?ES6 靜態(tài)模塊語(yǔ)句來(lái)分析哪些模塊被導(dǎo)入了:

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

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

尋找 Tree Shaking 的機(jī)會(huì)

為了便于說(shuō)明,這里有一個(gè)使用 webpack 的單頁(yè)應(yīng)用程序示例來(lái)演示 Tree Shaking 是如何工作的。界面如下:

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

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

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

在文件中這樣的導(dǎo)入語(yǔ)句應(yīng)該引起你的注意,它的意思是:從 utils 模塊導(dǎo)入所有內(nèi)容。問(wèn)題是:你真的用到所有的內(nèi)容了嗎?現(xiàn)在我們來(lái)檢查 FilterablePedalList.js 中究竟使用了 utils 模塊中的那些方法,通過(guò)檢索發(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)在開(kāi)始做 Tree Shaking 優(yōu)化

防止 Babel 將 ES6 模塊轉(zhuǎn)換為 CommonJS 模塊

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

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

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

留意 side effects

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

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

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

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

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

只導(dǎo)入你需要的

現(xiàn)在我們已經(jīng)告訴 babel 不要將 ES6 模塊轉(zhuǎn)成 CommonJS 模塊,現(xiàn)在我們需要對(duì)導(dǎo)入語(yǔ)法做一點(diǎn)微調(diào),只從 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 包大?。?/p>

                 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 包大小:

                 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 的文件大小下降比較明顯,這是因?yàn)?webpack 移除了不需要的 utils 方法。

更復(fù)雜的情況

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

// 仍然會(huì)導(dǎo)入所有的內(nèi)容
import { sortBy } from "lodash";
// 這只會(huì)導(dǎo)入 sortBy
import sortBy from "lodash/sortBy";

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

總結(jié)

為了確保構(gòu)建工具可以成功地優(yōu)化你的應(yīng)用程序,應(yīng)該避免依賴 CommonJS 模塊,并在整個(gè)應(yīng)用程序中使用 ES6 模塊語(yǔ)法。

以上就是JS 加載性能Tree Shaking優(yōu)化詳解的詳細(xì)內(nèi)容,更多關(guān)于JS 加載Tree Shaking的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript躲避行星游戲?qū)崿F(xiàn)全程

    JavaScript躲避行星游戲?qū)崿F(xiàn)全程

    本文將使用 canvas 創(chuàng)建一個(gè)躲避小行星游戲。另外將重點(diǎn)介紹的兩個(gè)方面是:如何使用 JavaScript 來(lái)檢測(cè)鍵盤(pán)輸入,以及如何在游戲中使用和處理 HTML5 音頻。希望你能夠喜歡
    2022-08-08
  • javascript 操作table的特性

    javascript 操作table的特性

    javascript操作table的特性,大家可以看下,發(fā)揮下,實(shí)現(xiàn)更多的功能。
    2009-09-09
  • 對(duì)Layer UI 模塊化的用法詳解

    對(duì)Layer UI 模塊化的用法詳解

    今天小編就為大家分享一篇對(duì)Layer UI 模塊化的用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-09-09
  • js中Function引用類型常見(jiàn)有用的方法和屬性詳解

    js中Function引用類型常見(jiàn)有用的方法和屬性詳解

    在本篇文章里小編給大家整理的是關(guān)于js中Function引用類型常見(jiàn)有用的方法和屬性知識(shí)點(diǎn),有興趣的朋友們可以學(xué)習(xí)下。
    2019-12-12
  • XHTML下,JS浮動(dòng)代碼失效的問(wèn)題

    XHTML下,JS浮動(dòng)代碼失效的問(wèn)題

    漂浮廣告/對(duì)聯(lián)代碼 為什么在XHTML語(yǔ)言的網(wǎng)頁(yè)中不能使用
    2009-11-11
  • JavaScript中閉包的作用和應(yīng)用場(chǎng)景

    JavaScript中閉包的作用和應(yīng)用場(chǎng)景

    這篇文章將給大家詳細(xì)介紹JavaScript?中閉包是什么,有哪些應(yīng)用場(chǎng)景,文章通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的參考價(jià)值,需要的朋友可以參考下
    2023-09-09
  • JavaScript前端靜態(tài)資源預(yù)加載實(shí)現(xiàn)示例

    JavaScript前端靜態(tài)資源預(yù)加載實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了JavaScript前端靜態(tài)資源預(yù)加載實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 微信小程序輪播圖swiper代碼詳解

    微信小程序輪播圖swiper代碼詳解

    swiper組件是滑塊視圖容器,主要用來(lái)做圖片輪播。這篇文章主要給大家介紹了關(guān)于微信小程序輪播圖swiper代碼的相關(guān)資料,需要的朋友可以參考下
    2020-12-12
  • javascript類繼承的實(shí)現(xiàn)方法

    javascript類繼承的實(shí)現(xiàn)方法

    JavaScript是一種面向?qū)ο蟮恼Z(yǔ)言,而繼承是面向?qū)ο缶幊痰囊粋€(gè)重要特性,在JavaScript中,繼承的實(shí)現(xiàn)方式有多種,本文將介紹javascript類的繼承的實(shí)現(xiàn),感興趣的朋友一起看看吧
    2023-10-10
  • javascript 改變網(wǎng)頁(yè)加載的CSS

    javascript 改變網(wǎng)頁(yè)加載的CSS

    javascript 改變網(wǎng)頁(yè)加載的CSS主要通過(guò)動(dòng)態(tài)響應(yīng)select觸發(fā)的選項(xiàng)變化控制link標(biāo)簽加載的css,以實(shí)現(xiàn)不依賴cookie控制的頁(yè)面css樣式動(dòng)態(tài)加載功能,需要的朋友可以參考一下
    2007-12-12

最新評(píng)論

霍州市| 龙里县| 金门县| 民权县| 宁陵县| 文登市| 泰州市| 凉城县| 都匀市| 湖北省| 锦州市| 迭部县| 图木舒克市| 皋兰县| 舟曲县| 松潘县| 肇州县| 灵山县| 沧州市| 新津县| 沙田区| 黑龙江省| 河东区| 乃东县| 邓州市| 惠州市| 阳城县| 祁东县| 奉节县| 德江县| 洪雅县| 长顺县| 那曲县| 桃园市| 邢台市| 车致| 章丘市| 水城县| 新宁县| 镇平县| 梅河口市|