页面性能问题排查
方法1:
使用long task
这是一个实验性 API,它可以直观地告诉我们哪些任务执行耗费了 50 毫秒或更多时间
long task 会长时间占据主线程资源,进而阻碍了其他关键任务的执行/响应,造成页面卡顿。
常见场景如:
- 长耗时的事件回调(long running event handlers)
- 一次性生成十分庞大的 DOM 元素,如大型表单;
- 不断计算 DOM 元素的大小、位置/代价高昂的回流和其他重绘(expensive reflows and other re-renders)
- 浏览器在超过 50 毫秒的事件循环的相邻循环之间所做的工作(work the browser does between different turns of the event loop that exceeds 50 ms)
long task 的基本属性
Long Tasks API 定义了 PerformanceLongTaskTiming 接口,用于描述 long task
几个关键字段:
- name: 用于描述 long task 的类型。分成两大类:
- rendering:event loop 中的 update the rendering 步骤,例如页面大量元素需要 relayout
- browser:与 event loop 彻底无关
- self:页面自身,例如执行某 JavaScript 函数
- same-origin-ancestor:同源的上级 frame(自身是 iframe)
- same-origin-descendent:同源的子级 frame(iframe)
- same-origin:同源 frame,但是 unreachable
- cross-origin-ancestor:跨域的上级 frame
- cross-origin-descendent:跨域的子级 frame
- cross-origin-unreachable:跨域 frame 且 unreachable
- multiple-context: 多处来源
- unknown: 未知
- 来自于执行 event loop tasks:
- entryType:值为 "longtask"
- attribution:一系列 TaskAttributionTiming 的集合。可以理解为是 long task 的详细信息。
关于 event loop task 的概念,参见 https://html.spec.whatwg.org/multipage/webappapis.html#concept-task1
一般而言,name + attribution 就可以基本定位出 long task 的来源:
name:告诉我们来源是 <script/> 还是 <iframe/> ?self -> <script/>;same-origin-xxx + cross-origin-xxx -> <iframe/>
attribution:到底是哪个 <iframe/>?
那么,attribution 究竟包含了哪些信息呢?
- TaskAttributionTiming
如上所属,attribution 的值是一些列 TaskAttributionTiming 的集合。
本质上,TaskAttributionTiming 拓展自 PerformanceEntry,具备了以下常见属性:
1 2 3 4 | name:当前只有 "script" 一种 entryType: "taskattribution" start: 0 end: 0 |
此外,TaskAttributionTiming 还具备了四个专有属性:
可以将下述字段中的 container 部分理解为,代码的执行环境。
containerType:来源的类型,且和 name 字段直接关联。例如 name: "self",那么值就是 "";name: "same-origin-descendent",值就是 iframe。此外还可以是 embed,object 等;
containerName:来源的 name 属性。例如 <iframe name="frame"/>;
containerId:来源的 id 属性。例如 <iframe id="frameId"/>;
containerSrc:来源的 scr 属性。例如 <iframe src="/iframe/src"/>。
出于隐私 + 安全的考量,attribution 受到了同源策略的限制。即当 name 是 cross-origin-xxx 时,attribution 中,上述四个 container<token> 专有字段对应的值均为 ""。
当页面含有多个第三方 iframe ,定位 long task 问题时就需要其他手段的辅助。例如,对每个第三方 iframe 进行逐一排查;直觉?
使用:
const observer = new PerformanceObserver(list => { list.getEntries().forEach(entry => { console.log('entry :>> ', entry); }); }); observer.observe({ type: 'longtask', buffered: true });
方法2
性能录制
Chrome -> Console -> Recorder -> Performance panel
https://codesandbox.io/s/dreamy-joana-6eu9i0?file=/src/index.js
const outer = document.querySelector(".outer"); const inner = document.querySelector(".inner"); function onClick() { Promise.resolve().then(function () { setTimeout(function () { console.log("timeout"); }, 0); console.log("promise"); console.log("click"); }); } inner.addEventListener("click", onClick); outer.addEventListener("click", onClick);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现