前端性能优化方法与实战 - 前 58 集团技术副总监 - 拉勾教育

前面我介绍了性能优化实践及在 Hybrid 下的进阶优化方案,这是我们目前的做法,那么,业界是什么样的情况呢?在这里我就挑选三家互联网公司——百度、阿里云、美团,一起来看看他们是怎么做的?

为什么选它们呢?

之所以选百度,是因为用户要快速搜索到自己想要的内容,这对性能要求非常高;阿里云呢,它的应用实时监控服务 ARMS 里,很重要的一个指标就是性能指标;美团的外卖到店,履约服务的体验和性能,对服务质量影响非常大。我从中选取他们各自重要的方面和你聊聊,希望对你有所启发。

百度

首先,我们来了解下手百前端团队(百度 App 前端团队或手机百度前端团队的简称)。他们的性能优化整体思路是怎么样的呢?

手百前端团队一般先是根据 QA 的专项测试和用户反馈去发现问题(如落地页首屏加载慢),然后定义性能指标,客户端和前端将指标上报,接着使用天幕平台监控预警,分析代码寻求优化解决方案,完成后实施评估。

他们的性能指标主要以FCP、FMP 和卡顿率为主。

其中,FCP 是指 First Contentful Paint, 表示浏览器内核首次绘制来自 DOM 的内容(如文本图片),其意义近似于白屏时间,不过是偏向内容出现的时间,而白屏时间是偏向等待的时间。FCP 的侧重点在于第一个字符开始绘制的时刻。

卡顿率则是指请求中出现卡顿问题的占比。FMP 的定义和我们一样,我就不多解释了。

指标上报过程中, NA(Native App)和 H5 都通过各自的埋点 SDK 进行上报,天幕平台根据上报的数据指标,给出平均值、80 分位值等,绘制性能报表。

然后是分析性能报表,他们找到指标不合理的地方,复现问题,进行优化。优化完成后,通过 AB 测试得出性能指标提升,评估体验提升。这样通过长期优化,渐渐达成秒开目标。

由于百度搜索前端团队的优化更多借助 NA 能力,对我们借鉴意义很大,在这里我就重点介绍一下。通过数据分析,手百前端团队性能问题主要集中在以下方面:

  1. WebView 初始化耗时 500ms;
  2. Hybrid 初始化大概 100ms,更多是指调起 App 时,Native 对协议中传入参数的解析及对模板头部和 body 的解析;
  3. 正文加载和渲染;

所以优化的思路大致是看WebView 初始化是否可以优化、串行逻辑是否可以并行、渲染速度是否可以提升。落地方案就是借助CloudHybridWebView 预创建

具体来说,借助 CloudHybrid 方案,采用 SSR + 预加载 + 拦截请求的方式,可以简化页面渲染流程,提前化和并行化网络请求逻辑,进而提升 H5 首屏速度。而 WebView 预创建,就是为了减少 WebView 创建期间的耗时,我们在适当时机提前创建好它,放入缓存池,当页面需要展示内容时,从缓存池取出即可。

手百团队用了很多 Native 的能力,比如首屏统计、卡顿率统计等。好处显而易见,手百客户端内的 H5 页面不需要进行开发就可以全面接入覆盖;缺点是方案依托 NA,升级时需要客户端来发版,另外如果要分享到端外,由于需要 H5 形式承接,指标采集和优化就必须有一套对应的解决方案。

对此,他们依托于 San 技术栈来完成(类似 Vue 和 React 的 MVVM 框架),在 San 框架内部,采集性能指标,对 SSR 方案进行定制化优化。

阿里云

阿里前端技术团队尤其是淘系,因为业务场景复杂,在性能方面有很深的造诣,秒开率指标就是这个团队最先提出的。

他们的整体性能优化思路及常规方案与百度非常类似,都是通过设定性能指标,搭建性能平台,针对监控平台上的数据诊断发现问题,优化完成后看业务数据变化。

由于阿里云的性能监控方案在体验指标方面非常有特色,业界很多业务都开始上云服务,所以这里我重点介绍一下阿里云的 ARMS 性能监控方案,另外再聊聊双十一场景下的优化。

那什么是 ARMS 性能监控方案?它是一种通过页面打开速度对 Web 场景进行监控,以此来提升站点性能体验的方案。很多阿里系业务都在使用这个方案对性能进行优化。

这个方案用的是什么性能指标呢?

ARMS 性能监控方案定义了一个性能指数Apdex,用来表示性能体验等级标准,其计算公式为Apdex=(满意数 + 可容忍数 / 2)/ 总样本量。Apdex 使用白屏时间作为计算指标,也就是 T,默认取 2s。公式中满意数为 0~T,可容忍数为 T~4T,不满意为大于 4T。

这是一个总体的指标,除此之外,还有首屏时间、秒开率、白屏时间、可交互时间、domReady 时间、Load 时间等指标。除首屏时间和秒开率之外,都是通过根据 W3C 规范中定义的 Navigation Timing API 计算出来的。

由于首屏时间非常重要,我在这里就着重说一下在 ARMS 性能监控方案里,它的计算过程。

首先是通过 mutationObserver 监听页面元素的变化,然后遍历每次新增的元素,计算元素得分总和,如果元素可见得分为 1,反之得分为 0。

遍历过程采用的是深度优先遍历算法。如果子元素可见,则父元素可见,不用计算;如果最后一个元素可见,则之前兄弟元素可见,通过减少这些计算过程,来提升采集脚本的性能。

这是具体的实现方案,业务侧怎么接入使用呢?非常简单,ARMS 性能监控方案支持 CDN 接入、NPM 包接入两种方式。

