webpack性能优化

77 阅读2分钟

优化打包构建速度 -- 开发体验和效率

优化babel-loader

只要是ES6代码没有改的,就不会重新编译,第二次编译的时候就直接启用缓存不会在编译

{
    test: /\.js$/,
    use: ['babel-loader?cacheDirector'], // 开启缓存
    include: path: resolve(__dirname, 'src') // 明确范围 include和exclude选一个即可
}

IgnorePlugin  避免引入无用模块

// index.js
// 如果引入moment这个日期处理类库,安装完引入之后就可以获取日期、时间、语言
// 这样默认引入所有语言JS代码,代码非常大
import moment from 'moment' 

如果系统不用支持多语言,只用支持中文或英文

// 首先在webpack.prod.js中配置
plugins: [
    ...
    // 忽略moment下的/locale目录
    new webpack.IgnorePlugin(/\.\/locale/, /moment/)
]

// index.js中手动引入需要的语言
import moment from 'moment'
// 手动引入中文语言包
import 'moment/locale/zh-cn'
// 设置语言为中文
moment.locale('zh-cn')

noParse 避免重复打包

module.exports = {
    module: {
        noParse: [/react\.min\.js$/]
    }
}

IgnorePlugin 直接不引入,代码中没有

noParse 引入,但不打包

happyPack 多进程打包

JS单线程,开启多进程打包

提高构建速度(特别是多核CPU)

// npm install happypack --save-dev
const HappyPack = require('happypack')


pugins: [
    ...
    // happyPack 开启多进程打包
    new HappyPack({
        // 用唯一的标志符 id 来代表当前的 HappyPack 是用来处理一类特定的
        id: 'babel',
        // 如何处理 .js文件,用法和Loader 配置中的一样
        loaders: ['babel-loader?cacheDiretory']
    })
]

ParallelUgligyPlugin  多进程压缩JS

webpack 内置 Uglify 工具压缩 JS

Js单线程,开启多进程压缩更快

和happyPack同理

const ParalleUglifyPlugin = require('webpack-parallel-uglify-plugin')

plugins: [
    // 使用ParallelUglifyPlugin 并行压缩输出的 JS 代码
    new ParalleUglifyPlugin({
        // 传递给UglifyJS 的参数
        // (还是使用 UglifyJS 压缩,只不过帮助开启了多进程)
        uglifyJS: {
            output: {
                beautify: false, // 最紧凑的输出
                comments: false, // 删除所有的注释
            },
            compress: {
                // 删除所有的`console`语句,可以兼容ie浏览器
                drop_console: true,
                // 内嵌定义但是只用到一次的变量
                collapse_vars: true,
                // 提取出出现多次但是没有定义成变量去引用的静态值
                reduce_vars: true
            }
        }
    })
]

关于开启多进程

项目较大,打包较慢,开启多进程能提高速度

如果项目较小,打包很快,打包多进程会降低速度(进程开销)

多进程按需使用

自动刷新 

module.exports = {
    watch: true, // 开启监听,默认为false
    // 注意,开启监听之后,webpack-dev-server 会自动开启刷新浏览器!!!
    
    // 监听配置
    watchOptions: {
        ignored: /node_modules/, // 忽略哪些
        // 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
        aggregateTimeout: 300, // 默认为 300ms
        // 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的
        poll: 1000 // 默认每隔1000毫秒询问一次
    }
}

一般用不到,dev环境配置devServer自带这个功能,prod环境没权限

自动刷新:整个网页全部刷新,速度比较慢

自动刷新:整个网页全部刷新,状态会丢失

热更新 

// webpack.dev.js
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin')
entry: {
    index: [
        'webpack-dev-server/client?http://localhost:8080/',
        'webpack/hot/dev-server,
        path.join(srcPath, 'index.js')
    ]
},
plugins: [
    ...
    new HotModuleReplacementPlugin()
]


// index.js
if(module.hot) {
    module.hot.accept(['./math'], () => {
        // 热更新需要在开发环境下自行去配置哪些模块需要去注册允许热更新的
    })
}

DllPlugin 动态链接库插件

优化产出代码 -- 产品性能

使用生产环境

小图片base64编码

bundle加hash

使用CDN

提取公共代码

懒加载

scope hosting

babel

polyfill

runtime