Skip to content

白屏检测开销 ​

量化 ErrorPlugin 白屏检测对页面性能的影响:在真实 SDK 路径上(起真实 TripoLens + ErrorPlugin,不复刻算法)截取单次判定的主线程占用,跨 5 个 DOM 复杂度场景(白屏态 → 典型内容 → 深层堆叠 → 海量节点 → 布局脏)对比,回答「这项检测日常花多少、最坏情况会不会卡」。

测量口径

一次判定 = SDK 同步连发 17 次 document.elementsFromPoint。探针包裹该方法(L6 domAdapter 每次动态读取,可无侵入包裹),「首次调用开始 → 第 17 次调用结束」的墙钟跨度即单次判定核心耗时——测的是真实代码路径,SDK 零改动。全程 mock 静默(不出网),并显式 debug: false 硬关 Debug Bridge(拒绝页面级 __tripo_lens_debug flag,保证零观测口径)。运行期间视口会被白色场景层短暂覆盖,属预期。

指标怎么算、为什么这么设 ​

为什么测 17 次 elementsFromPoint 的连发窗口 ​

白屏检测的成本结构里,_samplePoints 是纯算术、判定后组 payload/emit 在 µs 级,唯一有量级的开销是 17 次 elementsFromPoint + 每点最多 N 次 closest(N=空容器白名单长度)。elementsFromPoint 是强制 hit-test 的 DOM 读操作,布局脏时还会触发强制同步布局(forced reflow),成本随页面 DOM 复杂度变化——所以按「首次调用开始 → 第 17 次调用结束」截窗口,closest 夹在调用间隙也一并计入,即单次判定的完整同步占用。

为什么每样本新建实例、而不是反复切路由 ​

白屏检测每页面至多判定一次(_reported 门闸),重判只能靠首屏 load 或 SPA 路由切换(pushState/popstate 的 pathname 变化)触发。反复 pushState 会往浏览器 history 里塞几百个条目、污染回退栈;而首屏路径与路由切换路径执行同一 _detect,等价。故每个样本 new TripoLens → init()(文档已 load,start 即排期)→ 捕获 17 连发 → destroy(),干净且无副作用。

whiteScreenDelay 设 20ms 而非 0:保证 await init() 返回后、判定定时器触发前有确定窗口做布局脏化(「布局脏」场景需要在这个窗口里改样式)。

为什么不用 tinybench ​

性能基准页用 tinybench 是因为被测体(track() 等)可以直接放进任务函数体反复调用。而这里的被测段是 SDK 内部 setTimeout 回调中的一段同步窗口,外部无法作为任务体交给 tinybench 计时,只能探针取窗口。统计(mean / 样本标准差 / p95 / max)自算:每场景预热 5 个样本丢弃(JIT / 布局缓存到稳态)+ 正式 25 个样本。

场景矩阵为什么这么选 ​

场景 DOM 渲染在满视口不透明覆盖层里(elementsFromPoint 会跳过 pointer-events:none 的元素,故覆盖层保持可命中),跑完即拆:

  • 白屏态:覆盖层为空且其选择器加入 whiteScreenContainers,17 点栈顶均为空容器 → 真实命中并走完整 emit 路径(表格「白屏命中」列即验证)。这是白屏检测「生效时」的成本。
  • 典型内容页:几十张卡片铺满视口,日常页面的命中栈——大多数页面的真实日常成本。
  • 深层堆叠 ×60:60 层嵌套全屏 div,elementsFromPoint 每点返回长祖先栈——检验栈深的边际代价。
  • 海量节点 ×4000:4000 个网格小格铺满视口——检验大 DOM 的 hit-test 遍历代价。
  • 海量节点+布局脏:判定定时器触发前改覆盖层样式弄脏布局,首次 elementsFromPoint 付强制 reflow——最坏情况上界:真实页面里检测恰好赶上一次未落地的样式变更。

白屏检测会拖慢页面吗(结论怎么读) ​

看表格下方的「解读」行:以最坏场景的 mean 对照两条业内基线——一帧 16.7ms(占比多少)与 long task 阈值 50ms(是否可能被用户感知为卡顿)。再叠加触发频率(每页面至多一次、防抖合并、命中即停),即可判断这项检测的真实影响面。若你的业务页 DOM 极复杂且实测逼近阈值,可调大 whiteScreenDelay(错开首屏忙碌期)或收窄 whiteScreenContainers 白名单(减少每点 closest 次数)。

已知精度边界 ​

  • Chrome 非跨源隔离下 performance.now() 量化 ~0.1ms;空白/典型场景单次判定可能亚毫秒,单样本读数粗粒度,靠 25 样本均值平滑,±sd 列反映离散度。
  • 采样点坐标由视口尺寸决定(中心十字 17 点),注脚带当次视口;数字是本机单次运行的相对值,用于场景间横向对比,不跨机器可比。
  • 探针不含判定后组 payload / 分级 / emit 的开销(µs 级,可忽略);常驻成本(1 定时器 + 2 订阅)无量级,不设维度。

基于 MIT 协议发布(内部使用)