Ede's Blog

WEB文字性能优化简述

以下为概述,具体不展开

结论:两板斧下来,无论是首屏加载还是渲染,都有25%以上的提高。
小声BB:可能还是原来的代码太菜

方向

  • 首屏打开速度

  • 高频操作优化(eg:输入)

文字的三大步骤

  • 文字排版:输入后,计算布局排版结果(类似于浏览器的重排)
  • 排版渲染:得到排版结果,文档前端绘制(类似于浏览器的重绘)
  • 视图更新:GCP变化触发一系列React组件更新

一般地,执行的流程是:文字排版 -> 排版渲染 -> 视图更新

测量工具

  • Dev Performance & React Tools

首屏优化

分析首页加载的步骤

  • 按业务分阶段加载组件:

    • 首屏渲染阶段(KPI生命线)
    • 首屏渲染后(加载一些必要的组件,避免断网影响)
    • 其他辅助功能(用到时才加载)。
  • 网络层面优化:

    • preload服务端渲染
    • 提取公共库以及业务核心库(eg:React,polyfill),并移除某些polyfill
      • 减少约10%代码量
    • 语法层面采用更规范的ES6 modules
      • Babel默认的Commonjs会引入副作用导致webpack无法Tree Shake
      • 减少约7%代码量
    • 缓存:
      • cdn缓存(更新频繁时,命中率周期变化)
      • pwa缓存(这个作用不好评估,会加大init的时间)
        • 【后续,已移除PWA,中国缺少PWA生存土壤】
      • 入口文件prefetch文件
      • 组件相互唤起(未参与,不知优化效果)
    • 请求方式:提前加载,串行转并行
      • webpack code split后不注意会导致串行
      • 首次加载,网速较慢时,约提高100ms(未来可考察server push

高频操作优化

更新周期耗,期望小于16ms(60FPS-流畅),不高于32ms(30FPS-平稳)。

基本方法:

  1. 实时函数调用,进行性能优化。
  2. 非实时函数调用,进行限流防抖。

例子

  • 限制操作频率(最简单粗暴且有效)
  • 限制更新频率:
    • 组件更新异步:requestAnimaterequestIdleCallback(eg:SelectionChanged)
    • 减少setState调用次数(触发React diff,会占用1~2ms的时间)
    • 缓存高频属性(如clientWidthscrollTop等)(throttle自带缓存机制
  • 用ES5的接口替代部分JS实现,如:
    • Object.assign取代copy
    • 避免过频使用RegExep(第一次向Chromium提bug
    • 高频方法避免使用析构...args(polyfill后会转变成数组的slice、concat,耗时严重)
  • 渲染方面,svg较canvas,在放大缩小操作上有明显的性能优势。
    • svg结构松散时,可合并图层(离屏渲染、DocumentFragment)。
  • 更优的数据结构,如区间树(考验硬实力,向C艹大佬低头)
    • 数据巨大,遍历树时,仍是耗时操作,同样需要缓存高频属性

参考