YSS

Write Less & Do More

RN 性能优化总体指导

前言

为什么要写这篇文章呢?

一个是记录后面我们怎么去优化。

另外一个点就是总结一些经验,指导后面的优化方向。

存在的情况

我们在面对性能优化的时候,有的时候可能不知道如何着手,有各种各样的原因,但最重要的一个问题是没有一个方向,想到什么有问题,觉得什么有问题,就一股脑的去做。

这样下来,看似做了很多事情,一通优化下来,也确实是有提高了,但是,别人再问你后面应该如何优化,应该怎么去做。

你会发现你还是一片茫然。

总体指导思想

我们在面对着这一系列问题的时候,其实最缺乏的是一个总体指导思想。

那什么是一个总体指导思想呢?

总体指导思想是一个整体解决问题的方式方法的总结。

更多的是通过过往的经验和教训得到的。

而在这里所要阐述的,更多的是我个人的经验和教训下,在遇到性能优化,应该如何去做的。

解决

第一步,梳理现状

在做性能优化的第一步,不是一股脑的直接按照现有的优化规则去做,也不是去直接找其他人或其他团队去问是否有遇到同样的问题。

更多的是要去理清我们项目的实际情况。从我们自身项目实际情况出发,找到我们自身的问题所在,特别是问题的大头在哪里。

比如网络上很多的前端优化的 xx 条军规。他们确实总结得非常的好,也非常实用。但是不同的项目,不同的团队下都有非常大的业务差异。直接拿过来用,不是不行,只是很可能解决不了实际问题。

反面例子

我在面试的时候,经常会让候选人说一个自己解决的性能优化问题。有一次就说到 SSR 的优化,比如一些弹窗,登录组件等等不涉及 SEO 的组件设置为不需要 SEO,也不需要直接呈现的都设置为非服务端渲染。

我觉得这个做法非常好,也非常的认同,但是当我问及这个优化的实际效果呢?

他回答不出来,一个是他没有实际的数据,另外一个就是他的优化方向本身就是错的。

你在 Node.js 服务端本身已经有缓存了,上面的这些优化只是优化了第一次的执行速度。但对整个服务来说,后面 N 多个请求都是拿的缓存,那这个优化又有什么意义呢?

如何做

那我们具体应该如何去梳理现状呢?

总共三个点:

  1. 核心指标
  2. 执行链路
  3. 性能埋点

rn-opt-1

第一个点:核心指标

核心指标就是要明确做这个优化,我们最最核心要关注的点,也是我们所有优化效果的最终衡量指标。

这个核心指标需要根据我们自己实际的业务,实际的项目和团队去共同制定并确认。

确定了这个核心指标,就好比有了前行的目标,后面要做的事情就是围绕这个目标一步步前行。

第二个点:执行链路

执行链路指的是我们自己开发的程序是怎么一步步被执行的,更重要的是从用户角度出发,它是在哪个环节被用户使用到的。

一个是程序执行:这个就是我们代码是怎么运行。

第二个是用户使用我们产品的行为都有哪些,对应的是否会直接影响到我们的程序执行。

有了这些才能更好的指导后面的性能埋点应该如何去做。

第三个点:性能埋点

性能埋点就是最终践行我们核心指标的一个个点。

一个核心指标是一个点,但同时一个核心指标可以是很多个小埋点组成。

我们通过执行链路,把一个核心指标划分成很多个阶段,每个阶段都做一个埋点。

以此能分析出各个阶段的指标数据,既而知道后续的优化方向。

比如,我们 RN 项目的冷启动时间,可以拆分成:

  1. 引擎加载完 Bundle 的时间
  2. Bundle 初始化的时间
  3. 第一个页面网络数据请求时间
  4. 页面渲染时间
  5. 播放器播放加载时间

通过这些数据,我们就能非常直观明了的知道我们的性能问题所在了。

接下来要做的就是如何去优化了。

第二步,逐个逐步优化

逐个逐步优化的核心就是我们每次都聚焦在一个点上,然后去通过优化这个点去达到我们的一个小目标。

之后再重新走一遍这个流程,直到优化到我们认可的一个效果,或者没法再进一步优化为止。

rn-opt-2

性能点分析

这一阶段就是拿到我们的埋点数据,一个点一个点的数据去看。

结合各个维度去核实这些数据是不是有优化空间。

同时,还需要分析各个点的耗时情况,针对耗时特别大的,可以再看看这个点是不是可以再细化到更小的点。

特别注意的是,

这里面可能还有一些技术性的指标,不能在这些埋点数据体现的话,就需要回归第一步去定义这些技术性指标,并且是一个可量化的技术性指标。

优化点明确

这一阶段是明确我们接下来要优化的目标。

期间,我们可能会有很多需要优化的地方,但我们需要更聚焦于一个更具体的点,更能体现效果的点。

首先,明确的标准应该是我们当前遇到的最急迫,以及最需要去优化的点。

再则,是数值比较大的点。

最后,还有优化空间的点。

然后详细了解现在这个需要优化的点具体都做了哪些事情。

问题分析及调研

这一阶段主要是梳理现状,去分析现状,既而去发现问题。

然后,从这个问题着手去看看我们内外部有没有其他人针对类似问题的解决方案。

看看其他人是怎么做的,是不是可以给到我们一些参考。

方案设计及实施

这个阶段就是跟进内外部方案,以及我们的实际情况,给出我们认可的一个详细方案设计并实施上线。

解决并上线核实

这个阶段就是把我们的方案实现并上线。最终还需要通过新旧对比来看看我们是不是达到了预期的效果。这个很重要。

** 最后,如果一个优化方案的结果是没有可量化的、可以对照的指标,那么这个优化是没法让人信服的,是无效的。**

第三步,持续监控

上面的第二步是针对具体问题的具体解决。

我们不能仅仅停留在只是去解决一个问题,我们还需要一种自动化的手段,帮助我们去持续监控我们优化后的效果。

我们希望这个自动化的手段做到的效果是:

  1. 至少能够做到每次上线能跑一遍
  2. 更高一点就是每个需求单独部署的时候跑一遍

通过对比来确定当前上线或者当前的需求是否影响到了我们的核心指标。最后,通过报告的形式输出出来。

第四步,竞对分析

只有和你的竞对去做比较,看看我们之间的优势在哪里,差距在哪里。

才能更明确自己下一步的目标。

这里面最重要的一个点就是指标的选择。

视频类的,可以是:首帧耗时、起播耗时、滑动耗时、黑边率、CPU&MEM 、电量。

全局的指标制定

越是看得多,越是觉得欠缺了一些重要的东西。

这里从一个特别的角度来看待性能优化。

也是之前做过一段时间的 node.js 服务端的性能优化,最终优化来优化去,所有的优化指标最终都可以归结到四个点:CPU、内存、网络、IO。

每次遇到性能瓶颈的时候最直观的表现,都能够在这个四个点体现出来。

做 Web 性能优化的时候,其实还是很少涉及运行环境层面的监控。

主要还是本身 Web 都是运行在浏览器上的,正常情况下还是很难拿到 CPU、内存、网络及 IO 数据的。

但在 RN 这层本身有一半算是 Native,还有就是这些数据是可以通过 Native 去获取到的。

如果我们把 RN 当着 Native 去看待的话,这些数据就显得很重要了。

最后

有很多时候,我们看到的问题,不一定是因为我们自己问题,也可能是流程上的问题,也可能是整个技术栈的问题。

但更多的时候我们需要跳出一些固定思维。

当然,更多的时候,我们需要多看看其他人是怎么解决一个事情,这个比直接告诉你怎么去做更重要。