CDN 接入,代码示例如下所示。

  1. uid: "xxx"
  2. <script>
  3. !(function(c,b,d,a){c[a]||(c[a]={});c[a].config={pid:"xxx",appType:undefined,imgUrl:"https://arms-retcode.aliyuncs.com/r.png?", uid: "xxxx"};
  4. with(b)with(body)with(insertBefore(createElement("script"),firstChild))setAttribute("crossorigin","",src=d)
  5. })(window,document,"https://retcode.alicdn.com/retcode/bl.js","__bl");
  6. </script>

这里面主要是设置 uid 来区分不同的业务名称,然后将请求统一发送到服务端的地址 https://arms-retcode.aliyuncs.com/r.png? 。接着向括号中的地址请求采集脚本(https://retcode.alicdn.com/retcode/bl.js),并设置该请求支持 crossorigin 跨域。这样如果加载过程中报错,可以通过阿里云的异常监控捕获到。
使用 npm 包接入只需执行以下命令即可:

  1. npm install alife-logger --save

以上是有关 ARMS 性能监控方案的介绍,接下来我结合双十一会场项目,和你介绍下阿里云是如何进行性能优化的。

一般双十一会场项目的性能问题,主要集中在以下几个方面:

  1. 复杂网络环境下的问题,尤其是低端 Android 机环境下的问题;
  2. 拉新活动时,外部 H5(如投放在知乎、新浪微博的广告)调起淘宝 App 时需要初始化一些组件,从而导致页面体验相对于端内 H5 差的问题;
  3. 会场营销活动页面,因为二次访问率低,缓存数据过期导致的重复渲染和页面元素跳动问题。

针对上述问题,具体的优化方案,阿里主要利用数据预加载、缓存和 SSR 方案来解决。

其中阿里的 SSR 方案较之于常规,具有低风险、低成本的特点。具体来说,阿里的 SSR 提供平滑的自动切换方案,在遇到问题时可以切换到 CSR 来实现低风险;通过提供统一的 Fass 服务,将前端、客户端和服务端能力结合在一起,可以方便低成本接入。

它是怎么做到的呢?

当页面需要 CSR 渲染时, 前端应用通过数据中的模块列表来加载模块并渲染,当页面需要 SSR 渲染时,前端应用使用 SSR 返回的 HTML 塞入 root container 中,然后根据模块列表加载模块最终的 Hydrate(注水,形象化描述将字符串数据变为可用的组件的过程)。这就是自动切换方案。

而统一的 Fass 服务是指 SSR 渲染后台服务,独立出的一个数据服务,在文档服务返回内容保持静态化不变的同时,根据页面提供的模块列表和模块所需数据,将内容动态加载并渲染成 HTML。

通过该方案,阿里可以将秒开率提高了一个新高度——82.6%,并且在业务指标方面(如 UV 点击率)也有不小的提升,最高达 5%。

阿里云因为要为海量用户提供服务,属于 B 端产品,所以相关的性能统计方案很统一,实现起来简明扼要。双十一会场的优化,用的都是进阶的一些手段,因为业务体量大,一点体验上的改进,会带来业务收入上的较大收益。

美团

美团在前端性能优化方面,会对首屏时间、白屏时间、页面加载完成时间,以及流畅度进行检测,进而对白屏时间过长,首屏加载慢和交互体验不一致进行优化。性能平台上,他们也会给出一些分位值,如 TP50、TP90 和 TP99,对秒开率进行统计。

美团一般采用的是 Hybrid 开发模式,在这个模式下,美团大前端团队通过EnhanceHybrid(增强混合方案)方案、SSR 和离线化技术来进行性能优化。其中 EnhanceHybrid 是一大亮点,且对首屏时间贡献最大,具有零白屏时间的称号,我重点介绍一下它。

这是一个什么方案呢?

EnhanceHybrid 是一个视图切换的预加载方案。主要参考了苹果手机里的视图切换逻辑。当用户点击 A 的按钮进入 B 动作时,只有当 B 的动作完成之后,系统才会让 A 切换到 B,这样有效降低了白屏时间。就像你点击手机的设置按钮,当这个动作完成后,才会出现设置页面。

这个方案重点解决了三个问题:

  1. 无法在跳转 B 之前完成 B 的加载和渲染;
  2. 无法获取 B 的渲染进度;
  3. A 等待时间长。

它是这么解决的呢?

当用户触发 A 视图到 B 视图的跳转操作后,系统会隐藏式地开启一个新的 Webview 网页视图,并展示加载等待动画,此时会展示 B 的加载和渲染进度(这个进度只能是模拟的估计)。当 B 视图加载完成,首屏内容渲染完成后,客户端通知网页视图,进行 A 视图的展示。此过程中 A 等待时间长的问题,可以通过离线化来解决。

这个方案的一个好处是,直接可以接入使用,不需要业务前端做什么。

小结

好了,以上就是百度、阿里云、美团的性能优化方案,这里我们做一个对比。

性能优化本质还是为了解决业务的问题,手百属于超级 App,解决了它的性能问题,就解决了大多数场景下的性能问题,所以借助 Native 能力做重性能方案是值得的。

阿里云提供的服务旨在标准化,不能有太多个性化的统计方案,同时淘宝、天猫双十一会场遇到问题复杂度很高,我们场景的性能问题,他们都经历过。所以在性能指标采集和 SSR 方案实现方面要前沿一些。

美团立足 Hybrid 做了 EnhanceHybrid 方案,低成本、务实地解决了性能问题,挺符合这个公司的文化的。

下面给你留一个问题:

当下 RN 或者 Flutter 技术很火,为什么不直接用它们,而选择 EnhanceHybrid 方案呢?

欢迎在评论区和我沟通,下一讲,我将介绍 RN、Flutter、小程序这方面的性能演进。