webpack打包極限優化

webpack打包極限優化--基本介紹

1.爲何咱們須要構建工具

(a)轉換ES6語法css

(b)轉換JSXhtml

(c)CSS前綴補全/預處理器node

(d)壓縮混淆react

(e)圖片壓縮webpack

2.初級分析-使用Webpack內置的stats

(a)stats:構建的統計信息
(b)package.json中使用statusweb

 1 "scripts": { 2 "build:stats": "webpack ---env production --json > stats.json" 3 ... 4 } 正則表達式

(c)Node API中使用算法

 1 const webpack = require('webpack');
 2 const config = require('./webpack.config.js')("production");
 3 
 4 webpack(config, (err, stats) => {
 5   if (err) {
 6     return console.error(err);
 7   }
 8   if (stats.hasErrors()) {
 9     return console.error(stats.toString("errors-only"))
10   }
11   console.log(stats);
12 })

3.速度分析-使用speed-measure-webpack-plugin

 1 const speedMeasurePlugin = require("speed-measure-webpack-plugin");
 2 const smp = new SpeedMeasurePlugin();
 3 
 4 const webpackConfig = smp.wrap({
 5   plugins: {
 6     new MyPlugin(),
 7     new MyOtherPlugin()
 8   }
 9 })
10 // 能夠看到每一個loader和插件執行耗時

4.體積分析-使用webpack-bundle-analyzer

1 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
2 module.exports = {
3   plugins: {
4     new BundleAnalyzerPlugin()
5   }
6 }
7 // 構建完成後會在8888端口展現各個打包後文件的大小

webpack打包極限優化--構建速度優化

1.速度優化策略

(a)使用webpack4json

(b)多進程/多實例構建redux

(c)分包

(d)緩存

(e)縮小構建目標

2.使用webpack4-優化緣由

(a)V8帶來的優化(for of替代forEach、Map和Set替代Object、includes替代indexOf)

(b)默認使用更快的md4 hash算法

(c)webpacks AST能夠直接從loader傳遞給AST,減小解析時間

(d)使用字符串方法替代正則表達式

3.多進程/多實例-使用HappyPack解析資源

原理:每次webpack解析一個模塊,HappyPack會將它及它的依賴分配給worker線程中

 1 exports.plugins = {
 2   new HappyPack({
 3     id: 'jsx',
 4     threads: 4, // 固定線程數,可是不建議
 5     loaders: ['babel-loader']
 6   }),
 7   new HappyPack({
 8     id: 'styles',
 9     threads: 2, // 固定線程數,可是不建議
10     loaders: ['style-loader', 'css-loader', 'less-loader']
11   })
12 }

4.多進程/多實例-並行壓縮

方法一:使用parallel-uglify-plugin插件(webpack3使用)

 1 const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
 2 module.exports = {
 3   plugins: [
 4     new ParallelUglifyPlugin({
 5       uglifyJS: {
 6         output:{
 7           beautity: false,
 8           comments: false,
 9         },
10         compress: {
11           warnings: false,
12           drop_console: true,
13           collapse_vars: true,
14           reduce_vars: true
15         }
16       }
17     })
18   ]
19 }

方法二:使用uglifyjs-webpack-plugin開啓parallel參數(webpack4使用)

 1 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
 2 module.exports = {
 3   plugins: [
 4     new UglifyJsPlugin({
 5       uglifyOptions: {
 6         warnings: false,
 7         parse: {},
 8         compress: {},
 9         mangle: true,
10         output: null,
11         toplevel: false,
12         nameCache: null,
13         ie8: false,
14         keep_fnames: false
15       },
16       parallel: true
17     })
18   ]
19 }

5.分包-設置Externals

思路:將react、react-dom基礎包經過cdn引入,不打入bundle中
方法:使用html-webpack-externals-plugin

 1 const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
 2 plugins: [
 3   new HtmlWebpackExternalsPlugin({
 4     external: [
 5       {
 6         module: 'react',
 7         entry: '........./react-with-addons.min.js?_bid=313',
 8         global: 'React'
 9       },
10       {
11         module: 'react-dom',
12         entry: '........./react-dom.min.js?_bid=313',
13         global: 'ReactDOM'
14       }
15     ]
16   })
17 ]

6.進一步分包-預編譯資源模塊

思路:將react、react-dom、redux、react-redux基礎包和業務基礎包打包成一個文件。
方法:使用DLLPlugin進行分包,DllReferencePlugin對manifest.json引用

1 module.exports = {
2   plugins: [
3     new webpack.DllPlugin({
4       name: '[name]',
5       path: './build/library/[name].json'
6     })
7   ]
8 }

7.緩存

目的:提高二次構建速度
方法:使用HardSourceWebpackPlugin或者cache-loader
比較推薦使用HardSourceWebpackPlugin,速度更快

8.縮小構建目標

目的:儘量的少構建模塊
好比babel-loader不解析node_modules

1 module.exports = {
2   rules: {
3     test: /\.js$/,
4     loader: 'happypack/loader',
5     exclude: 'node_modules'
6   }
7 }

webpack打包極限優化--構建體積優化

1.體積優化策略

(a)Scope Hoisting

(b)Tree-shaking

(c)公共資源分離

(d)圖片壓縮

(e)動態Polyfill

2.Scope Hoisting

原理:將全部模塊的代碼按照引用順序放在一個函數做用域裏,而後適當的重命名一些變量以防止變量名衝突
對比:經過scope hoisting能夠減小函數聲明代碼

1 // 代碼示例:
2 module.exports = {
3   plugins: [
4     new webpack.opimize.ModuleConcatenationPlugin()
5   ]
6 }
7 // 要求:必須是ES6的語法,CJS的方式不支持

3.Tree-shaking

概念:1個模塊可能有多個方法,只要其中的某個方法使用到了,則整個文件都會被打到bundle裏面去,Tree-shaking
就是隻把用到的方法打入bundle,沒用到的方法會在uglify階段被刪掉
使用:webpack默認支持,在.babelrc裏設置modules:false便可
要求:必須是ES6的語法,CJS的方式不支持

4.公共資源分離

目的:提取多頁面公共JS chunk代碼
使用:webpack3使用CommonsChunkPlugin
webpack4使用SplitChunksPlugin

5.圖片壓縮

要求:基於Node庫的imagemin或者tinypng API

使用:配置image-webpack-loader

相關文章
相關標籤/搜索