成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Webpack 性能系列五:使用 Scope Hoisting

開發 前端
Webpack 會將模塊打包成一個一個分離的函數,這會造成一定程度上的代碼冗余與運行性能問題.

[[435028]]

一、什么是 Scope Hoisting

默認情況下,經過 Webpack 打包后的模塊資源會被組織成一個個函數形式,例如:

關于打包產物形態的更多知識,可參考前文《Webpack 原理系列八:產物轉譯打包邏輯》

  1. // common.js 
  2. export default "common"
  3.  
  4. // index.js 
  5. import common from './common'
  6. console.log(common); 

上例最終會被打包出形如下面結構的產物:

  1. "./src/common.js"
  2.   ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 
  3.      const __WEBPACK_DEFAULT_EXPORT__ = ("common"); 
  4.      __webpack_require__.d(__webpack_exports__, { 
  5.       /* harmony export */ 
  6.       "default": () => (__WEBPACK_DEFAULT_EXPORT__) 
  7.       /* harmony export */ 
  8.     }); 
  9.   }), 
  10. "./src/index.js"
  11.   ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 
  12.       var _common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./common */ "./src/common.js"); 
  13.       console.log(_common__WEBPACK_IMPORTED_MODULE_0__) 
  14.   }) 

這種結構存在兩個影響到運行性能的問題:

  • 重復的函數模板代碼會增大產物體積,消耗更多網絡流量
  • 函數的出棧入棧需要創建、銷毀作用域空間,影響運行性能

針對這些問題,自 Webpack 3 開始引入 Scope Hoisting 功能,本質上就是將符合條件的多個模塊合并到同一個函數空間內,減少函數聲明的模板代碼與運行時頻繁出入棧操作,從而打包出「體積更小」、「運行性能」更好的包。例如上述示例經過 Scope Hoisting 優化后,生成代碼:

  1. ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 
  2.     ;// CONCATENATED MODULE: ./src/common.js 
  3.     /* harmony default export */ const common = ("common"); 
  4.      
  5.     ;// CONCATENATED MODULE: ./src/index.js 
  6.     console.log(common); 
  7. }) 

二、使用 Scope Hoisting

2.1 開啟 Scope Hoisting 特性

Webpack 提供了三種方法開啟 Scope Hoisting 功能的方法:

  • 開啟 Production 模式
  • 使用 optimization.concatenateModules 配置項
  • 直接使用 ModuleConcatenationPlugin 插件

分別對應下述代碼:

  1. const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin'); 
  2.  
  3. module.exports = { 
  4.     // 方法1: 將 `mode` 設置為 production,即可開啟 
  5.     mode: "production"
  6.     // 方法2: 將 `optimization.concatenateModules` 設置為 true 
  7.     optimization: { 
  8.         concatenateModules: true
  9.         usedExports: true
  10.         providedExports: true
  11.     }, 
  12.     // 方法3: 直接使用 `ModuleConcatenationPlugin` 插件 
  13.     plugins: [new ModuleConcatenationPlugin()] 
  14. }; 

三種方法的作用原理相似,最終都會用到 ModuleConcatenationPlugin 完成模塊分析與合并操作,唯一需要注意的是使用 optimization.concatenateModules 時需要將 usedExports、providedExports 同時設置為 true,標記模塊的導入導出變量,才能完成合并操作。

2.2 模塊合并規則

開啟 Scope Hoisting 后,Webpack 會將盡可能多的模塊合并到同一個函數作用域下,但合并功能一方面依賴于 ESM 靜態分析能力;一方面需要確保合并操作不會造成代碼冗余。因此開發者需要注意 Scope Hoisting 會在以下場景下失效:

2.2.1 非 ESM 模塊

對于 AMD、CMD 一類的模塊,由于模塊導入導出內容的動態性,Webpack 無法確保模塊合并后不會對原有的代碼語義產生副作用,導致 Scope Hoisting 失效,例如:

  1. // common.js 
  2. module.exports = 'common'
  3.  
  4. // index.js 
  5. import common from './common'

上例中,由于 common.js 使用 CommonJS 導入模塊內容,Scope Hoisting 失效,兩個模塊無法合并。

