We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

这篇翻译不完整。请帮忙从英语翻译这篇文章

 

通过瀑布,您可以了解浏览器在运行网站或应用程序时所做的各种事情。它的基础是浏览器在运行网站时所做的事情可以分为各种类型 - 运行JavaScript,更新布局等等 - 而且在任何时候,浏览器都在做这些事情之一。

因此,如果您看到性能问题的迹象 - 例如帧速下降,您可以前往瀑布查看浏览器在录制过程中正在进行的操作。

 

 

沿着X轴是时间。记录的操作(称为标记)显示为水平条,以瀑布形式显示,以反映浏览器执行的连续性。

选择标记后,您会在右侧的侧边栏中看到更多关于它的信息。这包括标记的持续时间以及特定于标记类型的更多信息

标记

操作标记用颜色标记和标记。记录下列操作:

名称和说明 颜色 详细资料

DOM事件

为响应DOM事件而执行的JavaScript代码。

事件类型
例如,“点击”或“消息”。
活动阶段
例如,“目标”或“捕获”。

在页面中执行的JavaScript函数标有该函数被调用的原因:

脚本标记
setInterval
setTimeout
requestAnimationFrame
Promise回调
Promise Init
Worker
JavaScript URI
事件处理程序

调用堆栈,并链接到函数。

解析HTML

花费时间解析页面的HTML。

调用堆栈,并链接到函数。

解析XML

花费时间解析页面的XML。

调用堆栈,并链接到函数。

重新计算样式

计算适用于页面元素的计算样式。

Restyle提示
指示需要什么样的重新列表的字符串。提示可能是以下任何一种:
自子

LaterSiblings
CSSTransitions
CSSAnimations
SVGAttrAnimations
StyleAttribute
StyleAttribute_Animations
Force
ForceDescendants

布局

计算页面元素的位置和大小。该操作有时称为“回流”。

 

涂料

将像素绘制到屏幕上。

 

垃圾收集

垃圾收集事件非增量GC事件标记为“(非增量)”。

原因
表示GC执行原因的字符串。
非增量原因
如果GC事件是非增量的,则该字符串指示执行非增量GC的原因。

Firefox 46中的新增功能:如果GC事件是由分配压力引起的,则会显示一个链接,标记为“显示分配触发器”。点击链接可查看导致此GC事件的分配配置文件。

有关更多详细信息,请参阅分配和垃圾收集

周期收集

回收C ++引用计数的数据结构。

像垃圾收集一样,但是用于C ++对象。请参阅Kyle Huey关于周期收集的博客文章

类型
始终“收集”。

CC图减少

循环收集的准备/预优化。

类型
总是“忘记滑雪”。

安慰

匹配console.time()之间的时间间隔console.timeEnd()

计时器名称
参数传递给console函数。
在开始堆叠
调用堆栈console.time(),并链接到函数。
在最后堆叠
(Firefox 41中的新功能)。在堆栈调用堆栈console.timeEnd()如果这在a的回调中Promise,这也会显示“异步堆栈”

时间戳

console.timeStamp()

标签
该论据传递给timeStamp()

DOMContentLoaded

文档的DOMContentLoaded事件。

 

加载

文档的load事件。

 

主线程中的工作者事件

主线程向工作人员发送消息或从工作人员接收消息时显示。

之一:

在主线程上序列化数据
主线程正在序列化要发送给工作人员的消息。
反序列化主线程中的数据
主线程反序列化从工作人员收到的消息。

工作者线程中的工人事件

当工作人员从主线程收到消息或向主线程发送消息时显示。

之一:

在Worker中序列化数据
工作人员正在序列化要发送到主线程的消息。
在Worker中反序列化数据
工作人员正在反序列化从主线程收到的消息。

瀑布工具中的标记及其颜色与瀑布概述中的相同,因此可以很容易地从一个到另一个进行关联。

过滤标记

您可以使用工具栏中的按钮控制显示哪些标记

瀑布模式

您在瀑布中看到的内容完全取决于您的网站所做的事情:JavaScript网站会有很多橙色,而视觉动态网站会有很多紫色和绿色。但有一些常见的模式可以提醒您可能出现的性能问题。

渲染瀑布

您在瀑布视图中经常会看到的一种模式如下所示:

这是浏览器用于响应某些事件更新页面的基本算法的可视化:

  1. JavaScript函数调用:某些事件(例如DOM事件)会导致页面中的某些JavaScript运行。JavaScript改变了页面的一些DOM或CSSOM。
  2. 重新计算样式:如果浏览器认为页面元素的计算样式已更改,则必须重新计算它们。
  3. 布局:接下来,浏览器使用计算的样式来确定元素的位置和几何形状。此操作被标记为“布局”,但有时也称为“回流”。
  4. Paint:最后,浏览器需要重新绘制元素到屏幕上。最后一步不是按照这个顺序显示的:页面可以分成多个图层,这些图层被独立绘制,然后在称为“构图”的过程中合并。

该顺序需要适合一个框架,因为屏幕在完成之前不会更新。人们普遍接受每秒60帧是动画显示平滑的速率。对于每秒60帧的速率,浏览器会以16.7毫秒的时间执行完整的流程。

重要的是对于响应能力,浏览器​​并不总是要经过每一步:

  • CSS动画更新页面,而无需运行任何JavaScript。
  • 并非所有的CSS属性更改都会导致重排。改变,可以改变对象的几何形状和位置,性质,例如widthdisplayfont-size,或top,将引起回流。但是,改变不改变几何或位置的属性,例如coloropacity不会。
  • 并非所有CSS属性更改都会导致重新绘制。特别是,如果使用该transform属性为元素设置动画效果,则浏览器将为已转换的元素使用单独的图层,并且在元素移动时甚至不必重绘:元素的新位置在构图中处理。

