华人澳洲中文论坛

热图推荐

    加 3 行代码增加 80% 构建时间

    [复制链接]

    2022-10-30 06:33:36 56 0

    作者:Whilconn
    http://juejin.cn/post/7135756687134162980
    配景
    比来接手的BI名目在Jenkins的构建机上构建耗时对比久,日常构建耗时都在 20min 以上,即便改变一行代码也要构建这么久。构建耗时截图如下:


    构建耗时较长致使日常测试和正式发版都会挥霍得多时间等候,对研发流程影响较大(次要是我忍不了)。因此需求对构建速度进行优化。
    优化思绪剖析
    要优化名目的构建速度,得先理解构建流程:
    开发人员推送代码到Gitlab,触发Gitlab办事器的Push EventsPush Events被触发后,会调用提前配置好的Jenkins webhooksJenkins webhooks被调用后,会履行对应名目的构建工作构建工作开始后先拉取名目源码到构建机,再使用docker build构建镜像docker构建镜像分为两个阶段,先使用npm scripts构建前端名目,而后把构建产物拷贝到nginx根底镜像在这个流程中,能够优化的环节只要构建docker镜像这一步,其余环节的耗时根本能够疏忽不计。而在不大改名目的状况下能起到显著提速成果的计划是:缓存战略。构建docker镜像时能够用到的缓存包罗两类:docker层缓存和运用层缓存。
    docker层缓存是指docker build所发生的可重用镜像层,只有Dockerfile中的命令及相干的源文件未改动,就可以间接使用这些镜像缓存。这类缓存战略在代码不改动的状况下成果很好,构建耗时乃至能够管制在 10 秒内。而关于日常开发状况下,代码频繁变动,假如运用自身构建时间又很长,则需求使用运用层缓存。(docker 层缓存相干引见,也能够看看民间文档[1]、中文文档[2],本文再也不赘述)
    运用层缓存是指运用构建所发生的两头产物,这些两头产物次要是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,构建次要依托[email protected],底层实际调用的是[email protected],运用构建缓存次要来自webpack。webpack需求手工开启缓存功用(民间文档传送门[3]),配置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配置[4]中开启了babel-loader和eslint-webpack-plugin的缓存功用,此外terser-webpack-plugin配置[5]也默许开启了缓存功用。从缓存目录node_modules/.cache中也能看到它们的缓存文件。


    所以,这一步其实啥也不必做,假如想进一步提速能够降级到webpack@5。
    耐久化 node_modules目录
    想在docker build环境中耐久化node_modules需求使用到BuildKit的mount功用,该功用有几个前置前提:
    docker版本必需高于 18.09BuildKit需求 手工启用 [6],可在docker build命令前添加环境变量DOCKER_BUILDKIT=1启用假如前两个前提不知足,则需求具备Jenkins和构建机的读写权限,以调剂构建环境参数修正Dockerfile,使用RUN --mount=type=cache运转npm installnpm run build指令(--mount=type=cache阐明文档 传送门 [7])开启BuildKit还有其余特性[8],好比输入日志更敌对,根本每一个步都会输入耗时,就这一条,值了!实际操作分为 2 步
    1、修正Jenkins配置,在docker build命令前加之环境变量。修正后镜像构建命令长这样:
    DOCKER_BUILDKIT=1 docker build .
    2、修正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=http://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行代码,改变很少但成果很不错。


    参考材料 [1]
    民间文档: http://docs.docker.com/develop/develop-images/dockerfile_best-practices/#leverage-build-cache
    [2]
    中文文档: http://vuepress.mirror.docker-practice.com/appendix/best_practices/#%E6%9E%84%E5%BB%BA%E7%BC%93%E5%AD%98
    [3]
    传送门: http://v4.webpack.js.org/configuration/other-options/#cache
    配置: http://github.com/facebook/create-react-app/blob/v4.0.3/packages/react-scripts/config/webpack.config.js#L459
    [5]
    配置: http://github.com/webpack-contrib/terser-webpack-plugin/tree/v4.2.3#cache
    [6]
    手工启用: http://docs.docker.com/develop/develop-images/build_enhancements/#to-enable-buildkit-builds
    [7]
    传送门: http://vuepress.mirror.docker-practice.com/buildx/buildkit/#run-mount-type-cache
    [8]
    其余特性: http://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-co妹妹and-line-build-output
    - EOF -

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    返回列表 本版积分规则

    :
    注册会员
    :
    论坛短信
    :
    未填写
    :
    未填写
    :
    未填写

    主题33

    帖子40

    积分178

    图文推荐