使用 Chrome 的任务管理器了解您的页面当前正在使用的内存量。 使用 Timeline 记录可视化一段时间内的内存使用。 使用堆快照确定已分离的 DOM 树(内存泄漏的常见原因)。 使用分配时间线记录了解新内存在 JS 堆中的分配时间。
下面两列可以告诉您与页面的内存使用有关的不同信息: Memory 列表示原生内存。DOM 节点存储在原生内存中。 如果此值正在增大,则说明正在创建 DOM 节点。 JavaScript Memory 列表示 JS 堆。此列包含两个值。 您感兴趣的值是实时数字(括号中的数>字)。 实时数字表示您的页面上的可到达对象正在使用的内存量。 如果此数字在增大,要 么是正在创建新对象,要么是现有对象正在增长。 使用 Timeline 记录可视化内存泄漏
//要显示 Timeline 内存记录,请考虑使用下面的代码:
var ary = [];
function grow() {
for (var i = 0; i < 10000; i++) {
document.body.appendChild(document.createElement('div'));
}
ary.push(new Array(1000000).join('x'));
}
document.getElementById('grow').addEventListener('click', grow);
每次按代码中引用的按钮时,将向文档正文附加 1 万个 div 节点,并将一个由 100 万个 x 字>符组成的字符串推送到 x 数组。运行此代码会生成一个类似于以下屏幕截图的 Timeline 记录:
现在,我们将根据屏幕截图来分析代码。如果查看节点计数器(绿色图表),您会看到它与代码完全匹配。节点计数以离散步长方式增大。 您可以假定节点计数的每次增大都是对 grow() 的一次调用。 JS 堆图表(蓝色图表)的显示并不直接。为了符合最佳做法,第一次下降实际上是一次强制垃圾回收(通过按 Collect garbage 按钮实现)。随着记录的进行,您会看到 JS 堆大小高低交错变化。这种现象是正常的并且在预料之中:每次点击按钮,JavaScript 代码都会创建 DOM 节点,在创建由 100 万个字符组成的字符串期间,代码会完成大量工作。这里的关键是,JS 堆在结束时会比开始时大(这里“开始”是指强制垃圾回收后的时间点)。在实际使用过程中,如果您看到这种 JS 堆大小或节点大小不断增大的模式,则可能存在内存泄漏。
使用堆快照发现已分离 DOM 树的内存泄漏
只有页面的 DOM 树或 JavaScript 代码不再引用 DOM 节点时,DOM 节点才会被作为垃圾进行回收。 如果某个节点已从 DOM 树移除,但某些 JavaScript 仍然引用它,我们称此节点为“已分离”。已分离的 DOM 节点是内存泄漏的常见原因。此部分将教您如何使用 DevTools 的堆分析器确定已分离的节点。
下面是一个已分离 DOM 节点的简单示例
let detachedNodes;
function create() {
let ul = document.createElement('ul');
for (let i = 0; i < 10; i++) {
let li = document.createElement('li');
ul.appendChild(li);
}
detachedTree = ul;
}
document.getElementById('create').addEventListener('click', create);
点击代码中引用的按钮将创建一个包含 10 个 li 子级的 ul 节点。 这些节点由代码引用,但不存在于 DOM 树中,因此它们已分离。
堆快照是确定已分离节点的一种方式。顾名思义,堆快照可以为您显示拍摄快照时内存在您页面的 JS 对象和 DOM 节点间的分配。
要创建快照,请打开 DevTools 并转到 Profiles 面板,选择 Take Heap Snapshot 单选按钮,然后按 Take Snapshot 按钮。
以黄色突出显示的节点具有 JavaScript 代码对它们的直接引用。 以红色突出显示的节点则没有直接引用。只有属于黄色节点的树时,它们才处于活动状态。 一般而言,您需要将注意力放在黄色节点上。 修复代码,使黄色节点处于活动状态的时间不长于需要的时间,您也需要消除属于黄色节点树的红色节点。
点击黄色节点对其进行进一步调查。在 Object 窗格中,您可以看到与正在引用该节点的代码相关的更多信息。 例如,在下面的屏幕截图中,您可以看到 detachedTree 变量正在引用该节点。要解决这一特定的内存泄漏,您需要研究使用 detachedTree 的代码并确保在不需要时,此代码可以移除其对节点的引用。
发现频繁的垃圾回收
如果感觉页面经常暂停,则可能存在垃圾回收问题。
您可以使用 Chrome 任务管理器或者 Timeline 内存记录发现频繁的垃圾回收。 在任务管理器中,Memory 或 JavaScript Memory 值频繁上升和下降表示存在频繁的垃圾回收。在 Timeline 记录中,JS 堆或节点计数图表频繁上升和下降指示存在频繁的垃圾回收。
确定问题后,您可以使用分配时间线记录找出内存正在分配到什么地方,以及哪些函数导致分配。
快照可能需要一些时间处理和加载。完成后,请从左侧面板(名称为 HEAP SNAPSHOTS)中选择该快照。
在 Class filter 文本框中键入 Detached,搜索已分离的 DOM 树。
如何使用 Timeline 工具
Kayce Basques
By Kayce Basques
Technical Writer at Google
使用 Chrome DevTools 的 Timeline 面板可以记录和分析您的应用在运行时的所有活动。 这里是开始调查应用中可觉察性能问题的最佳位置。
Timeline 工具
TL;DR
执行 Timeline 记录,分析页面加载或用户交互后发生的每个事件。
在 Overview 窗格中查看 FPS、CPU 和网络请求。
点击火焰图中的事件以查看与其相关的详细信息。
放大显示一部分记录以简化分析。
Timeline 面板概览
Timeline 面板包含以下四个窗格:
Controls。开始记录,停止记录和配置记录期间捕获的信息。
Overview。 页面性能的高级汇总。更多内容请参见下文。
火焰图。 CPU 堆叠追踪的可视化。
您可以在火焰图上看到一到三条垂直的虚线。蓝线代表 DOMContentLoaded 事件。 绿线代表首次绘制的时间。 红线代表 load 事件。
Details。选择事件后,此窗格会显示与该事件有关的更多信息。 未选择事件时,此窗格会显示选定时间范围的相关信息。
带标注的 Timeline 面板
Overview 窗格
Overview 窗格包含以下三个图表:
FPS。每秒帧数。绿色竖线越高,FPS 越高。 FPS 图表上的红色块表示长时间帧,很可能会出现卡顿。
CPU。 CPU 资源。此面积图指示消耗 CPU 资源的事件类型。
NET。每条彩色横杠表示一种资源。横杠越长,检索资源所需的时间越长。 每个横杠的浅色部分表示等待时间(从请求资源到第一个字节下载完成的时间)。
深色部分表示传输时间(下载第一个和最后一个字节之间的时间)。
横杠按照以下方式进行彩色编码: HTML 文件为蓝色。 脚本为黄色。 样式表为紫色。 媒体文件为绿色。 其他资源为灰色。