WebView 性能分析和优化

文摘   2024-07-30 10:42   浙江  

我们的客户最近反映在使用 MicroStrategy Library 安卓应用时,尤其是在一些初端 Android 设备上,加载应用内的仪表盘(Dashboard)时等待时间过长(15s-30s)。客户所使用的 Android 设备是专为零售行业设计的,可能是考虑到能耗和稳定性,这些设备搭载的是高通骁龙660处理器,与市场上的主流 Android 设备相比性能有所差距。因此,在渲染较为复杂的 Dashboard 时,与主流设备相比,所需时间更长。


鉴于客户已经配备了大量此类设备,建议他们更换或升级设备对于客户来说并不现实。


“客户就是上帝”,为了满足客户对我们 Android 应用在这些特定设备上的性能期望,我们对 MicroStrategy Library Android 应用在这些设备上运行时的性能瓶颈进行了深入分析,并致力于解决这些问题。

1

MicroStrategy Library Android 应用架构

MicroStrategy Library Android 应用采用了混合式(Hybrid)架构,即应用中既包含原生(Native)代码部分,也融合了 WebView 组件。应用通过 WebView 组件来渲染 Dashboard,这样做可以有效复用 Library Web 端的渲染逻辑。原生代码部分主要负责应用的登录管理、首页展示、缓存管理、通知管理等 Android 系统特有的功能。



如上所述,当用户启动应用时,我们会启动一个 Native View 来负责登录和主页的展示。与此同时,在后台会启动一个全局 WebView 进行预热(prewarm)操作,并加载 Library Web 的初始界面。用户在选择并打开某个 Dashboard 时,我们会将 WebView 切换到前台显示相应的 Dashboard。用户关闭 Dashboard 后,WebView 会切回后台,为下一次打开 Dashboard 做准备。


考虑到预热 WebView 所需的时间不容忽视,为了确保性能,用户登录后这个 WebView 只会初始化一次,直至用户下次重新登录。


以上是应用的基本架构。鉴于客户主要反映 Dashboard 加载时间过长的问题,我们将重点分析 Dashboard 在整个加载过程中的各个阶段。



如上图所示,在用户登录后首次打开 Dashboard 时,预热占据了主要时间。在再次打开 Dashboard 时,主要取决于 Dashboard 数据的生成、传输以及渲染时间。为了提升性能,在打开 Dashboard 的同时,Native 端会并行地获取数据。


缩短这些过程的时间是优化 WebView 性能的关键所在。


接下来,我们将逐一分析各个阶段的耗时情况,并指出需要关注的优化点。


2

已有的优化

Javascript 下载

分析:

WebView 在加载过程中首先尝试从服务器下载资源文件。在网络条件较差的情况下,这一步骤可能会耗费较长时间。


如何优化:

为了缩短下载时间,我们采取了将资源文件直接打包进 Library Android 应用的策略。通过这种方式,我们可以将原本需要通过网络下载的时间缩短为从本地磁盘读取的时间。然而,由于 Library Android 应用需要与不同版本的 Library Web Server 进行连接,因此我们在 apk 中默认打包了一份资源文件,即最新版本的 Library Web。为了最大化性能,我们建议客户端和服务器端保持版本一致。


3

其它的优化

预热提前

分析:



WebView 的预热过程是线性的,本地 WebView 需要先等待网络请求和磁盘读写操作完成后,才能执行脚本和进行渲染。此外,整个预热过程必须在用户登录之后进行,这在 Android 低端机上尤其耗时。


如何优化:

我们之前是在用户登录之后才开始预热,主要是因为预热页面需要登录后才能获取到的信息。实际上,脚本的下载和解析可以在用户登录之前就开始,以此来加速预热过程。



另一个优化方向是尽可能保持 WebView 的上下文不变。在某些情况下,我们会主动清空 WebView,例如用户登出时,这时就需要重新预热 WebView。我们尝试延长 WebView 的生命周期,在用户登出时,我们不再重新加载和解析 JavaScript,而是仅清除与用户相关的信息。这样,在用户再次登录时,我们只需重新获取用户相关信息,从而显著提高了性能。



Javascript 加载

分析:



在 PC 上,由于 CPU 性能的不断提升,JavaScript(JS) 的解析和执行时间在整个页面打开过程中占比很小。但是在移动设备上,特别是初端 Android 机型上,由于 CPU 速度提升有限,JS 的编译和解析时间占比就变得显著。那么,在 Android 初端机上,JS 的编译和解析需要消耗多少时间呢?


我们采用以下方法来测试 JS 的编译和解析时间,选取了加载过程中体积最大的两个 JS bundle 文件进行测试:

<script>    window.t1 = Date.now()</script><script scr="1.js" ></script><script>    window.t2 = performance.now()</script><script scr="2.js" ></script><script>    window.t3 = performance.now()    alert("JS1 编译解析耗时:" + (t2 - t1));    alert("JS2 编译解析耗时:" + (t3 - t2));</script>


在启动客户端并打开 WebView 测试页面后,我们得到以下结果:


测试设备:Android: Zebra TC52 Qualcomm Snapdragon™ 660 Octa-Core, 2.2 GHz Memory: 4 GB RAM/32 GB Flash

PC: Ryzen 7 5700G 8核16线程,最高4.6 GHz,内存: 32 GB RAM

测试系统: Android OS 8.1

内容值: 编译+解析时间(毫秒)

_

PC

Android

JS 1(10.36 MB)

68

1503

JS 2(1.70 MB)

327

2169


从测试结果来看,Android 初端机的编译解析时间远慢于 PC,达到了秒级别。此外,过大的 JS bundle 也会拖慢整个 HTML 的解析加载时间。


如何优化:

为了改善这一问题,我们尝试将大型资源文件拆分成更小的片段,实现异步加载,而不是一开始就加载全部。


_

PC

Android

JS 1(10.36 MB → 3.2MB)

8

535

JS 2(1.70 MB → 1.17 MB)

200

1130


经过上述优化,不仅 PC 的性能得到提升,Android 设备的性能提升更为显著。


页面渲染

分析:

在对打开 Dashboard 的过程进行分析时,我们使用了 Chrome 自带的 profiler 工具,并重点关注了两个耗时较大的 Task。


第一个 Task:

在页面渲染时执行的一段 JavaScript 占据了整个 Task 时间的70%以上。


第二个Task:

主要时间消耗发生在 Recalculate Style 和 Layout 上,这两项占据了 Task 总时间的一半以上。


我们发现,在渲染过程中,频繁地向 DOM 中动态添加许多小元素会触发 layout 和 style 的重新计算,这导致整个渲染过程耗时较长。


如何优化:

针对第一个问题,我们尝试减少 Web 与 Native 之间的频繁调用。我们将 Native 的状态信息存储在Web的 Redux store 中,仅在 Native 状态发生变化时更新 store 的 state,而不是每次都调用 Native 函数获取。


针对第二个问题,我们尝试批量添加 element,以减少 layout 和 recalculate style 的次数。通过这些优化措施,我们努力减少渲染过程中的性能瓶颈,以提高在初端 Android 设备上的渲染效率。


4

WebView 性能优化总结

在网页加载的过程中,涉及到 native 端、网络请求、后端处理以及 CPU 等多个环节,每个环节都承担着必要的任务且存在依赖关系。为了加快网页加载速度,关键在于让这些环节能够并行工作而非相互阻塞:

  • JavaScript 下载慢 可以将 JavaScript 文件预先打包进应用中,避免运行时下载。

  • WebView 初始化慢 可以在 Native 初始化时就开始预加载静态资源,充分利用后端和网络资源。

  • JavaScript 加载执行慢: 通过分析和优化,减小 JavaScript 文件大小,降低其对页面解析的阻塞影响。

  • WebView 初始化频繁: 尽量避免重复加载 JavaScript,延长 WebView Context 的生命周期。

  • Web 与 Native 交互频繁: 减少 Web 和 Native 之间的调用次数,因为这些调用在低性能设备上的开销不容忽视。

  • DOM 操作过多: 减少 DOM 操作引起的 layout 和 recalculate style 次数,从而提升页面渲染性能。


微策略 商业智能
微策略 MicroStrategy (Nasdaq: MSTR) 是企业级分析和移动应用软件行业的佼佼者。关注我们了解行业资讯、技术干货和程序员日常。
 最新文章