乐趣区

关于前端:Flare-制作记录应用前后端性能优化

两周前,在给颜值在线的 flame 提交了几个 PR 之后,我将它封装成了容器,用于书签和在线利用的治理。

然而在迁徙集体书签的过程中,我察觉 flame 在性能上的体现并不是特地好,于是我做了一个改良版:flare

写在后面

在聊 flare 之前,我想先聊聊 flame。

flame 是一个颜值在线的导航页我的项目,你能够将你罕用的书签和在线利用存储在它下面。它由一个波兰小哥创立,我的项目地址是 https://github.com/pawelmalak/flame

在试用之后,我感觉我的项目还不错,于是稍作调整,封装了一个新的镜像:https://github.com/soulteary/docker-flame

在我的项目文档中,记录了我的批改:

  • 简化程序性能和依赖(如 K8S),缩小软件包体积,重构了一些细节逻辑,简化利用启动流程。
  • 重写了天气获取逻辑,应用城市名称替换经纬度来获取天气数据。
  • 对程序已有的一些小 BUG 进行了修复,反对中文搜索。
  • 对程序进行了简略的汉化。

然而随着深刻应用,我发现页面有着比拟大的性能问题。

因为波兰小哥采纳了 SPA 计划,我的项目内又蕴含了 6700 多个 SVG 图标、以及若干网页字体,并且在接口上有一些小问题,导致了页面体积十分大,接口申请数量也十分多。

甚至当你上传一些蕴含元素比拟多的 SVG 作为你书签图标的时候,由 React 触发的页面渲染会造成浏览器卡死。

我大略有几百个书签须要解决,预估将来书签数量还会增长,所以我应用程序批量创立了靠近一千个书签。而后我发现渲染如此多的书签,页面会呈现卡顿,甚至在页面内搜寻蕴含关键词的书签也会感触到显著的掉帧。

所以,我决定从新写一个轻量一些的程序,来解决我的需要。新的我的项目地址在这里,如果你好奇的话,能够试试看:https://github.com/soulteary/docker-flare

制作 flare 的过程,其实也是 flame 性能调优的过程。不过在解决问题之前,咱们首先得能定位问题有哪些。

利用性能问题剖析

对于这个利用的性能优化,其实并不简单,和传统利用优化差异不大:优先缩小计算量,在切实缩小不了的状况下应用计算效率更高的形式来解决问题。

不过联合应用场景来说,在剖析技术问题之前,能够先从性能动手。

对于我不实用的性能

首先从性能上看,我不须要这个利用与 Docker 集成,提供“服务发现”性能。比方在我启动容器后,这个利用会主动将新启动的容器作为书签或者利用进行增加。

其次,在领有本人的 SSO 服务之后,我也不再须要应用简略的账号密码登录之类的性能,所以这个性能也能够去掉。

最初,对于书签数据的存储,我感觉在短少用户体验十分棒的 Web 编辑器的前提下,可能不如配置申明的形式更易于治理和保护。(你能够应用任何你喜爱的编辑器来更新和保护内容,你能够应用 Git 或者任何你喜爱的形式,以白盒模式保留你本人的数据)。

基于下面的变动,我大略能够少写几个局部的代码:容器(Docker & K8S)集成、登录鉴权、利用和书签,以及书签分类的“CRUD”。

前端架构中的问题

Flame 我的项目中,作者应用都是 create-react-app 脚手架创立的我的项目,我的项目依赖为:React v17 + TypeScript + Redux,为了提供简洁统一的图标,作者在前端引入了 Templarian/MaterialDesign-JS,一个被精心解决过的 DOM 构造非常简单的 SVG 图标库。

在应用构建工具打包、服务端 GZip 压缩之后,须要传输靠近 1MB 的资源,原始脚本程序体积靠近 3MB。绝对膨大的程序体积导致了页面加载和执行工夫都会比拟长。比方页面页面首次渲染工夫在 1s 高低浮动,少数状况下会超过 1s,实现工夫个别都在 1.5s 以上。可能是作者对于服务端程序开发不够相熟,尽管在前端进行利用配置更新时会复用接口,然而在内容页面展现时,会调用多达 8 个接口。此外,为了在页面中展现和更新天气信息,波兰小哥还应用了 WebSocket 来进行数据交互。

其余的问题,在文章后面曾经提到过了,就不赘述了。

后端架构中的问题

我的项目应用的技术栈为 Node.js,Web 框架为市占率十分高的 Express 的最新版本,ORM 框架抉择的则是 Sequelize,数据存储落地为 SQLite3。下面的抉择粗看问题不大,如果利用不须要公开提供浏览拜访,应该不会呈现任何性能问题。

然而,如果咱们仔细观察服务响应,会发现有一些申请的响应的工夫十分长,比方页面资源、比方对于页面至关重要的 JS 程序资源,它们的获取都耗费了靠近 400ms。

此外,前端发动了屡次申请来获取数据,联合数据存储应用 SQLite,如果提供公开内容拜访,很容易遇到性能瓶颈。

针对利用进行改良

当咱们分明理解到下面的问题之后,比方容易采取的计划是:基于原程序进行重构调整,简化前端申请、正当拆分模块、解决资源加载和执行机会,调整数据存储和解决形式,进步服务端响应能力等组合拳。然而,这会是最简略和收益最高的计划嘛

调整前端实现

如果说在须要交互的页面程序中应用 MVVM 框架会有较高的收益和性价比,那么在短少多端组件代码复用、没有服务端渲染需要的场景下,应用这类框架则是一个性价比不高的抉择。

