雖然webpack的已經升級到了webpack4,而咱們目前還在使用webpack3,但其中的優化點都大同小異,升級後一樣適用。css
減少代碼量html
減少請求數vue
最大化利用瀏覽器緩存react
這三條原則永遠是一切優化的前提webpack
升級webpack 3
,優化js的編譯能力(Scope Hoisting)ios
1// 主要配置
2plugins:[
3 new webpack.optimize.ModuleConcatenationPlugin()
4]
合理規劃 entry
入口配置(平衡vendor.js, app.js文件的大小)web
1// main.js中第三方公共庫提出,做爲公共vendor.js, 配合package.json固定第三方庫版本,最大化利用瀏覽器緩存加載js
2entry: {
3 vendor:['vue', 'vue-router', 'vue-resource'],
4 app: './src/main.js'
5}
6// ...
7plugins:[
8 new webpack.optimize.CommonsChunkPlugin({
9 name: ['manifest','vendor'].reverse(),
10 minChunks:Infinity
11 })
12]
打包後文件大小限制,首次加載js+css超過 400k
,單個文件大小超過 300k
將會報錯,打包不經過,該配置在build中使用vue-router
1performance: {
2 hints: 'error',
3 maxEntrypointSize: 400000,
4 maxAssetSize: 300000
5}
提取 chunk
中使用的公共庫(能爲chunk代碼節約近1/3的代碼量)vuex
1new webpack.optimize.CommonsChunkPlugin({
2 name: 'app',
3 async: 'vendor-async',
4 children: true,
5 minChunks: (module, count) => {
6 // 被 2 個及以上 chunk 使用的共用模塊提取出來
7 return count >= 2
8 }
9})
減小圖片base64的使用,下降限制,限制2k(vue官方配置是10k,會大大增長js文件體積,移動端對base64的解析成本高)vue-cli
1 {
2 test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
3 loader: 'url-loader',
4 options: {
5 limit: 2048,
6 name: utils.assetsPath('img/[name].[hash:7].[ext]')
7 }
8 }
生產模式(pro)下第三方庫使用已壓縮版本,能節約近20k文件大小
1// 開發模式
2resolve: {
3 alias: {
4 'vue': 'vue/dist/vue.esm.js'
5 }
6}
7// 生產模式
8resolve: {
9 alias: {
10 'vue': 'vue/dist/vue.min.js'
11 }
12}
優化 babel-ployfill
,結合 babel-preset-env
實現兼容按需加載,比使用es2015
能節約近半的大小
1entry: {
2 vendor:['babel-polyfill', 'vue', 'vue-router', 'axios'],
3 app: './src/main.js'
4}
1// .babelrc
2{
3 "presets": [
4 ["env", {
5 "modules": false,
6 "targets": {
7 "browsers": [
8 "> 1%",
9 "last 3 versions",
10 "Firefox ESR",
11 "not ie < 10"
12 ]
13 },
14 "debug": false,
15 "useBuiltIns": true
16 }],
17 "react",
18 "stage-2"
19 ]
20}
極致壓縮js,css代碼
1var os = require('os')
2var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
3
4plugins: [
5 new webpack.optimize.UglifyJsPlugin({
6 // 利用多核能力壓縮
7 beautify: {
8 cache: true,
9 workers: os.cpus().length
10 },
11 // 最緊湊的輸出
12 beautify: false,
13 // 刪除全部的註釋
14 comments: false,
15 compress: {
16 // 在UglifyJs刪除沒有用到的代碼時不輸出警告
17 warnings: false,
18 // 刪除全部的 `console` 語句
19 drop_console: true,
20 // 內嵌定義了可是隻用到一次的變量
21 collapse_vars: true,
22 // 提取出出現屢次可是沒有定義成變量去引用的靜態值
23 reduce_vars: true,
24 },
25 sourceMap: true
26 }),
27 new OptimizeCSSPlugin({
28 cssProcessor: require('cssnano')({ zindex: false }),
29 cssProcessorOptions: {
30 safe: true,
31 discardComments: {removeAll: true }
32 }
33 })
34]
第三方庫的依賴過濾,以下:
1// 此插件默認所有引入語言庫,但咱們只用到了中文,最多英文,因此進行了過濾,大大減小了整體代碼量
2plugins: [
3 new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /zh|en/)
4]
manifest.js文件內聯(app.css能夠自行選擇,當小於10k是最好內聯),webpack推薦配置以下:
1// 引入內聯插件
2var HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin')
3
4plugins:[
5 // ...
6 new HtmlWebpackPlugin({
7 // ... 其餘不相關配置省略
8 inlineSource:/(app\.(.+)?\.css|manifest\.(.+)?\.js)$/,
9 // ...
10 }),
11 new HtmlWebpackInlineSourcePlugin()
12]
這樣能最大化利用瀏覽器緩存
1// 不固定版本,會形成打包後 hash 值變化,瀏覽器沒辦法利用自己的緩存加載js,每次上線都會使本地緩存失效,頁面加載變慢
2"dependencies": {
3 "moment": "2.17.1",
4 "querystring": "0.2.0",
5 "sprite-cli": "0.1.5",
6 "sticky-state": "2.4.1",
7 "superagent-jsonp": "0.1.1",
8 "underscore": "1.8.3",
9 "vue": "2.0.0",
10 "vue-lazyload": "0.8.3",
11 "vue-router": "2.0.0",
12 "vuex": "2.0.0"
13}
因爲cssnano
默認配置,是自動會把z-index
重置爲1,例如:
1classname {
2 z-index:1000;
3}
4
5after
6
7classname {
8 z-index:1;
9}
這時候須要優化cssnano的配置,.postcssrc 以下:
1/* eslint-disable no-unused-vars */
2module.exports = {
3 plugins: {
4 cssnano: {
5 preset: [
6 'advanced',
7 {
8 zindex: false,
9 }
10 ]
11 }
12 }
13}
須要注意的是,當使用按需加載的功能,而後沒有提取全部chunk
包裏的css
,同時又開啓了sourcemap
功能,那麼就會形成這種狀況
最簡單的辦法就是,對css
不使用sourcemap
功能,例如:
1rules: [
2 {
3 loader: 'postcss-loader',
4 options: {
5 sourceMap: false
6 }
7 }
8]
如下是筆者基於 vue-cli 的模版優化後的vue
和react
的打包工具,用法一致。
如下包集成了以上全部優化,支持單頁面及多頁面應用,徹底兼容vue-cli
生成的模版項目
zz-webpack-vue
zz-webpack-react
如下是使用本組一個vue-cli生成的項目作的一個優化對比:
優化前:
優化後:
能夠查看具體的優化配置,或者直接在項目中嘗試使用,有任何問題歡迎隨時反饋,目前正在籌劃統一升級webpack4