美文网首页
加 3 行代码减少 80% 构建时间

加 3 行代码减少 80% 构建时间

作者: BingJS | 来源:发表于2023-03-22 18:37 被阅读0次

优化思路分析

要优化项目的构建速度,得先了解构建流程:

  • 开发人员推送代码到 Gitlab,触发 Gitlab 服务器的 Push Events
  • Push Events被触发后,会调用提前配置好的 Jenkins webhooks
  • Jenkins webhooks被调用后,会执行对应项目的构建任务
  • 构建任务开始后先拉取项目源码到构建机,再使用docker build构建镜像
  • docker 构建镜像分为两个阶段,先使用npm scripts构建前端项目,然后把构建产物拷贝到nginx基础镜像

在这个流程中,可以优化的环节只有构建docker镜像这一步,其他环节的耗时基本可以忽略不计。而在不大改项目的情况下能起到明显提速效果的方案是:缓存策略。构建docker镜像时可以用到的缓存包括两类:docker层缓存和应用层缓存。

docker层缓存是指docker build所产生的可重用镜像层,只要Dockerfile中的命令及相关的源文件未改变,就能直接使用这些镜像缓存。这种缓存策略在代码不改变的情况下效果很好,构建耗时甚至可以控制在 10 秒内。而对于日常开发情况下,代码频繁变化,如果应用本身构建时间又很长,则需要使用应用层缓存。

应用层缓存是指应用构建所产生的中间产物,这些中间产物主要是node_modules目录中的物理文件,其中包括npm install下载的依赖包和npm run build产生的.cache目录文件。而docker build每次都会初始化全新的环境用于构建,新环境中不存在node_modules目录,因此每次都是重新写入而无法复用,得想办法复用该目录下的文件;另外npm run build需要开启缓存功能,才会输出缓存文件到node_modules/.cache目录。

综上,优化思路主要是两点:1、开启应用层构建缓存(如webpack cache);2、持久化node_modules目录,确保每次npm install和npm run build都能复用该目录下的文件。

开启应用层构建缓存

项目使用的技术是React,构建主要依靠react-scripts@4.0.3,底层实际调用的是webpack@4.44.2,应用构建缓存主要来自webpack。webpack需要手工开启缓存功能,配置cache属性为true即可。

实际操作只有 1 步, 找到webpack.config.js设置cache:true,代码如下:

module.exports = {
  //...
  cache: true
};

本地首次npm run build构建,无缓存的情况下,耗时 13min 左右。
启用缓存后在本地进行二次构建,有缓存的情况下,无论是否修改源码构建耗时均为 4min 左右,比优化前的 13min 有明显提升。
实际上,webpack@4的缓存只在watch和development模式下生效,在上述构建测试中其实不起作用。 实测删除wepack中的cache:true配置,或者配置为cache:false,二次构建时间也是 4min 左右。

之所以构建速度提升了那么多,是因为react-scripts的webpack配置中开启了babel-loader和eslint-webpack-plugin的缓存功能,另外terser-webpack-plugin配置也默认开启了缓存功能。从缓存目录node_modules/.cache中也能看到它们的缓存文件。

所以,这一步其实啥也不用做,如果想进一步提速可以升级到webpack@5。

持久化node_modules目录

想在docker build环境中持久化node_modules需要使用到BuildKit的mount功能,该功能有几个前置条件:

  • docker 版本必须高于 18.09
  • BuildKit需要手工启用,可在docker build命令前添加环境变量DOCKER_BUILDKIT=1启用
  • 如果前两个条件不满足,则需要具备Jenkins和构建机的读写权限,以调整构建环境参数
  • 修改Dockerfile,使用RUN --mount=type=cache运行npm install和npm run build指令

实际操作分为 2 步:

  1. 修改Jenkins配置,在docker build命令前加上环境变量。修改后镜像构建命令长这样:
DOCKER_BUILDKIT=1 docker build .
  1. 修改Dockerfile,将RUN npm install和RUN npm run build指令改为RUN --mount=type=cache npm xxx。修改后Dockerfile长这样:
FROM node:alpine as builder

WORKDIR /app

COPY package.json /app/

RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
    --mount=type=cache,target=/root/.npm,id=npm_cache \
    npm i --registry=https://registry.npm.taobao.org

COPY src /app/src

RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
    npm run build

文档说由于 BuildKit 为实验特性,需要在 Dockerfile 文件开头加上如下代码:# syntax = docker/dockerfile:experimental。在Docker 20.10环境下,加了上述代码反而构建报错,原因是加载外网资源失败,删除后构建成功。这不就是玄学吗?

优化结果

在配置好缓存策略后,模拟日常开发修改项目代码触发自动构建流程,构建耗时从 20min+下降到 4min+,总体耗时减少 80%。整个优化过程修改了Jenkins的一行配置,另外在Dockerfile中添加了3行代码,改动很少但效果很不错。

相关文章

  • Webpack 减少构建时间

    Webpack 构建项目的速度很大程度上取决于项目的复杂度和电脑配置。确保项目在有足够的磁盘空间和良好的处理器情况...

  • 前端页面优化

    1.使用代码构建工具,减少http请求的次数以及减少http请求的大小。减少http请求大小还包括减少cookie...

  • Dockerfile编写规则

    编写原则 少变化的,公用的写在上面 合理使用docker缓存机制,减少构建时间 不要在镜像中clone代码,尽量使...

  • 新葡京 潮牛 泉州 Android打包步骤

    一.CocosCreator部分1.构建2.main.js 加代码(热更新要用) 3.编译(编译完一般会报错,不用...

  • java-代码规范

    关于如何提高代码可读性,有以下几点可以参考: 1 代码缩进越少,可读性越高2 函数代码量越小越好 80行以内最佳3...

  • iOS网络缓存扫盲篇--使用两行代码就能完成80%的缓存需求

    iOS网络缓存扫盲篇--使用两行代码就能完成80%的缓存需求 iOS网络缓存扫盲篇--使用两行代码就能完成80%的...

  • webpack4自定义脚手架优化

    在上篇中搭建了vue的基本脚手架,为了加快脚手架打包项目的构建速度和减少打包代码的体积,下面在上一篇的基础上添砖加...

  • 用 80 行 Javascript 代码构建自己的语音助手

    本文演示了如何使用 Web Speech API 构建一个简单的人工智能聊天机器人。 在本教程中,我们将使用 80...

  • iOS macOS开发技巧之减少 iOS 的 XCode 构建时

    提示和建议如何使用不同的工具和技巧减少 iOS 构建/编译时间,从 Xcode 构建它 有很多方法可以减少 iOS...

  • Css 小技巧

    在页面构建中,能明显提升页面显示质量的一些CSS小技巧。很多简洁美观的页面表现,可以使用CSS3代码即可实现,减少...

网友评论

      本文标题:加 3 行代码减少 80% 构建时间

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