腾讯文档渲染优化之路

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. 腾讯文档渲染优化之路 肖骏 腾讯AlloyTeam 前端高级工程师
2. 个人介绍 肖骏,腾讯前端高级工程师,目前在AlloyTeam专注 腾讯文档doc排版渲染开发和优化,致力于跟团队一起 打造在线文档精品。 腾讯AlloyTeam 肖骏
3. 目录 1. 腾讯文档 ,科技向善 2. 腾讯文档渲染优化之路 3. AlloyPerf精确统计FPS
4. 01 腾讯文档 ,科技向善
5. 腾讯文档 — 可多人 协作的在线文档 · 1.6亿+ 月活用户数超过1亿6千万 · 1600万+ 日活用户数峰值超过1600万 · 300万+ 日活跃文档数超过300万 腾讯文档 — 可多人协作的在线文档
6. 科技向善,一直在路上 《环球网》报道 《中国青年报》报道 《央视新闻》报道 《环球网》对河南暴雨“救命文档”的报道,3000多人 《中国青年报》对河南暴雨的报道,报道了“救 《央视新闻》对河南暴雨“救命文档”的报道, 通过“救命文档”得到救助 命文档”的创建过程。 报道了文档的的实时记录过程
7. 保证极限场景的渲染交互 河南暴雨“救命文档” 河南暴雨救灾过程中,应对极限情况,腾讯文档需要支撑数十万行的数据渲染交互不卡顿
8. 02 腾讯文档渲染优化之路 在渲染上如何一步步优化?
9. 腾讯文档渲染优化之路 青铜时代 — Dom 腾讯文档最早期,使用Dom渲染 白银时代 — Canvas 腾讯文档中期,升级为Canvas渲染引擎 黄金时代 — 进阶优化 现在,基于Canvas渲染引擎进一步优化
10. 青铜时代的Dom渲染 Sheet — Handsontable Doc — React 初始阶段,Sheet使用Handsontable作为dom渲染的UI框架 初始阶段,Doc使用React作为dom渲染的UI框架
11. Sheet页面构成 腾讯文档Sheet页面示例 · 单元格 数量多、结构类似 · 图表、选区 数量少、结构独立 单元格 图表 选区
12. 渲染管道优化 Layout优化 Paint优化 • 尽量避免改变元素的几何属性(例如宽度、高度、左侧或顶部位置等) • 使用 will-change 或 translateZ 等提升元素层级 • 修改“paint only”属性(例如背景颜色、文字颜色等)-> repaint • 使用 transform 和 opacity 属性
13. Dom滚动复用 通过Dom复用极大减少了渲染的Dom数量
14. Recalculate Style / Layout开销 Layout Recalculate Style 开销 开销 元素复杂+滚动速度 元素复杂+滚动速度 随着页面元素复杂程度和页面滚动速度的增加,Layout 开销随之线性增长 随着页面元素复杂程度和页面滚动速度的增加,Recalulate Style 开销随之极大增加
15. 升级Canvas渲染引擎 · 业务逻辑 · Recalculate Style · Layout Canvas渲染层级
16. Canvas渲染模型 · 背景色 · 边框线 · 文字 以Sheet为例,Canvas渲染模型可抽象为每个单元格背景色、边框线、文字的渲染
17. 极端场景全表双边框 · 绘制量 X 2 相比于单边框,全表双边框绘制量直接翻倍 · 对接逻辑 对于双边框的绘制需要额外的对接逻辑。 渲染时间:单边框6.71ms -> 双边框 14.91ms
18. 业务逻辑都在干什么? 内存GC 调用Canvas API 浏览器垃圾收集器会定期(周期性)找出那些不在继续使用的 设置状态:strokeStyle、fillStyle 变量,然后释放其内存 执行绘制:fillText、strokeText、drawImage
19. 减少渲染时触发GC 频繁GC导致帧率不稳定 render • 大量创建对象会导致更频繁的GC • 频繁的GC会导致帧率不稳定,引起卡顿 new obj() GC init static pool render get obj from pool 对象池优化 • 建立对象池缓存,从对象池获取对象 • 减少渲染主循环过程中新建对象操作,从而减少GC
20. Canvas API调用的分析 CanvasStyle类继承关系 · 上下文设置style 通过canvas上下文设置的fill_style、stroke_style等状 态, 实际上都是CanvasStyle这个类的实例 · GC逻辑低效 GarbageCollected 自己实现了一套GC逻辑,并不会 走V8引擎的GC,不如C++ GC高效 · 性能开销 Canvas API调用设置状态操作,性能开销较大 CanvasStyle 类继承于GarbageCollected类,GarbageCollected 自己实现了一套GC逻辑,并不会走V8引擎 的GC,不如C++ GC高效
21. Canvas 切换状态机 · 渲染单元格 渲染背景色 渲染边框线 渲染富文本 …… · 渲染文本 渲染color: black文字 渲染color: red文字 渲染color: blue文字 …… Canvas在渲染过程中针对单元格需要渲染背景色、边框线、富文本,而不同的颜色、文本等又 需要不同的状态,所以需要频繁切换状态机
22. Canvas 切换状态机优化 · 遍历待绘制内容 遍历待绘制的所有边框线、文字等 · 相同状态内容整理 相同状态的绘制内容,进行合并、排序等整理 · 分类渲染 整理之后的内容,根据状态机进行分类渲染 通过提前收集、统一整理,减少切换状态机
23. Canvas 渲染复用 页面滚动时canvas渲染复用 · 离屏Canvas 离屏Canvas缓存主Canvas绘制内容 · 复用 直接复用离屏Canvas缓存的内容 通过离屏Canvas的复用,尽量减少canvas重绘
24. 03 AlloyPerf精确统计FPS 如何精确、自动化统计FPS?
25. 现有Web前端FPS统计方式 类似Chrome devtools的开发者工具 • 需要人工实时监测、无法自动化; • 更加适合开发阶段进行自测; RequestAnimationFrame API • 统计的FPS结果不够准确,因为以两次主线程执行时间间隔作为一帧; • 模拟交互不够真实,需要引入脚本且实现对应代码;
26. 主线程阻塞情况下浏览 器的优化 主线程阻塞情况下页面的滚动 · 嵌入死循环js <script> function block() { while (true) {} } setTimeout(block, 2000); </script> · 滚动依然流畅 页面嵌入死循环js,导致主线程完成阻塞,然而页面滚动依然十分流畅
27. Chrome浏览器做了什么? 主线程滚动 合成线程滚动 Chrome浏览器在主线程阻塞情况下,会将页面滚动处理由主线程移交给合成线程
28. FPS本质是什么? 渲染管道 · 帧率 浏览器渲染动画或页面每一帧的速率 · 渲染管道 浏览器渲染每一帧经历的固定流程 主线程 合成线程 GPU线程 主线程阻塞情况下,页面渲染可能在其之后的合成线程、GPU线程进行处理
29. Tracing工具 Chrome devtools performance 普遍常用的Chrome devtools performance面板 Tracing view 信息更加详细、全面的的Tracing view工具,使用chrome://tracing开启
30. Tracing view介绍 · 进程、线程 展示对应进程、线程信息 · Flow 事件对应的流向 · TRACE_EVENT 表示浏览器内核函数调用执行情况 Tracing view
31. 分析主线程阻塞时滚动 Tracing view示例图 · 主线程V8执行js死循环 · 合成线程处理滚动 合成线程 处理滚动
32. 寻找关键TRACE_EVENT 帧数据渲染流向 · 关键TRACE_EVENT 关键TRACE_EVENT出现次数 = 帧渲染次数 · 排除主线程 将寻找关键TRACE_EVENT的路径集中到主线程之后 的流程 寻找关键TRACE_EVENT将主线程排除,关注点放在后面的合成线程
33. 确定关键TRACE_EVENT · 合成线程中TRACE_EVENT ProxyImpl::ScheduledActionDraw 确定关键TRACE_EVENT,合成线程中 ProxyImpl::ScheduledActionDraw 可以作为 关键TRACE_EVENT进行FPS统计
34. AlloyPerf 实现原理 Action Emulation 静态 滚动 自定义 移动端 CPU 网速 清洗过滤 详细分析FPS异常原因
35. 跨平台环境、自动化CI · Docker集成环境 docker集成chrome、chrome driver统一环境,支持 跨平台 · 自动化CI 支持自动化CI,通过测试用例自动化测试统计对应、 对应交互的页面FPS Docker 集成环境 自动化CI流水线
36. 高效复用、快速接入 · npm包 公司内部npm打包发布,集成npm快速接入 · 全面开源 AlloyPerf 在公司内部打磨完善后,未来会对外全面开 源,to be continued…… 内部npm包
37. 感谢倾听 大会官网

首页 - Wiki
Copyright © 2011-2024 iteam. Current version is 2.132.0. UTC+08:00, 2024-09-21 10:35
浙ICP备14020137号-1 $访客地图$