违规长时间运行的 JavaScript 任务花费了 xx 毫秒

新手上路,请多包涵

最近,我收到了这样的警告,这是我第一次得到它:

[Violation] Long running JavaScript task took 234ms
[Violation] Forced reflow while executing JavaScript took 45ms

我正在做一个小组项目,我不知道这是从哪里来的。这以前从未发生过。突然,当其他人参与了该项目时,它出现了。如何找到导致此警告的文件/功能?我一直在寻找答案,但主要是关于如何解决它的解决方案。如果我什至找不到问题的根源,我就无法解决它。

在这种情况下,警告只会出现在 Chrome 上。我尝试使用 Edge,但没有收到任何类似的警告,而且我还没有在 Firefox 上测试过。

我什至从 jquery.min.js 得到错误:

[Violation] Handler took 231ms of runtime (50ms allowed)            jquery.min.js:2

原文由 procatmer 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 4.9k
2 个回答

更新:Chrome 58+ 默认隐藏这些和其他调试消息。要显示它们,请单击“信息”旁边的箭头并选择“详细”。

Chrome 57 默认开启“隐藏违规”。要重新打开它们,您需要启用过滤器并取消选中“隐藏违规”框。

当其他人参与该项目时,突然出现

我认为您更新到 Chrome 56 的可能性更大。在我看来,此警告是一个很棒的新功能,请仅在您绝望时将其关闭,并且您的评估员会从您那里拿走分数。其他浏览器中存在潜在问题,但浏览器并没有告诉您存在问题。 Chromium 票在 这里,但实际上并没有任何有趣的讨论。

这些消息是警告而不是错误,因为它不会真正导致重大问题。它可能会导致帧丢失或以其他方式导致不太流畅的体验。

但是,它们值得研究和修复以提高应用程序的质量。做到这一点的方法是注意消息出现的情况,并进行性能测试以缩小问题发生的范围。开始性能测试的最简单方法是插入如下代码:

 function someMethodIThinkMightBeSlow() {
 const startTime = performance.now();

 // Do the normal stuff for this function

 const duration = performance.now() - startTime;
 console.log(`someMethodIThinkMightBeSlow took ${duration}ms`);
 }

如果您想更高级,您还可以使用 Chrome 的分析器,或者使用像 这样 的基准测试库。

一旦你发现了一些需要很长时间的代码(50ms 是 Chrome 的阈值),你有几个选择:

  1. 删除一些/所有可能不必要的任务

  2. 弄清楚如何更快地完成相同的任务

  3. 将代码分成多个异步步骤

(1)和(2)可能很难或不可能,但有时真的很容易,应该是你的第一次尝试。如果需要,应该始终可以执行 (3)。为此,您将使用以下内容:

 setTimeout(functionToRunVerySoonButNotNow);

或者

// This one is not available natively in IE, but there are polyfills available.
 Promise.resolve().then(functionToRunVerySoonButNotNow);

您可以 在此处 阅读有关 JavaScript 异步特性的更多信息。

原文由 voltrevo 发布,翻译遵循 CC BY-SA 4.0 许可协议

正如大家提到的,这些只是警告。但是,如果您热衷于解决这些问题(您应该这样做),那么您需要首先确定导致警告的原因。没有任何一个原因会导致您收到强制回流警告。有人为一些可能的选项创建了一个 列表。您可以关注讨论以获取更多信息。

以下是可能原因的要点:

什么力量布局/回流

以下所有属性或方法,在 JavaScript 中请求/调用时,将触发浏览器同步计算样式和布局*。这也称为回流或 布局颠簸,是常见的性能瓶颈。

元素

盒子指标

  • elem.offsetLeft , elem.offsetTop , elem.offsetWidth , elem.offsetHeight , elem.offsetParent
  • elem.clientLeft , elem.clientTop , elem.clientWidth , elem.clientHeight
  • elem.getClientRects() , elem.getBoundingClientRect()

滚动的东西

  • elem.scrollBy() , elem.scrollTo()
  • elem.scrollIntoView() , elem.scrollIntoViewIfNeeded()
  • elem.scrollWidth , elem.scrollHeight
  • elem.scrollLeft , elem.scrollTop 同样,设置它们

重点

  • elem.focus() 可以触发 双重 强制布局( 来源

还…

  • elem.computedRole , elem.computedName
  • elem.innerText来源

getComputedStyle

window.getComputedStyle() 通常会强制样式重新计算( 来源

window.getComputedStyle() 如果满足以下任一条件,也将强制布局:

  1. 该元素在影子树中
  2. 有媒体查询(视口相关的)。 Specifically, one of the following: ( source ) \* min-width , min-height , max-width , max-height , width , height \* aspect-ratio , min-aspect-ratio , max-aspect-ratio
    • device-pixel-ratio , resolution , orientation
  3. 请求的属性是以下之一:( 来源
    • height , width \* top , right , bottom , left \* margin [ -top , -right , -bottom , -left , or shorthand ] only if the margin is fixed. * padding [ -top , -right , -bottom , -left , or shorthand ] only if the padding is fixed . * transform , transform-origin , perspective-origin \* translate , rotate , scale \* webkit-filter , backdrop-filter \* motion-path , motion-offset , motion-rotation \* x , y , rx , ry

窗户

  • window.scrollX , window.scrollY
  • window.innerHeight , window.innerWidth
  • window.getMatchedCSSRules() 仅力样式

形式

  • inputElem.focus()
  • inputElem.select() , textareaElem.select()来源

鼠标事件

  • mouseEvt.layerX mouseEvt.layerYmouseEvt.offsetX mouseEvt.offsetY

文档

  • doc.scrollingElement 仅强制风格

范围

  • range.getClientRects() , range.getBoundingClientRect()

SVG

内容可编辑

  • 很多东西,……包括将图像复制到剪贴板( 来源

在这里 检查更多。

此外,这是来自 原始问题 的 Chromium 源代码以及 关于警告的性能 API 的讨论


编辑: 还有一篇关于如何在 Google PageSpeed Insight 上最小化布局回流的文章。它解释了什么是浏览器回流:

Reflow 是 Web 浏览器进程的名称,用于重新计算文档中元素的位置和几何形状,以重新呈现部分或全部文档。由于回流是浏览器中的用户阻塞操作,因此对于开发人员了解如何提高回流时间以及了解各种文档属性(DOM 深度、CSS 规则效率、不同类型的样式更改)对回流的影响非常有用时间。有时重排文档中的单个元素可能需要重排其父元素及其后的任何元素。

此外,它还解释了如何最小化它:

  1. 减少不必要的 DOM 深度。 DOM 树中某一层的更改会导致树的每一层发生更改——一直到根,一直到修改节点的子节点。这导致花费更多时间执行回流。
  2. 最小化 CSS 规则,并删除未使用的 CSS 规则。
  3. 如果您进行复杂的渲染更改(例如动画),请在流程之外进行。使用绝对位置或固定位置来完成此操作。
  4. 避免不必要的复杂 CSS 选择器——尤其是后代选择器——这需要更多的 CPU 能力来进行选择器匹配。

原文由 0xC0DED00D 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题