本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com
大厂技术 高级前端 Node 进阶
点击上方 程序员成长指北,关注公众号
回复 1,加入高级 Node 交流群
前言
大家好,我是考拉🐨,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。
作者:苏州意大利炮
链接:https://juejin.cn/post/7233046023243907128
来源:稀土掘金
背景
去年 7 月入职了现在的公司。记录一下在公司做的前端代码优化,如果你也遇到了同样的问题,希望可以帮助到你, 或者可以在评论区进行交流。
搭建私服
背景
我入职公司的时候后端已经有了私服,前端是没有私服.
前端有一个业务组件库,将使用频率高的组件写到了一个 gitLab 的仓库中,当需要有新功能或者 bug 修复,需要先 build 后再拖动到项目中
存在的问题
引入麻烦。当组件库有更新时只能在本地构建后才可以放入到依赖的包里
没有版本的概念。只能用最新的代码,如果出现破坏性的更改,那后果将不堪设想
改进
搭建私服。可以看我的另外一个文章 前端私服 verdaccio 的介绍和用法 [1]
构建工具(webpack)优化
背景
刚来公司的时候,询问老员工,前端项目怎么启动(自己进行了 install 后,npm run serve)后启动了,但是调用接口不成功
老员工发给了我一个 nginx 的安装包
image.png
这是要干啥,我去当面沟通了一下,原来是启动项目的时候本地需要启动一个 nginx,用做接口转发
当时我内心是想着这个公司用了什么高级功能,webpack 的 devserver 有啥转发实现不了吗?算了先跑起来后面在问。
后期看了下 nginx 的配置,只是把所有的接口进行了转发,后加了一个 devserver 进行了解决。
解决后别的前端开发也说了,早知道这么简单早就弄了。。。
image.png
启动时间优化
背景
一个前端项目迭代了 3 年多(里面的一些功能也外包了出去,代码是又乱又多),非常庞大,可以说是巨石项目,启动时间达到了 120 秒左右(还是在 node_modules 里有 cache 的场景,非第一次启动),用公司配置的 window 电脑的话需要 5min
再测试一次
image.png
直接看优化后的效果图片
对你没看错,比优化前多了 50 秒,你可能有这个疑问(我知道你很急,但是你别急,请继续向下看)
第二次启动
第三次启动
原理
HardSourceWebpackPlugin 是 webpack 的插件,为模块提供中间缓存步骤,通俗一点为缓存了一些文件到你的 node_modules。
缓存的目录是node_modules/.cache/hard-source。
在解决的过程也尝试了很多 webpack 的插件 (多线程打包、happyPack 等效果都不明显),目前测试下来只有这个 hard-source-webpack-plugin[2] 作用最大
HardSourceWebpackPlugin 文档中 [3] 列出了一些你可能会遇到的问题以及如何解决,例如热更新失效,或者某些配置不生效等。
使用方法
- 安装依赖
复制代码
npm install hard-source-webpack-plugin -D- 修改
webpack的配置:
ini复制代码//webpack.config.jsvar HardSourceWebpackPlugin = require('hard-source-webpack-plugin');module.exports = { //... plugins: [ new HardSourceWebpackPlugin() ]}打包时间优化
背景
还是上面的巨石项目,启动时间大概在 2min(公司发的台式机是 5min),项目用的是 vuecli,打包时间竟然在 20 多分钟,并且 jekins 经常会构建失败,打包命令还需加上最大的内存的限制。
css
复制代码
node --max_old_space_size=8192 node_modules/@vue/cli-service/bin/vue-cli-service.js build我问了同事这个项目怎么构建这么久,你们平常上线的话是怎么来操作的?
我同事也很真诚的回答了我: 我们会几个人同时打包前端,然后开把王者荣耀,看谁打包的快,就用谁电脑上打的包。。。
这样的话还存在一个问题,假如有个人电脑的 nodejs 版本不同,或者某个人忘记拉取了最新的代码,会造成发布发布失败,跟个人的关联关系太大了,我们应该更加相信机器,使用 jekins 打包
结果
打包时间从 20 多 min 优化到 5min。
优化方案
加了一个配置项,css 不单独提取出去
image.png
解决过程
虽然相对于之前只加了一行代码,但是为了找出真正的原因花费了大半天的时间。
先找出插件和 loader 的耗时,查看耗时在哪里
speed-measure-webpack-plugin插件可以测量各个插件和loader所花费的时间。使用方法 传送门 [4]
测试后并没有发现有用的数据
思考问什么开发环境启动时 5min,打包怎么就成了 20 多 min。(想想打包的时候默认的 sourceMap 和 eslint 都是没开启的,按照道理来说应该是更快的。怎么反而更慢),
项目使用的是 vuecli(3.5.3),是不是 vuecli 对 webpack 里的默认值做了一些更改,然后对照着配置一个一个找,查看哪些是生产开启,开发没开启的
找了半天没发现可以的对象,一度想把 vuecli 升级到 5,但是担心一系列的组件依赖都要升级,项目的稳定性不够好,还是继续寻找。
终于找到了怀疑的对象,测试后发现构建的时间确实会缩短
image.png
猜想,项目是巨石应用,里面的代码太多了,所以在拆分 css 形成单独的文件的时候消耗太久了,开发环境这个参数默认是关闭的,所以启动时间在 5min,打包的时候这个参数开启,造成了大量的文件写入,所以慢。
代码优化
图标库的优化 [5]
下载体验优化
背景
项目中有一个功能是学习课程的,需要有一个下载的功能,现在的流程是后端返回是一个文件流形式,前端将文件流转成链接,然后下载。
600M 视频,需要 1-2min 左右的加载时间,目前是在下载的时候添加了 loading,造成用户在这 2min 不能操作,很影响用户体验
Q:为什么不能直接使用window.location.href?
A:视频的课程存储的是ID,后端单独有一个服务是文件服务,需要网关的鉴权,目前的鉴权是放在request的header中。
目标
期望可以跟在软件的官网上下载文件一样,调用浏览器的默认下载,如下图,不会影响用户的操作。
image.png
解决
查看一些资料后 location.href 或者 window.open 可以实现这种效果,但是 token 怎么来解决。
想到了把 token 可以存在cookie中,当用户发起请求的时候回默认带上,后端可以将下载的接口就行扩展,支持从 cookie 中获取。
jekins 优化
优化前
image.png
优化后
image.png
背景
组内人员反应 jekins 的前端项目每次打包的时候,nodejs 把服务器的内存占满了,导致打包排队,看是否能降低内存
每次都要进行 install,能否跟本地一样,只更新新装的包
还有一个很大的原因打包脚本是后端帮忙写的,后端不懂前端的打包,前端不懂打包脚本,造成了中间信息的断层
改进
我自己也不懂 jekins 啊,只能自己去学习,上家公司是有专业的运维团队在管理,有点尴尬
查看官方文档和打包的脚本再加上自己的脸皮厚,一直再问后端,慢慢理解。找到了原因每次打包都要进行 deleteDir() 查看官方的解释清空工作空间,猜测是不是这个导致的
image.png
将这个脚本删除后,发现每次都很快。每次将工作空间清除后,当再次执行脚本的时候,都要从 0 开始 install,导致了磁盘的读写,这样解决了占用 cpu 和每次从零安装的
这个时候要考虑两个场景
当
引入了新的依赖后,是否会安装成功当
依赖进行了升级,是否可以升级成功
测试下来没发现什么问题
打包流水线优化
之前是将 npm install 和 npm run build 统一放在了流水线 Protal Npm Build。不方便统计是安装包慢还是 npm run build 慢。
改进
将 npm install 和 npm run build 分开,同时将. npmrc(.npmrc 里指定仓库为私服仓库)提交到仓库(这样 install 的时候会优先从私服安装)
打包产物可以下载
组内的成员想在发布生产的时候,直接从测试环境下载压缩包更新到生产环境
查看官方文档 [6], 在 success 的时候将压缩包上传到服务器
yaml复制代码archiveArtifacts artifacts: 'dist/*.tar.gz', fingerprint: true结语
Node 社群
我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。
“分享、点赞、在看” 支持一下