webpack构建打包的性能优化实战指南

 更新时间:2022年03月11日 15:16:06   作者:如期_而至  
webpack是前端开发中比较常用的打包工具之一,另外还有gulp,grunt,下面这篇文章主要给大家介绍了关于webpack构建打包的性能优化的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

前言

开发的时候,如果每次我们修改了文件,webpack都能很迅速地帮我们编译完构建完而且浏览器能保存状态更新内容,体验会比较好;优化产出代码,减小体积,设置hash,可以提升生产环境上网页的加载速度

一、优化打包构建速度,提升开发体验和效率

1.1 优化babel-loader

开启缓存,只要是es6代码没有改动的部分,下次重新构建的时候可以使用缓存,不被重新编译。

    rules: [
        {
            test: /\.js$/,
            loader: ['babel-loader?cacheDirectory'],
            include: srcPath, //设置include或者exclude的范围,限定需要编译文件的目录范围
            //exclude: /node_modules/
        }
    ]

1.2 IgnorePlugin,避免引入无用模块

比如有些库包含多个国家的语言包(moment.js),我们只需要中文包或者英文报,所以我们需要避免引入不需要的语言包,

    plugins: [
        //忽略moment下的/locale目录,再手动import locale内部我们需要使用到的语言包
        new webpack.IgnorePlugin(/\.\/local/,/moment/)
    ]

1.3 noParse 避免重复模块化解析

代码中如果有xx.min.js之类的文件,基本已经采用模块化处理过的,无需在对类似文件进行递归解析处理,会引入进项目

module: {
    noParse: [/xx\.min\.js$/]
}

1.4 happyPack 多进程打包

开启多进程打包,提高构建速度

rules: [
    {
        test: /\.js$/,
        //把对.js文件的处理转交给id为babel的HappyPack实例
        use: ['happypack/loader?id=babel'],
        include: srcPath
    }
],
plugins: [
    new HappyPack({
        //用唯一的标识符id来代表当前的HappyPack是用来处理一类特定的文件
        id: 'babel',
        //如何处理.js文件,用法和loader配置中一样
        loaders: ['babel-loader?cacheDirectory']
    })
]

1.5 ParallelUglifyPlugin多进程压缩js

在生产环境中使用,因为在开发环境下没有必要压缩js代码

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

1.6 热更新

改完代码,浏览器无需刷新,新代码生效,状态保留。

entry: {
    index: [
        'webpack-dev-server/client?http://localhost:8080/',
        'webpack/hot/dev-server',
        path.join(srcPath, 'index.js')
    ],
    other: path.join(srcPath, 'other.js')
}

plugins: [
    new HotModuleReplacementPlugin()
]

devServer: {
    xxx: 'xx'
    hot: true //开启热更新
}

配置完后,修改样式,热更新生效了,但修改js,热更新没有生效,接下来还需要在js中设置允许热更新监听的模块

if(module.hot){
    module.hot.accept(['xxx文件名'], () => {
        //在注册了热更新的js文件修改后,才会进行热更新
    })
}

1.7 DllPlugin动态链接库插件

前端框架如Vue、React,体积大,构建慢,比较稳定,不常升级版本。这种情况下,同一个版本只构建一次,不用每次都重新构建; 由于webpack已内置DllPlugin,所以不需我们额外安装插件,包含两个插件 DllPlugin(用来打包出dll文件,只要打包过,就不需要再打包了),DllReferencePlugin(使用dll文件)

//webpack.dll.js文件中的配置
mode: 'development', 
entry: {
    //把react相关模块放到一个单独的动态链接库
    react: ['react','react-dom']
},
output: {
    //输出动态链接库的文件名称,[name]代表当前动态链接库的名称
    filename: '[name].dll.js',
    path: distPath,
    //存放动态链接库的全局变量名称,例如对应react来说就是 _dll_react
    //之所以在前面加上_dll_是为了防止全局变量冲突
    library: '_dll_[name]'
}
plugins: [
    new DllPlugin({
        //动态链接库的全局变量名称,需要和output.library中保持一致
        //该字段的值也就是输出的manifest.json文件中name字段的值
        name: '_dll_[name]',
        path: path.join(distPath, '[name].manifest.json')
    })
]

配置好webpack.dll.js后,在package.json文件中定义执行webpack.dll.js的命令

    "script": {
        "dll": "webpack --config build/webpack.dll.js"
    }

以上配置完执行dll打包命令打包后会产出react.dll.js和react.manifest.json文件,需要在项目中使用到打包后的react.dll.js

