webpack系列学习(四)性能优化(上)

开发环境性能优化

一、优化打包构建速度

1、HMR 热模块替换

当一个模块发生变化时,只有打包一个模块,不会全打包。
开启方式:`devServer添加hot:true`
css文件:style-loader已包含不需要处理
html文件:开启hmr导致html文件不能热更新,需要再入口处更改:
`entry: ['./src/js/index.js', './src/index.html'],`

js文件:添加js代码,只能监听非入口js文件

if (module.hot) {
  // 一旦为true,
  module.hot.accept('./print.js', () => {
    // 监听print.js的变化,一旦发生变化,默认不会重新打包构建
    print();
  });
}

二、优化代码调试

1、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']
    },
]

2、babel缓存

与HMR相似,一个js文件改变后,只打包此文件,在babel-loader中开启

{
    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
    }       
},

二、优化代码运行的性能

1、文件资源缓存(hash-chunkhash-cotenthash)

在生产环境有强缓存时,若改变某文件重新打包,但是浏览器还会请求缓存的数据,导致看不到改变的内容。
三种hash值:
hash:每次webpack构建时会生成一个唯一的hash值
  问题: 因为js和css同时使用一个hash值,如果重新打包,会导致所有缓存失效(可能我只是改了一个文件)
  所以,使用chunkhash,根据chunk生成的hash值,如果打包来源同一个chunk,则hash值一样,又导致一个问题,js和css的hash值还是一样的,因为css是在js中被引入的,所以同属于一个chunk
  所以,使用contenthash:根据文件的内容生成hash值

改动output文件配置:

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

改动css输出配置:

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

2、tree-shaking树摇

前提:使用es6模块化,使用production,作用,减少代码体积

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

3、code split代码分割

可以将一个文件分成多个文件并行加载速度更快,而且可以实现按需加载
1.第一种方式:多入口

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

生成两个分别名叫main和test的js文件

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

2.第二种方式

// 2.可以将node_modules中代码单独打包一个chunk输出
// 比如js文件中引入了jquery,将juqery单独打包
// 也可以自动分析多入口chunk中,有没有公共文件(比如都引入了jquery),有的话将jquery只打包成一个chunk,不会生成两个
optimization: {
    splitChunks: {
        chunks: 'all'
    }
},

3.第三种方式

单入口,但我想单独打包非入口文件的一个js文件

在入口js文件:

import(/* webpackChunkName: 'test' */'./test')
.then((add) => {
// 文件加载成功
// eslint-disable-next-line
console.log(add(2, 5));
})
.catch(() => {
// eslint-disable-next-line
console.log('文件加载失败')
})

你可能感兴趣的:(前端,webpack)