webpack性能优化(二)减少打包体积

204 阅读2分钟
文章开头第一句加入:本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

可以用webpack-bundle-analyzer插件来分析各个模块的体积占比,再针对性优化。

1.图片的压缩与优化

url-loader转化为base64

对于较小的图片可以转化为base64格式,可以减少http请求。

module: {
    rules: [
      {
        test: /.(png|jpg|gif)$/i,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192,
            },
          },
        ],
      },
    ],
  },

image-webpack-loader

通常一个项目我们会引入很多各种格式的图片,多张图片被打包以后,如果不做压缩的话,体积还是相当大的。我们可以使用image-webpack-loader进行图片压缩

2.js压缩

使用terser-webpack-plugin ,也可用 uglifyjs-webpack-plugin 进行js压缩;后者已不再维护

module.exports = {  
    optimization: {  
        minimizer: [  
            new TerserPlugin({  
                parallel: true,  
                cache: true  
            })  
        ]  
    }  
}

3.css压缩

CssMinimizerPlugin进行css插件

optimization: {
    minimizer: [
        new CssMinimizerPlugin()
    ]
}

4.treeShake

用来清除代码中无用代码,tree-shaking 在mode为production中自动生效 Babel的preset默认会将任何模块类型都转译成CommonJS类型,这样会导致tree-shaking失效;需在配置中加上modules: false;

module: {
    rules: [
        {
            test: /\.js$/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env', { modules: false }]
                }
            }
            exclude: /(node_modules)/
        }
    ]
}

5.polyfill按需引用

项目中会使用babel来将很多es6中的API进行转换成es5,但是还是有很多新特性没法进行完全转换,比如promise、async await、map、set等语法,那么我们就需要通过额外的polyfill(垫片)来实现语法编译上的支持。但我们并不是所有的es6语法都用到;故需按需引入

{
  "presets": [
    "@babel/preset-env",
    {
      "useBuildIns": "useage"
    }
  ]
}

6.代码分割

拆分代码(code Spliting)减少main.js包的体积

optimization: {
    splitChunks: {
        chunks: 'all',
        minSize: 10000,
    }
}

7.Scope Hoisting (作用域提升)

让打包出来的文件体积更小,运行更快。
只有被引用了一次的模块才会被合并,其余的会被抽离作为公共模块。
通过设置optimization.concatenate = true则开启。

8.GZip压缩

开启Gzip后,大大提高用户的页面加载速度,需要后端的配合,使用 compression-webpack-plugin

plugins: [
    new CompressionPlugin({
      algorithm: 'gzip',
      threshold: 10240,
      minRatio: 0.8
    })
  ]

9.擦除没有用到的css

purgecss-webpack-plugin识别用到的css class

const PATHS = {  
  src: path.join(__dirname, 'src'),  
};  
plugins: [  
new PurgecssPlugin({  
      paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }),  
    }),  
]

10.懒加载

使用懒加载或者按需加载,在一些代码块中完成某些操作后,引用另一些新的代码块。这样可以加快应用的初始加载速度,减轻了它的整体体积,因为某些代码块可能永远不会被加载。 import 加载js文件,会返回一个promise

懒加载js

function creatEle() {
    return import (/*webpackChunkName: 'lodash'*/'lodash').then(({default: _})=>{
     //do something
    })
}

路由懒加载

const HelloWorld = ()=>import("@/components/HelloWorld")
export default new Router({
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component:HelloWorld
    }
  ]
})