秒开率破90%!交易后台渲染性能优化 | 得物技术
一、前言
一直以来,体验都是得物技术部的关键词之一,对于前端开发而言,提高用户体验更是一项至关重要的工作。
本文从本次交易后台性能优化实践出发,同时介绍应用整体架构和设计,希望可以给参与网站性能建设的同学提供一定的学习和参考价值。
二、系统简介
交易后台是现有交易流程主要系统,包含商品、出价、商家、订单等二级业务域,其承载了交易的核心任务,在交易平台的整体架构中占据着非常重要的地位。
业务背景:整体日均 PV 数达到 10w+,其中 SPU 场景占比超过一半,由于页面功能结构复杂的原因,运营的使用体验和交易效率有一定程度上的影响。
技术背景:应用基于 qiankun 微前端架构,首屏加载资源过多,包括主子应用 JS 和样式文件,图片和其他静态资源,数十个子应用路由信息和数百个菜单项,以及接入的一些三方 SDK 等。
三、性能现状
先看优化前的首屏效果(没有开慢倍速):
可以从动图看出页面加载速度、白屏时间都不太理想,显然和我们的目标首屏秒开还有一段距离,为了实现首屏秒开的目标,可以先从以下几个方面进行分析。
性能看板分析
Chrome Performance 火焰图在页面性能问题分析中是一项非常重要的工具。
相关阅读:
https://juejin.cn/post/6844904074551230471
在打开看板后,先关注下这几个红色区域长任务,我们知道主线程一次只能处理一个任务,所以这会导致浏览器在主线程上阻塞一段时间,也是造成页面卡顿的主要原因。看下底部调用树的情况:
Task1:发生在 DCL 之前,因为浏览器解析 HTML 文件时,会在遇到<script>标签时立即执行脚本文件,所以 __webpack_require__ 和 Compile Code 很可能是因为入口文件过大导致。
Task2:发生在 FCP 之后,主要是源码中组件渲染相关的核心函数,componentUpdateFn 用于比较新旧 VNode 的差异,并调用 patch 函数对真实 DOM 进行更新,所以初步判断是渲染复杂组件导致。
另外可以观察以下关键性能指标,了解一下页面加载的各个阶段的耗时情况
- First Contentful Paint(FCP):首次内容绘制时间,此时页面仅展示出一些水印组件,和白屏几乎没区别,一般应该在页面加载后的 1-2s 内完成,此时用户可以感受到页面正在加载。(当前耗时2s+)
- Largest Contentful Paint(LCP):最大内容绘制时间,此时主应用框架渲染基本完成,子应用还未开始加载。通常应该在页面加载后的 2.5s 内完成,否则用户可能会感到页面加载缓慢。(当前耗时4s+)
根据这些具体的性能指标,之后才能更好的度量优化效果。
渲染流程分析
为了快速定位问题,我们按步骤拆分一下页面整体加载的渲染流程,这有助于我们做出针对性的优化。
我们重点关注几个标记的部分,接下来就可以根据实际情况逐一击破了。
四、方案拆解
根据对应用渲染流程的分析,我们可以将整体优化方案作进一步的拆解,并设置对应动作的开发优先级。
并通过二八法则,我们将主要精力重点投入到高优方案中,确保整体性能的提升。
五、具体动作
首屏资源优化
首屏资源加载会直接影响页面的渲染速度和体验,我们先查看下首屏资源的加载情况,由于各类资源请求过多,这里仅过滤来源于主应用的网络请求。
可以直接从中发现几个可优化的点:
- 入口 JS 资源文件 Size 优化
- 严重影响了页面整体加载性能,可以通过构建体积优化,主要思路就是代码分割拆包,静态资源上传 CDN,脚本代码压缩等方式处理
- 接口缓存、调用时序治理
- 针对用户信息、菜单信息等不常变动的接口可以采用相关缓存策略,减少首屏等待的时间
- 部分优先级不高的接口可以延迟调用,异步加载
// 我们采用 Cache aside 旁路缓存策略 async function cacheRequest(params: any) { const startTime = Date.now() const key = params.key const cache: any = JSON.parse(localStorage.getItem(key) || '{}') // 当天有缓存 const canCache = cache.cacheTime && moment(cache.cacheTime).isSame(moment(startTime), 'day') window.sendTrack?.({ event: 'main_request_cache', tags: { eventTitle: '主应用数据缓存', eventType: canCache ? 1 : 0, }, }) const requestCache = async () => { const data = await request(params) localStorage.setItem(key, JSON.stringify({ data, cacheTime: Date.now() })) return data } // 优先从缓存中读取数据 后续再更新缓存 保证数据的一致性 if (canCache) { setTimeout(requestCache, DELAY_CACHE_TIME * 1000) return cache.data } else { const data = await requestCache() return data } }
- 三方 SDK 集中治理
- 尽量放在 script 标签中异步加载脚本,可以加快解析时间且保证主入口文件的加载不会被阻塞
- 另外注意防止子应用重复加载,还有部分 SDK 需要及时下线
其实原则只有一个:减少首屏需要加载的资源数量和大小,并尽快加载必要的资源。
渲染优先级优化
最后为了减少 LCP 的等待时间,我们将页面左侧菜单栏做一个懒加载处理,初始化仅展示一级目录菜单,既考虑了首屏视觉效果,也间接将子应用加载的时间点提前。
相关阅读:当不希望因为不重要的任务导致用户感觉到卡顿的话,就应该考虑使用requestIdleCallback:
https://juejin.cn/post/6844903592831238157
// 采用 requestIdleCallback 方式利用 CPU 空闲时间渐进地加载内容 try { requestIdleCallback((deadline) => { // 当前帧有剩余时间 可以执行任务 while (deadline.timeRemaining() > 0 && || deadline.didTimeout) { // 加载剩余部分菜单项 } }) } catch (e) { // 低版本浏览器兜底处理 setTimeout(() => { // 加载剩余部分菜单项 }, DELAY_LOAD_TIME) } }
最后再看下优化后的首屏效果(没有开快倍速):
六、效果回收
主要性能指标
优化后各项指标数据均有一定提升,其中
秒开率(首次打开页面<1秒占比,以 FMP 为准):15%+
页面首次进入FMP90分位均值(秒):35%+
页面TTI%(可交互时长<1.5s占比) :30%+
TTI 90分位均值(秒):50%+
上述数据均来源于效率工程应用系统前端大盘看板。
优化前-7月
优化后-9月
其他相关数据统计(本机测试):页面传输资源大小减少约 1M、页面资源加载时间下降超过 0.5s、FCP、LCP 也分别优化到 1s、2s 以内 ,整体结果超出预期。
七、总结展望
随着业务复杂度提升和用户规模的增加,系统的性能和效率必然会面临更多的挑战,本轮性能优化工作基本告一段落,虽然取得了一些成绩,但还有很多事项需要后续不断的完善,比如:
- 框架层面优化。深入探究微前端框架层的性能瓶颈,降低应用间消息传递通信和模块重复资源加载损耗
- 使用 Service Worker。执行一些计算密集型或网络请求相关的任务,实现静态资源缓存优化
- 资源加载优化。利用发布平台事件同步能力实现应用配置文件按需加载,避免网络带宽造成过大的压力
希望能通过各项措施逐步形成后台应用性能优化最佳实践,从而避免各种性能卡点问题,进一步保证运营体验。
*文/ Johnny
本文属得物技术原创,更多精彩文章请看:得物技术官网
未经得物技术许可严禁转载,否则依法追究法律责任!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
基于afx透明视频的视觉增强前端方案
作者 |青玉 导读 本文介绍了增长前端团队自研的Webview框架下透明视频视觉增强方案,该方案在保证对视觉进行高度还原的同时可投入更少的开发成本,还能获得更优的前端性能表现。文章首先分析了市面上动画方案的优缺点,然后详细介绍了透明视频的整体设计、实现方法、使用流程和在运营活动中的使用案例。该方案通过在视频中添加透明通道,利用OpenGL和Canvas实现了视频动画,同时通过资源的预加载和缓存优化了加载过程,开发者还可通过叠加svg和css3等其他技术进行氛围增强。希望给到前端同学在开发动效方面一点小小启发和助力。 全文2456字,预计阅读时间7分钟。 01 背景 随着App娱乐元素的不断增加和交互的日益丰富,动画效果在用户体验中的地位越来越重要。然而,实现高质量的动画效果需要较高的开发成本,且目前尚无通用的技术方案。为了解决这一问题,降低或消除动效相关的研发成本,业界逐渐诞生了基于afx透明视频的视觉增强前端方案。 02 整体方案设计 2.1 常见动画方案及问题 为了在项目中实现动画效果,目前业界现有的方案有:帧动画、lottie、gif、video等。这些方案中帧动画占用的体积较大...
- 下一篇
从 MySQL 到 DynamoDB,Canva 如何应对每天新增的 5000 万素材
原文 From Zero to 50 Million Uploads per Day: Scaling Media at Canva 作为一款设计工具,Canva 吸引人的一个重要特色就是拥有数以亿计的照片和图形资源,支持用户上传个人素材。 Canva 于 2013 年推出,设立了一个包含大量照片和图形的资源库,并允许用户上传自己的素材以用于设计。从发布之日起,Canva 的用户群就迅速扩大:现在我们的月活用户已超过一亿,Canva 用户每天上传 5000 万个媒体素材。为了支持这种快速增长,同时让用户能够全天二十四小时使用 Canva,我们必须不断改进 Canva 的媒体存储方式。 Canva 的微服务和媒体服务 我们采用微服务架构来构建 Canva,大多数服务面向资源,管理 Canva 内部不同资源的操作,例如用户、文档、文件夹和媒体。服务提供公开的 API,具有独立的持久性,并且每个服务都由一个小型工程师团队负责。 媒体服务的简化架构概述 Canva 的媒体服务管理媒体资源的操作并封装媒体资源的状态。对于每个媒体,服务都会存储: 资源的唯一标识 ID。 它的所属用户。 是否属于 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7设置SWAP分区,小内存服务器的救世主
- Mario游戏-低调大师作品
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- 2048小游戏-低调大师作品
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库