Webpack性能優化

減少Webpack打包時間

1.優化Loader

對于Loader,影響打包效率的是它的屬性Babel.Babel會將代碼轉為字符串 生成AST,然后對AST繼續進行轉變最后生成新的代碼,項目越大,轉換代碼越多,效率就越低。

優化Loader的文件搜索范圍
module.exports = {
        module:{
            rules:[
              {
                //js文件才使用babel
                test:/\.js$/,
                loader:'babel-loader',
                //只在src文件夾下查找
                include:[resolve('src')],
                //不會去查找的路徑
                exclude:/node_modules/
              }
            ]
        }
    }
把Babel編譯過的文件緩存起來

下次只需要編譯更改過的代碼文件即可

loader: 'babel-loader?cacheDirectory=ture'
HappyPack

因為Node是單線程運行的,所以Webpack在打包的過程中也是單線程的,特別是在執行Loader的時候,這樣會導致等待的情況
HappyPack可以將Loader的同步執行轉換為并行的

module:{
        loader:[
           {
                //js文件才使用babel
                test:/\.js$/,
                //只在src文件夾下查找
                include:[resolve('src')],
                exclude:/node_modules/,
                //id后面的內容對應下面
                loader:'happypack/loader?id=happypack'
           }
        ]
    },
    plugins:[
      new HappyPack({
        id:'happypack',
        loaders:['babel-loader?cacheDirectory'],
        //開啟4個線程
        threads:4
      })
    ]
DllPlugin

DllPlugin可以將特定的類庫提前打包然后引入。這種方式可以極大的減少打包類庫的次數,只有當類庫更新版本才有需要重新打包,并且也實現了將公共代碼抽離成單獨文件的優化方案

//單獨配置在一個文件里
    //webpack.dll.conf.js
    const path = require('path')
    const webpack = require('webpack')
    module.exports = {
        entry:{
            //想統一打包的庫
            vendor:['react']
        },
        output:{
            path:path.join(__dirname,'dist'),
            filename:'[name].dll.js',
            library:'[name]-[hash]'
        },
        plugins:[
          new webpack.DllPlugin({
            //name必須和output.library一致
            name:'[name]-[hash]',
            //該屬性需要與DllReferencePlugin中一致
            context:__dirname,
            path:path.join(__dirname,'dist','[name]-mainfest.json')
          })
        ]
    }

然后需要執行這個配置文件生成依賴文件,接下來需要使用DllReferencePluhin將依賴文件引入項目中

 //webpack.conf.js
   module.exports={
    //...省略其他配置
    plugins: [
      new webpack.DllReferencePlugin({
        context: __dirname,
        mainfest:require('./dist/vendor-mainfest.json')
      })
    ]
   }

減少Webpack打包后的文件體積

按需加載

如果我們把十幾個頁面甚至更多的路由頁面,把這些頁面全部打包進一個JS文件的話,雖然將多個請求合并了,但是同樣也加載了很多并不需要的代碼,耗費了更長的時間。那么為了首頁能更快地呈現給客戶,這時候我們就可以使用按需加載,將每個路由頁面單獨打包為一個文件,當然不僅路由可以按需加載,對于loadash這種大型類庫可以使用這個功能。

當使用的時候再去下載對應文件,返回一個Promise當Promise成功以后去執行回調
Scope Hoisting

Scope Hoisting會分析出模塊之間的依賴關系,盡可能的把打包出來的模塊合并到一個函數中去。

比如我們希望打包兩個模塊
   //test.js
   export const a=1
   //index.js
   import {a} from './test.js'
   對于這種情況,我們打包出來的代碼類似這樣
   [
     function (module,exports,require){
        //...
     },
     function(module,exports,require){
        //...
     }

   ]
   但是如果我們使用Scope Hoisting的話,代碼就會盡可能的合并到一個函數去,也就變成了這樣的類似代碼
   [
     function(module,exports,require){
        //...
     }
   ]
   這樣的打包方式生成的代碼明顯比之前的少了多了。如果在webpack4中希望開啟這個功能,只需要啟用
   optimization.concatenateModules就可以了
   module,exports={
    optimization:{
        concatenateModules:true
    }
   }
Tree Shaking

Tree Shaking 可以實現刪除項目中未被引用的代碼

 //test.js
   export const a = 1;
   export const b = 2;
   //index.js
   import {a} from './test.js'

test文件中的變量b如果沒有在項目中使用到的話,就不會被打包到文件中。
webpack4的話,開啟生產環境就會自動啟動這個優化功能。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 寫在前面的話 閱讀本文之前,先看下面這個webpack的配置文件,如果每一項你都懂,那本文能帶給你的收獲也許就比較...
    不忘初心_9a16閱讀 3,259評論 0 17
  • GitChat技術雜談 前言 本文較長,為了節省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,710評論 7 110
  • 目錄第1章 webpack簡介 11.1 webpack是什么? 11.2 官網地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,752評論 0 1
  • 作者:小 boy (滬江前端開發工程師)本文原創,轉載請注明作者及出處。原文地址:https://www.smas...
    iKcamp閱讀 2,773評論 0 18
  • 輕舟晨霧小屋靜, 綠肥紅瘦殘花落, 鶯啼燕語叢林中, 幽谷逸林水自流。
    愛你的人是我865432閱讀 228評論 0 3