這一問題在導入 NPM 包尤其常見,由于大部分框架都會自行打包后再上傳到 NPM,并且默認導出的是兼容性更佳的 CommonJS 模塊方案,因而無法使用 Scope Hoisting 功能,此時可通過 mainFileds 屬性嘗試引入框架的 ESM 版本:

  1. module.exports = { 
  2.   resolve: { 
  3.     // 優先使用 jsnext:main 中指向的 ES6 模塊化語法的文件 
  4.     mainFields: ['jsnext:main''browser''main'
  5.   }, 
  6. }; 

2.2.2 模塊被多個 Chunk 引用

如果一個模塊被多個 Chunk 同時引用,為避免重復打包,Scope Hoisting 同樣會失效,例如:

  1. // common.js 
  2. export default "common" 
  3.  
  4. // async.js 
  5. import common from './common'
  6.  
  7. // index.js  
  8. import common from './common'
  9. import("./async"); 

上例中,入口 index.js 以異步引用方式導入 async.js 模塊,同時 async.js 與 index.js 都依賴于 common.js 模塊,根據 Chunk 的運行規則, async.js 會被處理為單獨的 Chunk ,這就意味著 common.js 模塊同時被 index.js 對應的 Initial Chunk 與 async.js 對應的 Async Chunk 引用,此時 Scope Hoisting 失效,common.js 無法被合并入任一 Chunk,而是作為生成為單獨的作用域,最終打包結果:

  1. "./src/common.js"
  2.  (() => { 
  3.    var __WEBPACK_DEFAULT_EXPORT__ = ("common"); 
  4.  }), 
  5. "./src/index.js"
  6.  (() => { 
  7.    var _common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__( /*! ./common */ "./src/common.js"); 
  8.    __webpack_require__.e( /*! import() */ "src_async_js").then(__webpack_require__.bind(__webpack_require__, /*! ./async */ "./src/async.js")); 
  9.  }),   

關于 Chunk 的更多內容,請參考:

  • 《Webpack 性能系列四:分包優化》
  • 《有點難的知識點:Webpack Chunk 分包規則詳解》

 三、總結

默認情況下,Webpack 會將模塊打包成一個一個分離的函數,這會造成一定程度上的代碼冗余與運行性能問題,這一情況自 Webpack 3.0 引入 ModuleConcatenationPlugin 后,開發者可使用 Scope Hoisting 技術將多個模塊合并成一個函數,減少性能問題。

 

責任編輯:姜華 來源: Tecvan
相關推薦

2021-10-25 10:23:49

Webpack 前端Tree shakin

2021-11-09 09:57:46

Webpack 前端分包優化

2021-09-27 08:16:38

Webpack 前端Cache

2021-12-15 09:21:59

Webpack 前端Sourcemap

2020-09-19 21:26:56

webpack

2015-10-20 13:11:23

JavascriptHoisting

2019-03-05 10:20:49

WebWebpack分離數據

2021-05-31 05:36:43

WebpackJavaScript 前端

2021-10-12 09:52:30

Webpack 前端多進程打包

2022-03-03 07:34:31

注解容器作用域

2019-03-15 15:00:49

Webpack構建速度前端

2021-06-28 05:59:17

Webpack 前端打包與工程化

2021-09-13 09:40:35

Webpack 前端HMR 原理

2019-03-26 10:02:16

WebpackJavascript前端

2021-08-26 10:30:29

WebpackTree-Shakin前端

2013-12-17 16:21:17

iOSiOS性能優化

2021-12-16 22:02:28

webpack原理模塊化

2017-01-12 15:37:34

LinuxLXD 2.0鏡像管理

2017-09-26 16:32:03

JavaGC分析

2022-08-30 08:50:07

Spring權限控制
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品九九视频 | 欧美视频免费 | 免费在线精品视频 | 91欧美激情一区二区三区成人 | 亚洲精品电影网在线观看 | 精品免费国产一区二区三区四区 | 天天综合网7799精品 | 国产精品久久久久久吹潮 | 99精品热视频 | 午夜精品一区二区三区在线视频 | 亚洲欧美综合精品久久成人 | 久久久毛片 | 成人av网页 | 精品毛片| 久久久久亚洲 | 国产一区二区在线看 | 精品国产精品 | 国产在线中文字幕 | 欧美视频一区二区三区 | 亚洲一区欧美一区 | 欧美一区二区三区四区在线 | 日日操夜夜操天天操 | 国产国语精品 | 欧美日韩1区2区 | www国产成人免费观看视频,深夜成人网 | 欧美成人精品一区二区男人看 | 亚洲高清在线 | 不卡的av在线 | av在线免费网站 | 九九九视频 | 欧美情趣视频 | 日本精品一区二区三区在线观看 | 国产成人精品一区二区三区 | 欧美在线一区二区三区 | 久久久影院| 天堂一区二区三区 | 日韩在线视频免费观看 | 日韩中文字幕 | 国产麻豆一区二区三区 | 亚洲综合在线视频 | 亚洲国产成人在线视频 |