前端优化小结

87 阅读2分钟

image.png

babel优化 useBuiltIns: 'usage', module: false,走runtime包 只打包使用的文件而且才有esm规范

修改 babel.config.js 配置 , 详见 我掌握的Babel配置(带视频)

module.exports = {
    presets: [
      [
        "@babel/preset-env",
        {
          modules: false,
          useBuiltIns: "usage",
          corejs: 2
        },
      ],
    ],
    plugins: ["@babel/plugin-transform-runtime"],
};

webpack优化:打包缓存,多进程,oneOf,代码压缩

  • 缓存两部分 eslint 和 babel, 因为js经常进行eslint检查和babel编译,所以要缓存结果

  • 因为rules匹配是匹配到一个后,会继续往下匹配,oneOf作用就是只做唯一匹配就退出

  • 多进程是利用电脑多核加快打包,如果代码简单就没必要,会有开启进额外开销600ms,多进程优化babel,eslint,terser包(压缩js和html)

  • 压缩css使用css-minimizer-webpack-plugin

  • 检查tree-shaking,optimization下默认sideEffects:true,usedExports:true,生产环境默认都是true

  • 图片压缩 image-minimizer-webpack-plugin (exe文件可能下载不下来,很烦人,可跳过,用下面webp)

以及无损压缩

npm install image-minimizer-webpack-plugin imagemin --save-dev
npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo --save-dev
  • 图片转webp

  • 拆包 optimazation 中 splitChunks 详见 webpack的摇树、拆包、热更新、按需加载等难点

  • 预加载,preload和prefetch,都是先加载不执行,当前页面要用的用preload,下一个页面要用的用prefetch,插件 @vue/preload-webpack-plugin,webpack5内置

  • runtimeChunk 配置,把模块依赖关系存起来,某个文件修改后只改某个文件的hash

webpackPrefetch: true
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
const ESLintPlugin = require('eslint-webpack-plugin')
const TerserPlugin = require("terser-webpack-plugin")
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin")
const threadLoader = require('thread-loader')
const os = require('os')  // 核心包,直接调用
const threads = os.cups().length // cpu核数

{
    module: {
        rules:[
            {
                oneOf:[
                    {
                        test: /\.css/,
                        use: ['style-loader','css-loader']
                    },
                    {
                        test: /\.js$/,
                        exclude: /node_modules/,
                        use:[
                          {
                            loader: 'thread-loader', // 开启多进程和进程数量
                            options:{
                                workers: threads 
                            }
                          },{
                            loader: 'babel-loader',
                            options: {
                                cacheDirectory: true,  // 开启babel缓存,会在node_modules下生产.cache文件夹
                                cacheCompression: false  // 关闭缓存文件压缩
                            }
                        }]
                    }
                ]
            }
        ]
    },
    plugins:[
        new ESLintPlugin({
            context: path.resolve(__dirname,'./src'),
            exclude: 'node_modules',
            cache: true, // 开启缓存
            cacheLocation: path.resolve(__dirname,'./node_modules/.cache/eslintcache'),
            threads   // 开启多进程和进程数量
        }),
    ],
    optimization:{
        minimize: true,
        minimizer: [
            new CssMinimizerPlugin(),  // 压缩css
            new TerserPlugin({
              parallel: threads  // 开启多进程和进程数量
            }),
            new ImageMinimizerPlugin({  // 图片无损压缩
              minimizerOptions: {
                plugins: [
                  ["gifsicle", { interlaced: true }],
                  ["jpegtran", { progressive: true }],
                  ["optipng", { optimizationLevel: 5 }],
                  [
                    "svgo",
                    {
                      plugins: extendDefaultPlugins([
                        {
                          name: "removeViewBox",
                          active: false,
                        },
                        {
                          name: "addAttributesToSVGElement",
                          params: {
                            attributes: [{ xmlns: "http://www.w3.org/2000/svg" }],
                          },
                        },
                      ]),
                    },
                  ],
                ],
              },
            }),
        ]
    }
}

三方包的按需加载

有了tree-shaking,为什么还要做按需加载呢?

  • 引入的样式文件通常只有一个是所有样式的合并,按需加载减少样式文件大小

  • 三方库可能没有做esm导出统一入口,具体要看包的package.json的module字段是否有,否则就是commonjs导出的

  • 具体像我们用到的组件库,elment,antd

  • 用到的工具库 loadsh

  • 比如 moment.js 较大,可以换成 dayjs