动画效果的CSS属性介绍了如何动画不同的CSS属性可以给不同的绩效结果,与瀑布如何能够帮助发出信号。

阻止JavaScript

默认情况下,站点的JavaScript在与浏览器用于布局更新,重绘,DOM事件等相同的线程中执行。这意味着长时间运行的JavaScript函数可能会导致无响应(无效):动画可能不平滑,或者该网站甚至可能会冻结。

同时使用帧速率工具和瀑布,很容易看到长时间运行的JavaScript引起响应问题的时间。在下面的屏幕截图中,我们放大了导致帧频下降的JS函数:

密集的JavaScript文章显示了瀑布如何突出造成长期的JavaScript函数响应的问题,以及如何使用异步方法来保持主线程响应。

昂贵的油漆

某些绘画效果(例如box-shadow)可能很昂贵,尤其是在浏览器必须在每一帧中计算它们的过渡中应用它们时。如果您看到帧频下降,尤其是在图形密集型操作和转换期间,请检查瀑布是否有长绿色标记。

垃圾收集

瀑布中的红色标记表示垃圾收集(GC)事件,其中SpiderMonkey(Firefox中的JavaScript引擎)遍历堆寻找不再可及的内存并随后释放它。GC与性能相关,因为它在运行时必须暂停JavaScript引擎,以便程序暂停并且完全无响应。

为了减少暂停的时间,SpiderMonkey实现了增量GC:这意味着它可以以相当小的增量执行垃圾收集,让程序在两者之间运行。但有时候,它需要执行完整的非增量收集,程序必须等待它完成。

在试图避免GC事件,尤其是非增量GC事件时,明智的做法是不尝试针对JavaScript引擎的特定实现进行优化。SpiderMonkey使用一套复杂的启发式方法来确定何时需要GC,何时需要非增量GC。一般来说,虽然:

  • GC在分配大量内存时需要
  • 当内存分配速率足够高以至于SpiderMonkey在增量GC期间可能会耗尽内存时,通常需要非增量GC

当瀑布记录GC标记时,它表示:

  • GC是否是增量式的
  • GC执行的原因
  • 如果GC是非递增的,则它是非递增的原因
  • 从Firefox 46开始,如果GC事件是由分配压力引起的,则会显示一个链接,标记为“显示分配触发器”。点击链接可查看导致此GC事件的分配配置文件。有关更多详细信息,请参阅分配和垃圾收集

使用控制台API添加标记

两个标记直接由控制台API调用控制:“控制台”和“时间戳”。

控制台标记

这些使您可以标记录制的特定部分。

要制作控制台标记,请console.time()在该部分的开始console.timeEnd()处以及结尾处调用这些函数带有一个用于命名该部分的参数。

例如,假设我们有这样的代码:

 

var iterations = 70;
var multiplier = 1000000000;

function calculatePrimes() {

  console.time("calculating...");

  var primes = [];
  for (var i = 0; i < iterations; i++) {
    var candidate = i * (multiplier * Math.random());
    var isPrime = true;
    for (var c = 2; c <= Math.sqrt(candidate); ++c) {
      if (candidate % c === 0) {
          // not prime
          isPrime = false;
          break;
       }
    }
    if (isPrime) {
      primes.push(candidate);
    }
  }

  console.timeEnd("calculating...");

  return primes;
}

 

瀑布的输出将如下所示:

标记用您传递给的参数console.time()进行标记,当您选择标记时,可以在右侧边栏中看到程序堆栈。

异步堆栈

Firefox中的新功能41。

从Firefox 41开始,右侧侧边栏也会在期末显示堆栈:即在该点console.timeEnd()被调用。如果console.timeEnd()从a的解析中被调用Promise,它也会显示“(Async:Promise)”​​,在这个下面它将显示“异步堆栈”:也就是说,在承诺的地方调用堆栈。

例如,考虑这样的代码:

var timerButton = document.getElementById("timer");
timerButton.addEventListener("click", handleClick, false);

function handleClick() {
  console.time("timer");
  runTimer(1000).then(timerFinished);
}

function timerFinished() {
  console.timeEnd("timer");
  console.log("ready!");
}

function runTimer(t) {
  return new Promise(function(resolve) {
    setTimeout(resolve, t);
  });
}

瀑布将显示一个标志物之间的期间time()timeEnd(),如果你选择它,你会看到侧边栏的异步栈:

时间戳记标记

时间戳使您可以在录制中标记一个瞬间。

要制作时间戳记标记,请致电console.timeStamp()您可以传递参数来标记时间戳。

例如,假设我们调整上面的代码以每循环10次迭代一次时间戳,并用迭代号标记:

var iterations = 70;
var multiplier = 1000000000;

function calculatePrimes() {
  console.time("calculating...");

  var primes = [];
  for (var i = 0; i < iterations; i++) {

    if (i % 10 == 0) {
      console.timeStamp(i.toString());
    }
    
    var candidate = i * (multiplier * Math.random());
    var isPrime = true;
    for (var c = 2; c <= Math.sqrt(candidate); ++c) {
      if (candidate % c === 0) {
          // not prime
          isPrime = false;
          break;
       }
    }
    if (isPrime) {
      primes.push(candidate);
    }
  }
  console.timeEnd("calculating...");
  return primes;
}

在瀑布现在你会看到这样的东西:

 

文档标签和贡献者

此页面的贡献者: daaain
最后编辑者: daaain,