OLED屏幕的1个像素R:G:B比例为1:2:1,显示时DDIC(Display Driver IC,显示驱动芯片)会进行次像素渲染从其他像素借元素使显示更饱满。但代码并不能直接控制该行为,系统需要保证提交的内容与屏幕像素完全对齐,即不能出现类似使用0.5个像素的情况。
标黄区域为坐标、大小结果与屏幕像素未对齐
其他的优化还有:智能预加载、消息回收、图片资源异步解码等。如下图所示,根据屏幕比例得到一级缓存 display ,二级缓存 preload ,超出的部分则被回收释放。
资源预加载策略图
2.2.3 尽可能让 GPU 绘制简单的界面,减少 GPU 耗时。
除了布局可以异步计算,复杂的图像也能使用"异步渲染"的方式降低 GPU 的耗时;特别是面对需要叠加裁剪的图形时, GPU 的绘制任务无法在一个 Frame 内完成,就需要再额外开辟一个 Frame Buffer 进行绘制,并在全部完成后将两个 Buffer 的内容进行合成,这被称作“离屏渲染”。离屏渲染对于性能的损耗非常大,主要在于 GPU 的上下文切换所需的开销很大,需要清空当前的管线和栅栏。原话在这:A Performance-minded take on iOS design | Lobsters。对于这种情况,苹果的工程师给出的建议是用 CPU 绘制来给 GPU 分担一部分工作。如下图所示:
标黄区域为GPU离屏渲染,不可否认GPU的off-screen比CPU的off-screen代价高很多;在无法避免mask的场景下,使用多核CPU进行异步渲染性能更好。
我们在渲染消息时利用了多核 CPU 进行异步渲染,降低 GPU 部分的耗时。这里面临的难点在于:在可快速滑动更新的列表场景使用时会出现"闪白"的问题;如著名第三方开源框架 YYKit 也存在此类问题,我们通过 LRU 缓存 增量刷新的方式很好的解决了此问题。
2.2.4 叠满 buffer 的丝滑体验
基于上述 CPU 与 GPU 维度的各项优化,我们在消息 Tab 上实现了国内头部同类应用目前也不具备的滚动中实时接收消息的能力,且不会出现卡顿;此外,也扩展了老版本 150 个会话的限制,与聊天界面一致以分页的形式加载用户所有的会话节点,如下所示:
,时长00:13
滚动中接受消息,且不卡顿
进入群、好友聊天界面的速度也得到了质的提升,在加快进入动画的同时,依然能够保证即刻就能看到最新的聊天内容。如下图所示 —— 同一个帐号进入同一个聊天页面。左边是优化前的效果,聊天页面都快全部展示了,内容还在加载中;右边是优化后效果,聊天页面只展示了一点点,就已经能看到发送方头像和消息内容了。