//在inde.html中
<script src="./react.dll.js"></script>
//在webpack.dev.js中
plugins: [
    new DllReferencePlugin({
        //描述react动态链接库的文件内容
        manifest: require(path.join(distPath, 'react.manifest.json'))
    })
]

二、webpack性能优化-产出代码

可以从体积更小;合理分包,不重复加载;速度更快、内存使用更少这几方面去进行优化

  • 2.1 小图片base64编码,使用url-loader,可减少网络请求
  • 2.2 bundle加hash,如果文件没有变,hash值不变,浏览器可以命中缓存
  • 2.3 提取公共代码,可以是整个项目的体积更小
  • 2.4 IngorePlugin 忽略库中不需要的包
  • 2.5使用cdn加速
output: {
    publicPath: 'http://cdn.xxx.com'//引用文件路径是,路径名前加cdn域名的前缀
}

打包后,将代码放入cdn域名对应的服务器中。

  • 2.6 使用production

mode为production时,打包后的代码会自动压缩,Vue/React会自动删掉调式代码(如开发环境的warning),也会自动启用Tree-Shaking,将未使用到的代码删掉

mode: "production"
  • 2.7 Scope Hosting

将多个函数合并到一个函数中,可以使代码体积更小,创建的函数作用域更少,代码可读性更好

module.exports = {
    resolve: {
        mainFields: ['jsnext: main','browser','main']
    },
    plugins: [
        //开启Scope Hosting
        new ModuleConcatenationPlugin()
    ]
}

总结

到此这篇关于webpack构建打包的性能优化的文章就介绍到这了,更多相关webpack构建打包性能优化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 轻松实现HTML和JS之间的转化的代码

    轻松实现HTML和JS之间的转化的代码

    轻松实现HTML和JS之间的转化的代码...
    2007-09-09
  • js中数组解构与对象解构示例代码

    js中数组解构与对象解构示例代码

    数组解构是一种在 JavaScript 中从数组中提取值并将它们分配给变量的方式,在数组解构中分为完全解构,不完全解构,解构失败以及解构默认值,这篇文章主要介绍了js中数组解构与对象解构,需要的朋友可以参考下
    2023-09-09
  • 一分钟理解js闭包

    一分钟理解js闭包

    一分钟理解js闭包,关于js闭包的内容介绍了很多,本文带着大家快速理解什么是js闭包,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • js实现鼠标点击左上角滑动菜单效果代码

    js实现鼠标点击左上角滑动菜单效果代码

    这篇文章主要介绍了js实现鼠标点击左上角滑动菜单效果代码,涉及JavaScript基于鼠标事件动态变换页面元素样式的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-09-09
  • 深入分析javascript中的错误处理机制

    深入分析javascript中的错误处理机制

    这篇文章主要介绍了深入分析javascript中的错误处理机制的相关资料,需要的朋友可以参考下
    2016-07-07
  • jQuery实现随意改变div任意属性的名称和值(部分原生js实现)

    jQuery实现随意改变div任意属性的名称和值(部分原生js实现)

    用原生js和jQuery实现随意改变div属性和重置,在输入框输入“属性名”及“属性值”,点击确定按钮查看效果,感兴趣的你可不要错过了哈
    2013-05-05
  • js实现杯子倒水问题自动求解程序

    js实现杯子倒水问题自动求解程序

    智力测试题经常遇到类似的逻辑题,给几个容量不等的杯子,让你倒出多少的水,感兴趣的朋友可以参考下哈希望可以帮助到你
    2013-03-03
  • JS实现的加减乘除四则运算计算器示例

    JS实现的加减乘除四则运算计算器示例

    这篇文章主要介绍了JS实现的加减乘除四则运算计算器,涉及javascript事件响应及数学运算相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • 浅谈JS三座大山之异步和单线程

    浅谈JS三座大山之异步和单线程

    首先我们要知道,js这门语言是单线程的,同时只能做一件事,比如说渲染dom,执行js方法,这些事情只能一个一个做,不能分开执行。(因为js需要操作dom,当两个js方法同时操作一个dom的时候就会出问题,所以js被设计成了单线程)。本文将介绍JS三座大山之异步和单线程。
    2021-06-06
  • 微信小程序网络封装(简单高效)

    微信小程序网络封装(简单高效)

    这篇文章主要介绍了微信小程序网络封装(简单高效),微信小程序的网络请求很便捷,直接调用就可以了。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08

最新评论