解法
多年来,浏览器一直在通过减少工作量来提升流畅度:只重绘变化的矩形区域、将内容缓存为图层、合成这些图层,最后把这两项工作都移到GPU上。在2017年10月的Mozilla Hacks上,Lin Clark解释了为什么页面仍然卡顿。图层既耗费内存和传输时间,而且浏览器需要猜测页面需要多少图层。图层太多会占满内存并拖慢合成器;图层太少则可能导致重绘的图层被合成时没有变化,每个像素被处理两次。无论怎样,动画背景色都会强制整个图层重绘。
WebRender是Servo的技术,以Quantum Render的名称进入Firefox,它遵循了不同的先例:3D游戏引擎每帧重绘每个像素,并且比浏览器更可靠地保持60 FPS,这得益于GPU拥有成百上千个并行处理像素的核心。因此,WebRender去掉了绘制和合成的边界。布局输出变成了一个显示列表,包含高层级的绘制指令,不依赖任何图形API。WebRender的RenderBackend将该列表转换为批量的GPU绘制调用,GPU每帧重绘页面整个可见场景,无需猜测图层。
让整帧重绘变得可行需要消除不必要的工作。屏幕外的项目在到达GPU之前就被剔除。一个渲染任务树规划出滤镜和层叠上下文所需的最少数量的昂贵屏幕外纹理。绘制调用被批处理,以保持GPU并行核心忙碌。渲染分为从前到后的不透明通道(跳过被覆盖的像素)和从后到前的半透明通道——文章称之为z-culling,这在典型页面上有很大收益。文字字形仍然是CPU的任务,但被缓存在一个跨帧保留的纹理中。
目标是稳定性,而不仅仅是速度:无论显示多大或页面变化多少,都不能出现性能悬崖,要平滑的60 FPS。文章报道,在Chrome或当时Firefox中只能以15 FPS运行的页面,使用WebRender能达到60 FPS,并将这项工作视为为4K显示器和WebVR做准备,后者需要每只眼睛以90 FPS渲染一帧。
What it achieved
别再猜测图层了:把高级显示列表交给GPU,每帧重绘整个页面,采用游戏引擎的方式
为什么有效
GPU有数百到数千个并行处理像素的核心,因此每帧重绘整个可见页面是它们的强项,而不是CPU的任务。
保留的显示列表是对场景的小型、独立于API的描述,因此CPU只需构建一次命令,RenderBackend可以在任何像素工作发生之前进行剔除、排序和批处理。
整个场景的重绘消除了图层猜测及其失败模式:不再误判图层数量,不会重复处理像素,因此帧时间不会跌入性能悬崖。
工作消除使重绘保持廉价:剔除、减少屏幕外目标、批处理和z-culling减少了GPU需要着色的内容,而CPU渲染的字形存放在纹理缓存中,不进入每帧的路径。
可以借鉴什么
当增量式启发法总是遇到最坏情况悬崖时,改变模型:一次性描述整个场景,让大规模并行硬件每帧重绘它
后续
WebRender并没有包含在随后的Firefox Quantum发布中:Lin Clark在文章评论中写道,它将不会在Firefox 57之前落地,并且该文章计划在2018年通过Quantum Render项目进行集成,早期版本已经可以通过标志使用。其链接的演示显示了在Chrome或当天的Firefox中以15 FPS运行的页面,使用WebRender后运行在60 FPS,该说明在2017年10月10日在Hacker News上获得了853个积分和207条评论。
从这里,追溯依据
参考来源
- The whole web at maximum FPS: How WebRender gets rid of jank hacks.mozilla.org
- Hacker News discussion: The whole web at maximum FPS — How WebRender gets rid of jank news.ycombinator.com