webpack系列學習(四)性能優化(上)

開發環境性能優化

1、優化打包構建速度

一、HMR 熱模塊替換

當一個模塊發生變化時,只有打包一個模塊,不會全打包。
開啓方式:`devServer添加hot:true`
css文件:style-loader已包含不須要處理
html文件:開啓hmr致使html文件不能熱更新,須要再入口處更改:
`entry: ['./src/js/index.js', './src/index.html'],`

js文件:添加js代碼,只能監聽非入口js文件css

if (module.hot) {
  // 一旦爲true,
  module.hot.accept('./print.js', () => {
    // 監聽print.js的變化,一旦發生變化,默認不會從新打包構建
    print();
  });
}

2、優化代碼調試

一、source-map一種提供源代碼到構建後代碼的映射技術

開發環境:速度快,調試更友好
速度快(eval>inline>cheap...)
eval-cheap-source-map>eval-source-map
調試更友好
source-map>cheap-module-source-map>cheap-source-map

--> eval-source-map折中的最好的選擇 或者 eval-cheap-source-map
生產環境:源代碼要不要隱藏,調試要不要更友好
內聯會讓代碼體積變大,因此生產不用內聯
nosource-source-map 所有隱藏
hidden-source-map  只隱藏源代碼,會提示構建後代碼錯誤
-->source-map / cheap-module-source-map

生產環境性能優化

1、優化打包構建速度

一、oneOf能讓loader找到了就再也不往下繼續找了

oneOf:[
   {
        test: /\.css$/,
        use: [...commonCssLoader]
    },
    {
        test: /\.less$/,
        use: [...commonCssLoader, 'less-loader']
    },
]

二、babel緩存

與HMR類似,一個js文件改變後,只打包此文件,在babel-loader中開啓html

{
    test: /\.js$/,
    exclude: /node_modules/,    
    // 
    loader: 'babel-loader',
    options: {
        presets: [
            [
                '@babel/preset-env', // 基本兼容
                {
                    // 按需加載
                    useBuiltIns: 'usage',
                    corejs: {
                        version: 3
                    },
                    // 指定兼容性作到哪一個版本的瀏覽器
                    targets: {
                        chrome: '60',
                        firefox: '60',
                        ie: '9',
                        safari: '10',
                        edge: '17'
                    }
                }
            ]

        ],
 // 開啓babel緩存,第二次構建時,會讀取以前的緩存
        cacheDirectory: true
    }       
},

2、優化代碼運行的性能

一、文件資源緩存(hash-chunkhash-cotenthash)

在生產環境有強緩存時,若改變某文件從新打包,可是瀏覽器還會請求緩存的數據,致使看不到改變的內容。
三種hash值:
hash:每次webpack構建時會生成一個惟一的hash值
  問題: 由於js和css同時使用一個hash值,若是從新打包,會致使全部緩存失效(可能我只是改了一個文件)
  因此,使用chunkhash,根據chunk生成的hash值,若是打包來源同一個chunk,則hash值同樣,又致使一個問題,js和css的hash值仍是同樣的,由於css是在js中被引入的,因此同屬於一個chunk
  因此,使用contenthash:根據文件的內容生成hash值

改動output文件配置:node

output: {
    filename: 'js/built.[contenthash:10].js',
    path: resolve(__dirname, 'build')
},

改動css輸出配置:jquery

new MiniCssExtractPlugin({
    filename: 'css/built.[contenthash:10].css'
}),

二、tree-shaking樹搖

前提:使用es6模塊化,使用production,做用,減小代碼體積webpack

package.json增長
`"sideEffects": ["*.css", "*.less"]`

三、code split代碼分割

能夠將一個文件分紅多個文件並行加載速度更快,並且能夠實現按需加載
1.第一種方式:多入口es6

entry: {
    // 1.多入口
    main: './src/js/index.js',
    test: './src/js/test.js'
},

生成兩個分別名叫main和test的js文件web

output: {
    // 1.[name]:取文件名
    filename: 'js/[name].[contenthash:10].js',
    path: resolve(__dirname, 'build')
},

2.第二種方式chrome

// 2.能夠將node_modules中代碼單獨打包一個chunk輸出
// 好比js文件中引入了jquery,將juqery單獨打包
// 也能夠自動分析多入口chunk中,有沒有公共文件(好比都引入了jquery),有的話將jquery只打包成一個chunk,不會生成兩個
optimization: {
    splitChunks: {
        chunks: 'all'
    }
},

3.第三種方式json

單入口,但我想單獨打包非入口文件的一個js文件

在入口js文件:瀏覽器

import(/* webpackChunkName: 'test' */'./test')
.then((add) => {
// 文件加載成功
// eslint-disable-next-line
console.log(add(2, 5));
})
.catch(() => {
// eslint-disable-next-line
console.log('文件加載失敗')
})
相關文章
相關標籤/搜索