资讯详情

资讯详情

Chrome Performance面板实战:从火焰图定位前端性能瓶颈

1. 页面性能工具到底在解决什么问题前端性能优化这件事很多人第一反应是“代码写得好不好”但实际工作中你会发现真正难的不是写出高性能代码而是定位性能瓶颈到底在哪里。我见过太多团队在优化时凭感觉走觉得首屏慢就拼命做懒加载觉得卡顿就到处加防抖结果改了一堆东西 Lighthouse 分数从 62 涨到 65用户该卡还是卡。问题的根源在于没有度量就没有优化。浏览器提供了 Performance 面板这个工具它做的事情就是把页面从加载到交互的整个生命周期拆解成一条精确到毫秒的时间轴让你能像看慢动作回放一样看清楚每一帧、每一个任务、每一次网络请求到底花了多少时间。Performance 面板能回答的核心问题包括页面加载阶段哪个资源拖了后腿、主线程在什么时候被什么任务阻塞了、交互响应延迟是网络问题还是渲染问题、内存有没有泄漏导致页面越用越卡。它适合所有前端开发者不管你是刚入行的新手还是工作多年的老手只要你的页面需要跑在浏览器里这个工具就是必备技能。我个人的经验是掌握 Performance 面板之后性能优化从“玄学”变成了“工程”。你不再需要猜打开面板录一段问题基本都能定位到具体文件和具体代码行。这篇文章我会从面板结构讲起然后拆解录制和分析的完整流程最后分享一些实际排查中踩过的坑和技巧。2. Performance 面板的整体结构与核心概念2.1 面板四大区域的功能划分打开 Chrome DevTools切到 Performance 标签你会看到界面大致分成四个区域。很多人第一次打开会被密密麻麻的色块吓到其实只要理解每个区域负责什么上手并不难。顶部是控制栏包含录制按钮、刷新并录制按钮、清除按钮以及一些配置选项。这里有个细节很多人忽略录制按钮旁边有个小齿轮图标点开可以设置 CPU 降速和网络降速。这个功能非常关键后面我会专门讲。中间是概览区展示的是整个录制时间段内 CPU 和网络的整体情况。CPU 那一行用不同颜色表示不同活动蓝色是加载、黄色是脚本执行、紫色是渲染、绿色是绘制。网络那一行则显示请求的瀑布流。概览区的作用是让你快速定位到“哪个时间段有问题”比如你看到某一段黄色特别密集就知道那段时间主线程在疯狂跑 JS。下方是火焰图区这是 Performance 面板的核心。它按时间轴展开每一行代表一个线程或一个类别横向的条块代表任务条块的长度就是耗时。火焰图区默认会展示 Main 线程、Compositor 线程、GPU 线程等。Main 线程是重点因为 JS 执行、样式计算、布局、绘制都在这里发生。右侧是详情面板当你点击火焰图中的某个条块时这里会显示详细信息。比如你点了一个函数调用这里会显示函数的名称、文件位置、执行时间、自身时间Self Time和总时间Total Time。自身时间指的是这个函数本身消耗的时间总时间包含了它调用的子函数。这两个概念非常重要后面分析时会反复用到。2.2 火焰图里那些色块到底代表什么火焰图里的色块颜色不是随便设计的每种颜色对应一类活动。理解颜色含义能让你扫一眼就大致判断问题类型。蓝色Loading 相关包括 HTML 解析、网络请求回调等。黄色Scripting也就是 JavaScript 执行。黄色块越多越长说明 JS 越重。紫色Rendering包括样式计算Recalculate Style和布局Layout。绿色Painting绘制相关包括图层绘制和合成。灰色System 和其他活动比如 GC垃圾回收。红色通常表示长任务或者警告需要重点关注。我刚开始用的时候看到一大片黄色就慌觉得 JS 太多了。后来才明白黄色多不一定有问题关键看这些黄色块是不是集中在关键路径上以及单个任务有没有超过 50ms。浏览器的主线程是单线程的一个任务超过 50ms 就会被标记为长任务用户就能感知到卡顿。所以看火焰图时找长任务比看颜色面积更重要。2.3 关键指标FPS、CPU 和网络瀑布流概览区的 FPS 图表显示的是每秒帧数。理想情况下应该稳定在 60fps也就是每帧 16.7ms。如果 FPS 图表出现红色条说明有帧丢失用户会感觉卡顿。FPS 掉帧通常和长任务有关因为主线程被 JS 占着没空去渲染下一帧。CPU 图表显示的是 CPU 使用率。如果 CPU 长时间跑满说明主线程压力大。但要注意CPU 跑满不一定是坏事短时间跑满然后空闲是正常的持续跑满才是问题。网络瀑布流显示的是资源加载顺序和耗时。这里能看出哪些资源是串行加载的哪些是并行的。如果关键资源被排在后面首屏就会慢。网络瀑布流和火焰图是联动的你点某个请求火焰图会跳到对应的时间点。3. 录制一场有意义的性能分析3.1 录制前的环境准备录制之前有几件事必须做否则录出来的数据没有参考价值。第一使用无痕模式。浏览器插件会注入脚本影响性能数据。无痕模式默认禁用插件能保证环境干净。如果你不得不在普通模式下录至少把插件都关掉。第二开启 CPU 降速。这是最容易被忽略但最重要的一步。现在的开发机性能都很好你不降速录出来的数据全是绿的什么问题都看不出来。但用户的设备可能只是中低端手机性能只有你开发机的四分之一甚至更低。我一般会把 CPU 降速设为 4x 或 6x模拟中低端设备。网络也可以降速比如设为 Fast 3G 或 Slow 4G模拟移动网络环境。第三明确录制目标。不要漫无目的地录先想清楚你要分析什么。是首屏加载慢还是某个交互卡顿还是滚动不流畅目标不同录制的操作也不同。分析加载性能就录页面刷新分析交互性能就录点击操作分析滚动性能就录滚动过程。第四清空缓存并刷新。如果你想分析首次加载性能需要勾选“Disable cache”并硬刷新。如果分析的是二次加载就不用清缓存。这两种场景的性能特征完全不同不要混在一起看。3.2 录制操作的节奏控制录制按钮点下去之后你的每一个操作都会被记录。这里有个技巧操作之间要有停顿。比如你要分析页面加载点“刷新并录制”之后就不要动鼠标了等页面完全加载完再停止录制。如果你在加载过程中乱动火焰图里会混入交互事件分析起来很麻烦。分析交互性能时操作要干净。比如你要测一个按钮点击的响应就只点那一下不要连续点。点完之后等一两秒再停止录制让后续的渲染和布局都记录下来。录制时长也要控制。一般 5 到 15 秒就够了太短可能没覆盖完整流程太长数据量太大不好分析。我见过有人录了一分钟火焰图密密麻麻根本没法看。3.3 录制后的第一眼看概览找异常录完之后不要急着扎进火焰图先看概览区。这一步能帮你快速缩小范围。先看 FPS 有没有红色条。如果有记下大概的时间点然后去火焰图对应位置找长任务。再看 CPU 图表有没有持续跑满的区间。最后看网络瀑布流有没有某个请求特别长或者关键资源被阻塞了。概览区的作用是“定位问题时间段”火焰图的作用是“定位问题代码”。先粗后细效率最高。我刚开始用的时候直接看火焰图结果在几千个条块里找问题眼睛都看花了。后来学会先看概览基本能在半分钟内锁定问题区域。4. 火焰图深度分析实战4.1 识别长任务与主线程阻塞长任务是性能问题的头号嫌疑犯。在火焰图中长任务会显示为一个很长的条块通常超过 50ms。你可以用鼠标在火焰图上拖动选中一段区域概览区会显示这段区域的总耗时和任务数量。找到长任务后点击它右侧详情面板会显示这个任务的详细信息。重点看两个东西任务的总耗时和任务内部的函数调用栈。如果任务总耗时 200ms里面有一个函数自身时间 150ms那这个函数就是罪魁祸首。常见的长任务来源包括大量 DOM 操作、复杂的计算、同步的 XHR 请求、大型 JSON 解析、频繁的布局抖动。我遇到过一个案例页面滚动时卡顿录下来发现每次滚动事件触发后都有一个 80ms 的长任务点进去看是一个函数在循环里反复读取 offsetHeight导致浏览器强制同步布局。改成批量读取后长任务降到 5ms 以内。4.2 分析函数调用栈与自身时间火焰图的调用栈是从下往上读的。最下面是底层函数越往上越接近入口。每个条块的长度代表执行时间但要注意父函数的长度包含了子函数的时间。所以看的时候要关注自身时间也就是详情面板里的 Self Time。举个例子你看到一个函数 A 总时间 100ms但它调用了 B 和 CB 自身 30msC 自身 40ms那 A 自身只有 30ms。优化的时候优先优化自身时间长的函数。如果 A 自身时间很短但总时间很长说明问题在它调用的子函数里要继续往下挖。还有一个技巧用“Bottom-Up”视图。火焰图默认是“Call Tree”视图从入口往下展开。切换到“Bottom-Up”后它会按自身时间从大到小排列所有函数直接告诉你哪个函数最耗时。这个视图在快速定位热点函数时非常好用。4.3 网络请求与资源加载的关联分析火焰图上方有一条“Network”轨道显示所有网络请求。你可以把鼠标放在某个请求上火焰图会自动跳到该请求发起的时间点。反过来点击火焰图中的某个资源加载回调也能看到对应的网络请求。分析加载性能时重点看关键请求链。比如 HTML 加载完后浏览器解析到 link 标签才开始加载 CSSCSS 加载完才开始渲染。如果 CSS 加载慢整个渲染都会被阻塞。火焰图里能看到 HTML 解析、CSS 加载、JS 加载、首次渲染之间的时间关系。我常用的一个技巧是在火焰图里找“First Paint”和“First Contentful Paint”标记。这两个标记之间的时间差反映了从白屏到有内容的时间。如果这个时间差很大说明渲染被阻塞了通常是 CSS 或同步 JS 的问题。4.4 渲染与绘制阶段的性能陷阱紫色和绿色的条块代表渲染和绘制。很多人只关注 JS忽略了渲染性能。实际上布局和绘制的开销有时候比 JS 还大。强制同步布局是最常见的渲染陷阱。当你在 JS 里先修改样式然后立即读取布局属性如 offsetTop、clientWidth浏览器为了给你正确的值会强制立即执行布局计算。如果这在循环里发生就会导致布局抖动性能急剧下降。火焰图里会显示为多个小的紫色“Layout”条块交替出现。绘制区域过大是另一个问题。如果页面有很多复杂的阴影、渐变、圆角绘制开销会很大。火焰图里绿色的“Paint”条块会很长。优化方法是使用 will-change 或 transform 把元素提升为合成层让 GPU 分担绘制工作。但要注意合成层过多会占用大量内存反而导致性能下降。5. 常见性能问题与排查技巧5.1 首屏加载慢的排查路径首屏慢是最常见的性能问题。排查时按以下顺序来先看网络瀑布流找出加载时间最长的资源。如果是图片考虑压缩或懒加载如果是 JS考虑代码分割如果是 CSS考虑内联关键 CSS。再看火焰图找“Parse HTML”和“Evaluate Script”的耗时。如果 HTML 解析慢可能是 DOM 结构太深如果脚本执行慢可能是同步脚本阻塞了渲染。最后看首次渲染时间。如果资源都加载完了但迟迟不渲染检查是否有同步 JS 在阻塞或者 CSS 里有昂贵的计算属性。5.2 交互卡顿的定位方法交互卡顿的排查关键是找到事件处理函数。在火焰图里交互事件会显示为“Event”或“Click”之类的条块。点击它详情面板会显示事件类型和处理函数。如果事件处理函数自身时间很短但后续有长任务说明卡顿在渲染阶段。检查是否有大量 DOM 更新或者是否触发了强制同步布局。如果事件处理函数自身时间很长说明 JS 计算量大。考虑用防抖、节流或者把计算拆分成多个小任务用 requestIdleCallback 或 setTimeout 分片执行。5.3 内存泄漏的间接识别Performance 面板不能直接分析内存但可以通过一些迹象间接判断。比如录制一段时间的操作如果发现 GC垃圾回收频繁出现而且每次 GC 后内存没有明显下降可能存在内存泄漏。更准确的方法是配合 Memory 面板。在 Performance 录制中如果看到灰色的“GC”条块越来越频繁或者页面越用越卡就应该去 Memory 面板拍快照对比。5.4 常见问题速查表现象可能原因排查位置解决方向FPS 掉帧长任务阻塞主线程火焰图找超过 50ms 的任务拆分任务、用 Worker首屏白屏久关键资源加载慢网络瀑布流预加载、内联关键 CSS点击无响应事件处理函数耗时长火焰图 Event 条块防抖节流、分片执行滚动卡顿强制同步布局火焰图 Layout 条块批量读写、避免布局抖动页面越用越卡内存泄漏GC 频率、Memory 面板检查事件监听、定时器动画不流畅绘制区域过大火焰图 Paint 条块合成层、transform6. 从数据到优化实战经验分享6.1 一次典型的性能优化完整过程我拿一个实际案例来串一遍完整流程。某个列表页面用户反馈滚动时卡顿。我打开 Performance 面板开启 4x CPU 降速录制了一段滚动操作。概览区显示 FPS 有明显掉帧CPU 在滚动期间持续高位。火焰图里找到几个超过 60ms 的长任务点进去看发现是一个滚动事件处理函数在每次触发时都读取了元素的 offsetTop导致强制同步布局。优化方案把 offsetTop 的读取缓存起来只在必要时更新。同时给滚动事件加了节流每 16ms 最多执行一次。改完后重新录制长任务降到 10ms 以内FPS 稳定在 55 以上。这个案例的关键点是不要凭感觉优化让数据告诉你问题在哪。如果我不录这一段可能会去优化图片或者加懒加载但那些都不是瓶颈。6.2 录制参数的取舍与陷阱CPU 降速的倍数选择有讲究。4x 适合模拟中端手机6x 适合低端手机。但降速太高会导致所有任务都变长反而难以区分主次。我一般先用 4x 录一遍如果问题不明显再提高到 6x。网络降速也是类似。Fast 3G 适合模拟一般移动网络Slow 4G 适合模拟较差网络。但要注意网络降速会影响资源加载时间但不影响 JS 执行时间。分析 JS 性能时不需要降网络。还有一个陷阱录制时不要开 DevTools 的其他面板。DevTools 本身会消耗性能开着 Elements 面板录制会影响数据准确性。录制时只开 Performance 面板录完再切到其他面板分析。6.3 性能优化的优先级判断拿到性能数据后不要试图一次性优化所有问题。按以下优先级排序第一影响用户核心流程的问题。比如电商网站的加入购物车按钮点击卡顿比页脚动画不流畅重要得多。第二长任务。超过 50ms 的任务直接导致卡顿感优先解决。第三高频操作。滚动、输入、鼠标移动这些高频事件的处理函数即使单次耗时短累积起来也会影响体验。第四首屏关键路径。首屏加载慢直接影响跳出率但优化成本通常较高放在后面。我个人的习惯是每次优化只解决一到两个问题改完立即重新录制对比。这样能清楚知道每个改动带来了多少收益避免改了一堆东西不知道哪个起作用。6.4 那些文档里不会写的实操心得第一个心得火焰图要看“趋势”而不是“绝对值”。同样的代码在不同设备上耗时不同不要纠结于某个函数是 10ms 还是 15ms要看它占总时间的比例以及是否在关键路径上。第二个心得善用“Screenshots”功能。录制时勾选 Screenshots火焰图上方会显示每一帧的截图。分析渲染问题时截图能直观看到页面在什么时候变成了什么样比看色块快得多。第三个心得保存录制结果。Performance 面板支持导出录制文件格式是 JSON。遇到复杂问题时可以把录制文件保存下来慢慢分析或者发给同事一起看。我习惯把典型问题的录制文件存档下次遇到类似问题可以直接对比。第四个心得不要忽略“Idle”时间。火焰图里灰色的 Idle 表示主线程空闲。如果 Idle 很多但页面还是慢说明瓶颈不在主线程可能在网络或者 GPU。这时候要去网络瀑布流或者 GPU 轨道找原因。第五个心得移动端真机调试。DevTools 的模拟降速和真机还是有差距。有条件的话用真机连接调试录制的数据最准确。真机上的一些性能问题在桌面模拟环境里可能根本复现不出来。7. 把 Performance 变成日常习惯Performance 面板最大的价值不是解决某一次性能问题而是帮你建立性能意识。当你习惯了看火焰图写代码时会自然避开那些已知的性能陷阱不会在循环里读布局属性不会写超长的同步任务不会让事件处理函数做太多事情。我现在的习惯是每做一个新功能上线前用 Performance 录一段确认没有长任务和明显掉帧。这个习惯花不了几分钟但能避免很多上线后的性能问题。性能优化不是一次性的项目而是持续的过程。工具就在那里用不用、怎么用决定了你的页面是流畅还是卡顿。最后分享一个我常用的检查清单录制前确认无痕模式、CPU 降速、清缓存录制时操作干净、有停顿分析时先看概览找异常时间段再看火焰图找长任务最后看详情面板找具体函数优化后重新录制对比。这套流程走下来大部分性能问题都能定位和解决。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →