作者 | 赵公卓
1 写在前面
微信读书中,阅读引擎负责解析并呈现书本每一页的内容,是整个 app 最重要的一个模块,也是用户使用最多,产生交互最频繁的一个模块。
微信读书发布之初,从支持最基本的 TXT 纯文本书籍,再经过快速迭代同时支持 EPUB 格式书籍,整个过程当中阅读引擎的功能一直在快速膨胀,加上项目前期快速试错,进度紧张等原因,逐渐积累的卡顿问题开始凸显,通过对用户反馈的问题进行统计分析,读书时翻页卡顿的投诉占比高达 51%,远超其它问题。为提升读书的用户体验和口碑,我们必须优化解决掉卡顿的问题。
2 测试如何重现并定位
先来看看什么是卡顿,又是什么原因导致的呢?
我们知道大多数手机的屏幕刷新频率是 60hz,如果在 1000/60=16.67ms 内没有办法把一帧的任务执行完毕,就会发生丢帧的现象。丢帧越多,用户感受到的卡顿情况就越严重。
而一个绘制周期中,即每一帧的刷新,需要通过 CPU 和 GPU 两个过程的处理,CPU 主要负责程序内部逻辑处理包括 Measure,Layout,Record,Execute 的计算操作,GPU 则主要负责图形的渲染工作。显示图片的时候,需要先经过 CPU 的计算加载到内存中,然后传递给 GPU 进行渲染。一旦 GPU 或者 CPU 的工作超过了规定时间,就会出现卡顿现象。
从图上可以看到,第一帧中 CPU 处理的时间是合理的,但是由于 GPU 的处理耗时过长,导致在第一帧的 16.6ms 内无法完成对 B 帧的渲染,那么屏幕只能保持 A 帧画面,如果此时是正在运行着动画,那么就会出现卡屏的情况。
同样,在第三帧的时候,画面 B 已经 Ready,被显示到屏幕上,重新更新 A 画面时,由于 CPU 中发生了耗时过长的处理,导致无法在 16.6ms 内完成对 A 画面的渲染,第四帧只能仍然保持 B 画面,又发生了一次卡顿,直到第五帧时,A 画面才得以显示。
清楚了卡顿产生的基本原因后,我们再来结合读书的业务逻辑流程,分析可能导致卡顿的地方在哪里:
在书架中点击一本书到内容完整的呈现出来,会经历以下几步的逻辑处理流程:
1、选择书籍打开。
2、打开书籍时判断书籍当前章节内容是否存在,本地不存在则下载该章节(一个 zip 包),后续内容也会以章节为单位进行下载并解压得到书源文件(html、css)。
3、