或者有同学会问,如果不应用 React、Vue、Angular 这类框架,难道在 2022 年还要再拾起 jQuery 等老的工具吗?尽管能够,但其实在近乎于纯展现的场景下,咱们能够脱离 JS 来实现业务性能和简略的交互,比方主动获取焦点、菜单按钮的激活状态变动、甚至是带有动画成果的天气图标。

所以,在调整实现的时候,其实还有一个抉择:不应用任何脚本

在实现程序之后,咱们能够看到从服务器获取整个页面数据、构造解析、款式计算、元素布局、页面绘制的残缺工夫在 33ms(蕴含了 idle 等待时间),其中要害流程的工夫耗费加起来不到 10ms,而实现页面渲染的工夫更是缩短到了 1.65ms。

在失去了页面疾速渲染能力之后,即便不应用浏览器针对资源进行缓存,减速渲染,咱们也可能做到页面切换的“无刷新”浏览(因为渲染速度足够快)。

调整后端实现

尽管我十分喜爱应用 Node.js,以往也分享过不少基于 Node.js 编写的程序或者优化实际,然而,为了可能低成本进步高性能的资源响应,这里进行技术栈切换是必要的:比方 Golang。

在应用 Golang 简化程序性能后,程序对于每个申请的响应根本可能放弃在几毫秒的程度(受限于网络传输),相比拟之前大略降落了 2~3 个量级。页面要害的 DOM ContentLoad 工夫更是缩短到原来的八分之一。

联合下面的前端优化提到的渲染工夫来粗略预计,从资源下载到渲染加起来都不到 10ms,如果不是浏览器的一些限度,绘制帧率应该可能远超 60 帧,进一步满足咱们实现“即便刷新了也比没一些没刷新的实现还顺滑”。

下面的实现中,我将页面图标申请和页面文档进行了拆分,在书签数量和图标品种不多的场景下,或者并不是最优的计划,然而一旦书签数量级到几百、上千之后,你会发现图标拆分能够极大地晋升性能。

当然,为了满足数量比拟少的场景,我也对合并输入进行了实现,算上网站 favicon 获取,一共只有两个申请。在书签不是很多的时候,渲染性能甚至比文档和资源拆分输入效率更好。

图标资源优化

Flame 应用的计划是读取后端接口配置,从前端脚本中动态创建 SVG 图标并插入文档中,Flare 程序默认的形式则是将 SVG 和文档拆分,以应答大量书签情况下的页面性能问题。

尽管解决了页面性能问题,然而服务端 IO 问题却会随同而来,所以这里还须要解决资源在服务端的开释和读取问题,尽量将资源的磁盘 IO 变为零。

听起来比拟玄乎,但其实联合代码生成的形式,还是蛮好实现的。当然,因为 Go 存在主动 GC,所以在不同的资源被应用的时候,会呈现大量内存的调配,影响效率,这里能够思考应用长久化计划来解决问题,解决起来挺有意思的,受限于篇幅和主题就不开展啦。有一部分我在前两篇文章中提到了,对于 Golang 嵌入资源的应用和优化。

比方,在不针对 HTTP 服务实现做任何优化、限度运行资源为两外围的前提下,仅优化资源 IO 后,能达到稳固 3ms 输入资源,每秒提供 2 万 7 千次以上的响应服务。

容器镜像的优化

除了惯例优化之外,容器时代的利用,镜像优化也是十分要害的。容器优化形式,我在后面的文章重复提过屡次,所以也不再开展了,感兴趣能够自行翻阅之前的内容。

# docker images | grep fla                 
soulteary/flare       0.1.1      22b18ad73c66        12MB
soulteary/flaume      2.2.0      b39fffc0ca81        152MB
pawelmalak/flame      2.2.0      fa47c93c0af6        179MB
pawelmalak/flame      2.0.0      729b0fcea7f0        190MB

能够看到,相比拟原版程序,优化后的程序在本地解压后的尺寸大略是之前十五到十六分之一。

额定的优化

如果咱们应用 lighthouse 针对 Flame 前端实现进行测试,可能看到前端程序在实现上的一些小问题,得分尽管四个环绿三个,然而只有一个环是绿色的。

在从新实现的过程中,除了简化构造,调试实现之外,还棘手将这四个圈都打到了满分(Chrome 版本 v97+)。

最初

聊到这里,置信你曾经理解了我是怎么做的啦,如果你对 Flare 感兴趣,并且也须要一个简略的导航程序,能够拜访我的项目 https://github.com/soulteary/docker-flare,来亲自上手试试。

–EOF


咱们有一个小小的折腾群,外面汇集了几百位喜爱折腾的小伙伴。

在不发广告的状况下,咱们在外面会一起聊聊软硬件、HomeLab、编程上的一些问题,也会在群里不定期的分享一些技术沙龙的材料。

喜爱折腾的小伙伴欢送扫码增加好友。(增加好友,请备注实名,注明起源和目标,否则不会通过审核)

对于折腾群入群的那些事


如果你感觉内容还算实用,欢送点赞分享给你的敌人,在此谢过。

如果你想更快的看到后续内容的更新,请不吝“点赞”或“转发分享”,这些收费的激励将会影响后续无关内容的更新速度。


本文应用「署名 4.0 国内 (CC BY 4.0)」许可协定,欢送转载、或从新批改应用,但须要注明起源。署名 4.0 国内 (CC BY 4.0)

本文作者: 苏洋

创立工夫: 2022 年 01 月 19 日
统计字数: 5054 字
浏览工夫: 11 分钟浏览
本文链接: https://soulteary.com/2022/01…

退出移动版