渐进式优化项目前端工作流–webpack配置更新

背景

最近入职的公司是一家TO B公司, 前后端分离,几乎所有的业务逻辑都是后端处理,前端基本上就是一个页面仔,和后端确认好字段后就可以开始单机开发。

项目维护多年,基建有很多地方都可以优化

  • 项目开发/生产环境优化
  • 前端项目持续集成
  • 公司私有组件库
  • 性能优化等等

从这里起,会持续记录优化的过程,今天先来看看项目webpack配置的更新。

开发环境与生产环境

修改webpack前,首先要明确的是作为一个前端工程师,工作的大部分时间都是在开发环境中度过,速度对开发工作的影响至关重要,而在生产环境中,项目的性能,文件打包构建速度,文件体积及优化才是重点。在开发环境中过分追求包体积的优化或者首屏加载速度,实在是没有必要。

本轮优化主要分为两个部分,开发环境以及生产环境。这一节,就先来优化开发效率。

webpack配置更新

公司的项目虽然是用了webpack5,依然是沿用了webpack3的配置,由于webpack5已经集成很多以前需要通过loader或plugin来实现的功能,如编译缓存,file-loader等等,这些在webpack5中已经集成,所以可以直接使用webpack5的配置。

另外一个方面,前端是一个更新迭代非常快的行业,webpack3的loader或plugin肯定有很多东西已经被废弃或有更优的选择,如对标babel的swc,使用swc-loader可以编译速度提升数倍甚至更多。

构建性能分析

要了解构建性能的优化对比,首先给项目加入构建性能分析工具,这里选择speed-measure-webpack-plugin

https://www.npmjs.com/package/speed-measure-webpack-plugin

在webpack配置中,几乎都会有多环境配置,每个配置都需要单独使用该插件包裹

  • speedMeasure.js

    const SpeedMeasurePlugin = require(“speed-measure-webpack-plugin”);
    const paths = require(“./paths”);
    const smp = new SpeedMeasurePlugin({
    // your config
    });

    module.exports = smp;

common.config.js

const { merge } = require("webpack-merge");
const smp = require("./utils/speedMeasure");

module.exports = smp.wrap(
  merge(
    // common config
  )
);

dev.config.js

const { merge } = require("webpack-merge");
const smp = require("./utils/speedMeasure");

module.exports = smp.wrap(
  merge(
    // dev config
  )
);

加入该组件后,即可以看到编译时间以及loader的大小

除了直接在terminal上面显示,也可以通过配置输出文件记录到日志文件上面, 可以按需配置。

图片与字体文件的处理

file-loader

在webpack5以前,如果webpack需要对图片,字体灯文件进行处理,都需要使用到file-loader,如下

{
  test: /\.(eot|woff|woff2|ttf)(\?.*)?$/,
  use: [{
    loader: require.resolve('file-loader'),
    options: {
      name: `static/[name].[hash:8].[ext]`,
      esModule: false,
    },
  }],
},

type

https://webpack.js.org/guides/asset-management/#loading-fonts

而在webpack5中,file-loader的功能已经内置可以直接通过指定文件的type让webpack进行处理

{
  test: /\.(png|jpe?g|gif|webp|ico|svg)(\?.*)?$/,
  type: 'asset/resource',
},
{
  test: /\.(eot|woff|woff2|ttf)(\?.*)?$/,
  type: 'asset/resource',
},

构建性能提速

像这种To B项目,交付按期完成远比技术升级迭代的需求要重要得多,所以对项目构建性能的重视程度很低。记得在呆过的一家业务流程差不多的公司,用一台8g的window,没保存一次平均等待20s,工作效率极低。虽然现在的项目等待时间只有几秒,但是人生苦短,编译的速度当然是越快越好。

使用swc替换babel

babel-loader

https://babeljs.io/

作为一名前端, babel对我们来说肯定不陌生,通过babel-loader我们可以对js,jsx,ts文件进行处理,转换成为当前或旧版本浏览器向后兼容的js代码。babel是使用js便携的一个代码转换工具,虽然功能强大,但局限于js本身代码的执行效率,在项目越来越大的情况下,babel所需要的时间也较长。

{
  test: /\.ts|tsx$/,
  use: [
    {
      loader: require.resolve('babel-loader'),
      options: {
        // options
      },
    },
    {
      loader: require.resolve('ts-loader'),
      options: {
        // options
      },
    },
  ],
},

swc–对标babel

https://swc.rs/

swc是使用rust编写的一个可拓展平台, 可以用于编译以及打包js代码,next.js,parcel和deno等工具都在使用.

  • 根据官网配置最基本的swc-loader

    {
    test: /.[j|t]sx?$/,
    exclude: /node_modules/,
    use: {
    loader: “swc-loader”
    }
    },

  • .swcrc

    {
    “jsc”: {
    “parser”: {
    “syntax”: “typescript”,
    “tsx”: true,
    “decorators”: true
    },
    “loose”: true
    }
    }

官方模式配置是只对js做处理,加入项目中使用到了ts,react,则需要加上对应的配置,从需要处理的文件到对浏览器支持的配置,都与babel非常相似,迁移成本较小,看这熟悉的浏览器支持版本配置

{
  "env": {
    "targets": {
      "chrome": "79"
    },
    "mode": "entry",
    "coreJs": "3.22"
  }
}

启动项目

根据分析插件的输出, 在其他配置相同的情况下, babel-loader需要时间为14s, 而swc-loader只需要2.5s, swc-loader的编译速度是babel-loader的6倍

文件修改

修改文件保存,可以看到swc的速度是babel的大概50倍

为什么速度相差这么多?

因为babel是使用js进行开发, 由于js是单线程,对繁重计算的处理并不是非常。而swc使用rust开发,在多线程中运行,而不是在js的事件循环中执行。

在官网上介绍SWC is 20x faster than Babel on a single thread and 70x faster on four cores.

在单核模式上会比babel快20倍,四核模式上快70倍,而笔者正在使用的是10核,实际情况并没有达到上面所说的效果。可能在更大型的项目中会有更加明显的效果。

开启编译缓存

明明只是加了个console,却把项目上所有需要编译的文件都编译了一次,相信是所有前端都感觉迷惑的事情,特别是维护那种大型老旧项目时特别有感觉。通过开启编译缓存 ,可以把编译结果缓存起来,文件启动以及修改某文件的编译速度会得到明显提升

在webpack5以前我们可以通过一些loader/plugin来做编译缓存,如:cache-loader,hard-source-webpack-plugin,而在webpack5中可以直接配置cache来设置编译缓存

用以下配置后,webpack会在本地生产缓存文件

  cache: {
    // 保存到文件中
    type: "filesystem",
    // 运行内存收集
    allowCollectingMemory: true,
  },

开启前

开启后

启动速度

首次启动,启动的总时间与未开启几乎相同

而启动成功后,可以在node_modules中看到webpack生成了缓存文件

在生成cache再次启动项目,启动速度只需要1s,速度大概快了5倍

文件修改,编译速度提升

随便修改一个文件,编译时间只需要0.8s

总结

本次优化是针对开发环境的速度提升,启动速度提升了数倍,编译时间降低到了1s以内,下一周开始搞生产模式的性能优化。

最后贴上和自己研究了一天猫猫

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容