webpack性能优化

387 阅读3分钟

构建速度

  • 更新npm版本
  • 优化打包速度 babel-loader
//开发环境
{
    test: /\.js$/,
    //加缓存
    use: ['babel-loader?cacheDirectory'],
    //明确范围
    include: srcPath,
    exclude: /node_modules/
}
  • IgnorePlugin
//生产环境
//开发环境
//避免引入无效模块
// 忽略 moment 下的 /locale 目录,忽略所有语言包
new webpack.IgnorePlugin(/\.\/locale/, /moment/),
//自定义引入需要的语言包
import 'moment/locale/zh-cn'

  • noParse
//生产环境
//避免重复打包
module.export = {
    module:{
      //忽略一些xxx.min.js已经打包压缩好了的文件
      noParse: [/react\.min\.js$/]
    }
}

  • happyPack
//生产环境
//多进程打包
//module
{
    test: /\.js$/,
    // 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
    use: ['happypack/loader?id=babel'],
    include: srcPath,
    // exclude: /node_modules/
},
//plugin
new HappyPack({
    // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
    id: 'babel',
    // 如何处理 .js 文件,用法和 Loader 配置中一样
    loaders: ['babel-loader?cacheDirectory']
}),


//遇到的问题:1
在使用happypack插件的时候,会碰到this.getOptions is not a funtion的问题,网上搜的大部分是less-loader,sass-loader的版本过高,但是我并没有安装这两个
解决办法:降低style-loader,css-loader版本
//问题2
happypack插件不能与MiniCssExtractPlugin公用,也会出现上述问题,降低版本无效,暂时搁置?

//插件记录:
//记录各个模块的打包时间
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
//查看打包后各个包的体积
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
//为模块提供中间缓存,使用无效,暂且搁置?
//Cannot read property 'tap' of undefined
//配置cache:true也可以
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');


  • HardSourceWebpackPlugin
//为模块提供中间缓存步骤,第一次构建正常,第二次加快90%速度
//此插件可代替Dllplugin
  • parallelUglifyPlugin
//生产环境
//webpack内置Uglify工具压缩
//多进程压缩js
// 使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码
new ParallelUglifyPlugin({
    // 传递给 UglifyJS 的参数
    // (还是使用 UglifyJS 压缩,只不过帮助开启了多进程)
    uglifyJS: {
    output: {
        beautify: false, // 最紧凑的输出
        comments: false, // 删除所有的注释
        },
    compress: {
        // 删除所有的 `console` 语句,可以兼容ie浏览器
        drop_console: true,
        // 内嵌定义了但是只用到一次的变量
        collapse_vars: true,
        // 提取出出现多次但是没有定义成变量去引用的静态值
        reduce_vars: true,
        }
    }
})

//项目较大,打包比较慢,开启多进程能提高打包速度
//项目较小,开启多进程会降低速度(进程开销)
  • Dllplugin
//开发环境
//动态链接库插件,将业务代码和第三方代码区分
创建一个webpack.dll.js文件,打包一些第三方库的代码,用到Dllwebpackplugin
在webpack.config.js文件要用到addAssetsHtmlPlugin和DllreferencePlugin
//缺点:过于繁琐,用hardSourceWebpackPlugin代替
  • 自动刷新
watch: true, // 开启监听,默认为 false
watchOptions: {
    ignored: /node_modules/, // 忽略哪些
    // 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
    aggregateTimeout: 300,
    // 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的
    poll: 1000
}
  • 热更新
//不能用于生产环境
//自动刷新:整个网页刷新,速度较慢,网页数据消失
//热更新:新代码生效,网页不刷新,数据不丢失
new HotModuleReplacementPlugin()
devServer: {
    hot:true
}
// 增加,开启热更新之后的代码逻辑
if (module.hot) {
    module.hot.accept(['./math'], () => {
        const sumRes = sum(10, 30)
        console.log('sumRes in hot', sumRes)
    })
}

产出代码优化

  1. 体积更小
  2. 合理分包,提出重复逻辑
  3. 速度更快,内存使用小
  • 小图片base64编码 url-loader
  • bundle打包出的路径加hash
  • 懒加载
  • 提取公共代码
  • IgnorePlugin
  • CDN加速
  • 使用production
//自动压缩代码UglifyPlugin
//自动删除调试代码
//自动启动Tree-Shaking(删除没有用到的代码)
条件:必须要ES Module下才能生效,commonjs不行
mode: production
ES Module和Commonjs的区别
1.ES Module 静态引入,编译时引入,所以import只能在最上面引入
2.Commonjs 动态引用,执行时引入
只有静态引用的规范,才能实现Tree-Shaking
  • 使用Scope Hosting
//把多个函数合并成一个函数
new ModuleConcatenationPlugin()