AI时代,前段已死 了吗?记一次网页 CPU 占用异常的排查

18次阅读
没有评论

友盟官网首页(umeng.com)在我的机器上打开后风扇狂转,页面几乎无法操作。本文记录排查过程和结论。

AI 时代,前段已死 了吗?记一次网页 CPU 占用异常的排查

壹、现象

网页卡顿有三种常见病因。网络慢表现为内容迟迟出不来;渲染慢表现为内容已经出现但滚动不跟手;算力占用高则页面看起来正常,CPU 和 GPU 却持续满载,机器发热。三种情况的排查方向完全不同。

我的情况属于第三种。为了排除网络因素,我先做了一次测量。

贰、服务端测量

用 curl 测量首页响应:

DNS 解析: 0.0001s   TCP 连接: 0.002s   TLS 握手: 0.90s
首字节: 1.2s       总耗时: 1.8s      状态码: 200

响应正常,服务端和 CDN 没有瓶颈。HTML 本身有 668KB,一般官网首页在 50~100KB 量级,这个体积明显偏大。
随后检查页面加载的资源。CSS 共 3 个文件,体量正常。

JS 包括自家统计 SDK、客服脚本和导航页脚组件。页面源码中 video、canvas、lottie 类动画元素出现 30 余处。

到这里可以初步判断问题出在客户端渲染。动画数量多只是嫌疑,是否成立需要数据支持。

叁、Performance 记录

用 Chrome DevTools 的 Performance 面板录制约 24 秒,导出的 profile 文件为 gzip 压缩的 Chrome Trace JSON,压缩后 21.7MB,解压 130MB。我写了一段 Python 脚本逐行解析,按事件类型聚合耗时。

结果如下表。

指标 数值
记录时长 24.3s
动画帧 / 掉帧 4212 帧中掉帧 2871(68%)
Layout 事件 523 次,累计 818ms
Paint 事件 8741 次
主线程 JS(FunctionCall) 累计 912ms
UpdateLayer 事件 约 11.7 万次

68% 的掉帧率与主观感受吻合。

Layout 只有 523 次、818ms,在主线程中占比不高,重排可以排除主要嫌疑。

主线程 JS 累计不到 1 秒,脚本开销同样有限。

Paint 达到 8741 次,平均每秒约 360 次, 远超 60fps 显示器下应有的水平,加上 UpdateLayer 的数量异常,问题指向逐帧重绘和图层抖动。

肆、定位到具体元素

统计 Paint 事件中被重绘的节点,按累计面积排序,前列全部是装饰元素。

元素 重绘次数 说明
I class='gnode' 202 星系动画节点,单次重绘区域 842×5932
I class='blob b1' ~ b6 各 92 六个模糊光斑
DIV class='bg-aurora' 85 全屏背景
A class='cta-dark' 1116 页面按钮,受背景动画影响被连带重绘

检查 HTML 源码,这些光斑元素带有如下样式:

filter: blur(6px) saturate(108%);
filter: blur(10px);

原因至此确定。六个带 blur 滤镜的大面积元素持续做位移动画,带 filter 的元素无法使用简单的合成路径,浏览器每一帧都要对其覆盖区域重新栅格化,blur 又是栅格化中开销较高的操作。多层叠加、全屏尺寸、不间断运行,三个因素叠加后 CPU 和 GPU 同时被占满。

那个按钮被重绘 1116 次,与它自身的样式无关。它与背景动画元素重叠,背景每帧失效时它也进入重绘范围,属于连带伤害。

渲染管线的成本分布

这次问题的机制可以归结为浏览器渲染各阶段的成本差异。只改 transform 和 opacity 时走合成器,GPU 处理,主线程基本空闲,成本最低。改颜色、阴影或做大面积 canvas 重画会触发绘制,逐帧重画像素。改几何属性(width、top、margin 等)会触发重排,影响整个布局子树。JS 循环中交替读写布局属性则会在一帧内多次强制重排,成本最高。

友盟首页的特效属于第二档,即逐帧重绘加 blur 重栅格化,并且叠加了多层、全屏、持续运行三个放大因素。动画数量多本身未必导致问题,关键在于实现是否停留在合成档。

验证方法很简单:DevTools 的 Rendering 面板开启 Paint flashing,页面上持续闪烁绿色区域的部位即为逐帧重绘位置。

处理

问题出在对方的实现上,本机只能缓解。绕开首页直接访问控制台(passport.umeng.com)或文档页是最直接的办法,特效只在首页存在。用浏览器扩展拦截统计和客服脚本可以减少一部分脚本开销,对 blur 重绘无效。

我另外写了一个油猴脚本(Cool Page),按需冻结页面特效。脚本清除 filter 和 backdrop-filter,停用 CSS 动画,暂停视频,并将 requestAnimationFrame 限流到 2fps,状态按站点记忆。canvas 和 lottie 的动画循环依赖每帧重新注册 rAF,限流后即静止。脚本文件见 cool-page.user.js。

  文件名称:cool-page.user.js
  文件大小:2KB
  下载声明:本站部分资源来自于网络收集,若侵犯了你的隐私或版权,请及时联系我们删除有关信息。

评论

友盟以用户行为数据分析为主营业务,其官网首页的加载性能低于行业一般水平。重特效营销页追求视觉表现无可厚非,全屏 blur 动画的实现代价应当被评估,至少应保证页面在普通机器上基本可用。这类问题在营销页中并不少见,本次只是其中一个有完整数据记录的样本。

正文完
 0
评论(没有评论)
验证码