美文网首页
webpack 打包优化

webpack 打包优化

作者: 茂茂爱吃鱼 | 来源:发表于2018-10-31 19:58 被阅读0次

    最近使用 Vue 2 + Webpack 4 + axios + ElementUI 搭建了个后台系统,开发过程中发现打包出来的 bundle 过大,时间较长,遂优化之。

    目前已知问题的优化

    问题1:为了让 babel 正确解析 async/await,引入了 babel-polyfill,其实不需要所有的 polyfills,只包含 async/await 的特定 polyfills 即可

    解决方法:去掉 babel-polyfill,在 babel 配置中添加"targets": { "node": "current" }来包含用于运行 Babel 和 Node 最新版所必须的 polyfills 和 transforms

    [18-11-20 修改] 使用 node 最新版解析有部分浏览器打不开的情况(如:百度浏览器), 现修改为浏览器解析 "targets": { "browsers": [ "last 2 versions", "IE >= 9" ] }
    针对不兼容 async/await 的情况引入 regenerator 即可
    (顺便提一下,由于 IE 浏览器只兼容 11% 的 ES6 特性,针对这类浏览器全局引入 polyfill 有些不合理,如果有兼容 IE 的需求,可以考虑引入 polyfill.io,他可以检测浏览器内核,然后根据需要引入相应 polyfill)

    问题2:全局引入 ElementUI,导致打包太慢且 bundle 过大
    全局引入ElementUI,导致打包太慢且bundle过大

    解决方法:考虑到小伙伴们使用便捷度及按需引入代码不够美观(每次使用都需要import一下),放弃按需引入,采用全局引入方式。使用CDN + externals方式引入可以避免每次代码更改都重新打包的问题,但是需要在HTML中手动添加链接,若有依赖还得注意依赖的引入,且更改麻烦;使用NPM安装,能更好的与webpack等模块打包器配合使用,所以考虑合理拆分依赖库,最好可以独立出来单独打包

    分析

    step1.png
    bundle.png

    先看下目前打包的情况,可见,时间大概约27s,bundle的大小约1M,其中element-ui占了一大半

    1. Code Splitting
      webpack 4 废弃了之前的CommonsChunk,取而代之的是SplitChunks。考虑到element-ui较大,若直接一刀切,将node_modules抽取出来,打包出来的bundle仍然很大,所以做了如下的拆分


      step2-code.png

      vue & vue-router 单独拆分为vueBase
      axios & qs & viewerjs & v-viewer 单独拆分为base
      elementUI 拆分为 lib 和 common


      step2.png
      step2-res.png
      可见原来的bundle被拆分为了5个,但是打包时间并未减少,类似element-ui这种不常更改的基础库能否避免每次代码更改都重新打包呢
    2. DllPlugin & DllReferencePlugin
      这两个插件搭配使用,作用是将不常用的公共库抽离并进行预编译,这样每次构建的时候无需再重复构建这些库,大大提升构建速度。


      step3-code.png

      将以上库单独打包为vendor,然后每次构建的时候直接引入vendor即可,无需重复构建。


      step3-res.png
      step3.png
      构建时间直接降到了不到12s,提速明显。
      遗憾:dllPlugin不能抽离css,导致element-ui相关css还是需要重复构建

      思考:如果这些库基本不变的话没什么问题,但如果后期需要增删改其中的一个或多个,就需要重新构建,即使只改了一行代码,由于原来的hash变了,缓存失效需要重新加载整个vendor,因此该方式并不适合生产环境的构建

    3. CDN
      之前提到过CDN+externals方式的弊端,鉴于CDN方式的优势,想想有没有办法解决这些弊端呢。
      找到了个很好的工具 webpack-cdn-plugin 根据你安装的包版本及指定的CDN地址自动引入对应CDN资源,只需更改webpack配置即可。
      添加如下配置,将vue/vue-router/element-ui改为CDN方式引入

      cdn-code.png
      构建结果如下:
      bundle-html.png
      cdn-res.png
      cdn.png
      bundle大小和速度都比较可观
    4. 其他优化
      避免无用解析,如:loader解析过滤掉node_modules等
      loader开启缓存,以babel-loader为例,改为loader: babel-loader?cacheDirectory=true
      精简不必要的模块,如原本为了使用cssnano特意引入了postcss,但发现css-loader开启了minimize仍然无效,经调试发现与cssnano冲突,于是换成了更为精简的 optimize-css-assets-webpack-plugin ,然后设置使用cssnano来处理css,原有问题完美解决
      uglify并行执行压缩,如webpack 3 时代使用的 webpack-uglify-parallel来允许多核并行执行,webpack 4 的uglify-plugin自带了这个功能,在插件配置中添加parallel: true开启即可。


    经过一顿折腾之后看看最后的构建结果^^


    result.png

    相关文章

      网友评论

          本文标题:webpack 打包优化

          本文链接:https://www.haomeiwen.com/subject/cwzttqtx.html