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

2020/09/30 20:01 · javascript ·  · 0评论

最近,我得到了这种警告,这是我第一次得到警告:

[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

更新:默认情况下,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的分析器,或使用像这样的基准测试库

找到花费很长时间的代码(Chrome的阈值为50ms)后,您可以选择以下两种方法:

  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的异步特性的更多信息

所有人都提到这些只是警告。但是,如果您想解决这些问题(应该这样做),则需要首先确定引起警告的原因。没有任何原因可以得到强制回流警告。有人为某些可能的选项创建了一个列表您可以按照讨论获取更多信息。

这是可能原因的要点:

是什么促使布局/回流

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

元件

盒子指标

  • elem.offsetLeftelem.offsetTopelem.offsetWidthelem.offsetHeightelem.offsetParent
  • elem.clientLeftelem.clientTopelem.clientWidthelem.clientHeight
  • elem.getClientRects()elem.getBoundingClientRect()

滚动的东西

  • elem.scrollBy()elem.scrollTo()
  • elem.scrollIntoView()elem.scrollIntoViewIfNeeded()
  • elem.scrollWidthelem.scrollHeight
  • elem.scrollLeftelem.scrollTop同时进行设置

焦点

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

也…

  • elem.computedRoleelem.computedName
  • elem.innerText来源

getComputedStyle

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

window.getComputedStyle() 如果以下任一情况成立,也会强制布局:

  1. 元素在阴影树中
  2. 有媒体查询(与视口有关的查询)。具体而言,执行以下操作之一:()* min-widthmin-heightmax-widthmax-heightwidthheight * aspect-ratiomin-aspect-ratiomax-aspect-ratio
    • device-pixel-ratioresolutionorientation
  3. 请求的属性是以下之一:(source

    • heightwidth * toprightbottomleft * margin[ -top-right-bottom-left,或速记]仅当余量是固定的。* padding[ -top-right-bottom-left,或速记]仅当填充是固定的。* transform
      transform-originperspective-origin * translaterotate
      scale * webkit-filterbackdrop-filter * motion-path
      motion-offsetmotion-rotation * xyrxry

窗口

  • window.scrollXwindow.scrollY
  • window.innerHeightwindow.innerWidth
  • window.getMatchedCSSRules() 唯力风格

形式

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

鼠标事件

  • mouseEvt.layerXmouseEvt.layerYmouseEvt.offsetXmouseEvt.offsetY

文件

  • doc.scrollingElement 唯力风格

范围

  • range.getClientRects()range.getBoundingClientRect()

SVG

内容可编辑

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

在这里查看更多

此外,这是原始发行版的Chromium源代码,以及有关警告的性能API讨论


编辑:还有一篇文章,介绍如何在Google的PageSpeed Insight上最大程度地减少布局重排它解释了什么是浏览器重排:

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

另外,它说明了如何最小化它:

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

一些想法:

  • 删除一半的代码(也许通过注释掉)。

    • 问题仍然存在吗?太好了,您已经缩小了可能性!重复。

    • 问题不在那里吗?好吧,看看您评论的一半!

  • 您是否在使用任何版本控制系统(例如Git)?如果是这样,git checkout您的一些最近的提交。问题何时引入?查看提交,以确切了解问题首次到达时更改了哪些代码。

为了确定问题的根源,请运行您的应用程序,并将其记录在Chrome的“性能”标签中

在那里,您可以检查花费很长时间才能运行的各种功能。就我而言,与控制台中的警告相关的是来自由AdBlock扩展程序加载的文件,但是在您的情况下,这可能是其他事情。

检查这些文件,并尝试确定这是扩展名还是您的扩展名。(如果是您的,那么您已找到问题的根源。)

我在我的代码中找到了此消息的根,该代码搜索并隐藏或显示了节点(脱机)。这是我的代码:

search.addEventListener('keyup', function() {
    for (const node of nodes)
        if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
            node.classList.remove('hidden');
        else
            node.classList.add('hidden');
});

性能选项卡(分析器)显示事件耗时约60毫秒:
铬性能分析器布局重新计算重排

现在:

search.addEventListener('keyup', function() {
    const nodesToHide = [];
    const nodesToShow = [];
    for (const node of nodes)
        if (node.innerText.toLowerCase().includes(this.value.toLowerCase()))
            nodesToShow.push(node);
        else
            nodesToHide.push(node);

    nodesToHide.forEach(node => node.classList.add('hidden'));
    nodesToShow.forEach(node => node.classList.remove('hidden'));
});

现在,“性能”选项卡(分析器)显示该事件大约需要1毫秒:
铬探伤剂暗

而且我认为搜索现在可以更快地进行(229个节点)。

在“网络”标签下的Chrome浏览器控制台中查找加载时间最长的脚本。

就我而言,我已经包含但尚未在应用程序中使用的一组Angular附加脚本:

<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-utils/0.1.1/angular-ui-utils.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-animate.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.9/angular-aria.min.js"></script>

这些是加载时间比指定的“长时间运行的任务”错误的时间更长的唯一JavaScript文件。

所有这些文件都在我的其他网站上运行,没有生成任何错误,但是我在几乎没有任何功能的新Web应用程序上遇到此“长时间运行的任务”错误。删除后,错误立即停止。

我最好的猜测是,这些Angular插件正在递归地查找DOM的越来越深的部分作为开​​始标签-没有找到它们,它们在退出前就必须遍历整个DOM,这比Chrome期望的时间更长-因此发出警告。

我在Apache Cordova源代码中找到了一个解决方案。他们这样实现:

var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve();
var nextTick = resolvedPromise ? function(fn) { resolvedPromise.then(fn); } : function(fn) { setTimeout(fn); };

实现简单,但方法明智。

在Android 4.4上,使用Promise对于较旧的浏览器,请使用setTimeout()


用法:

nextTick(function() {
  // your code
});

插入此技巧代码后,所有警告消息均消失。

尽管Chrome Chromium博客的此变更日志中没有它,但它已添加到Chrome 56 beta中:Chrome 56 Beta:“不安全”警告,Web蓝牙和CSSposition: sticky

您可以使用“隐藏违规”复选框将其隐藏在控制台的过滤器栏中

如果您使用的是Chrome Canary(或Beta),则只需选中“隐藏违规”选项即可。

在Chrome 56控制台中隐藏违规复选框

这是Google Chrome浏览器的违规错误,该错误会在Verbose启用日志记录级别时显示

错误消息示例:

警告的屏幕截图

说明:

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

原始文章:最小化浏览器重排 UX开发人员Lindsey Simon发表在developers.google.com上,以最大程度

这是链接谷歌Chrome提供了性能分析器,在布局轮廓(紫红色地区),关于警告的详细信息。

在此添加我的见解,因为该线程是该主题上的“转到” stackoverflow问题。

我的问题是在Material-UI应用程序中(早期)

  • 放置自定义主题提供程序的原因

当我进行一些计算以强制页面呈现时(一个组件,“显示结果”,取决于在其他组件(“输入部分”)中设置的内容)。

一切都很好,直到我更新了迫使“结果组件”重新呈现的“状态”。这里的主要问题是我在同一渲染器(App.js / return ..)中有一个material-ui主题(https://material-ui.com/customization/theming/#a-note-on-performance)。作为“结果组件”,SummaryAppBarPure

解决方案是将ThemeProvider提升一级(Index.js),并在此处包装App组件,从而不强制ThemeProvider重新计算和绘制/布局/重排。

之前

在App.js中:

  return (
    <>
      <MyThemeProvider>
      <Container className={classes.appMaxWidth}>

        <SummaryAppBarPure
//...

在index.js中

ReactDOM.render(
  <React.StrictMode>
      <App />
//...

在App.js中:

return (
    <>
      {/* move theme to index. made reflow problem go away */}
      {/* <MyThemeProvider> */}
      <Container className={classes.appMaxWidth}>

        <SummaryAppBarPure
//...

在index.js中

ReactDOM.render(
  <React.StrictMode>
    <MyThemeProvider>
      <App />
//...

对于它的价值,这是我遇到

[Violation] Forced reflow while executing JavaScript took <N>ms

警告。有问题的页面是根据用户内容生成的,因此我对DOM的大小影响不大。就我而言,问题是两列的表可能有数百行,甚至数千行。(尚未实现按需行加载,抱歉!)

使用jQuerykeydown页面上选择一组行并切换其可见性。我注意到toggle()在该集合上使用比使用hide()show()显式更容易触发警告

有关此特定性能方案的更多详细信息,另请参见本文

当您在执行结束之前多次调用一个函数时,通常会发生强制重排。

例如,您可能在智能手机上有问题,但在传统浏览器上却没有。

我建议使用asetTimeout解决问题。

这不是很重要,但是我重复一遍,问题是在多次调用一个函数时出现的,而不是在该函数花费超过50毫秒时出现的。我认为您的答案有误。

  1. 关闭1-by-1调用,然后重新加载代码以查看它是否仍然产生错误。
  2. 如果第二个脚本导致错误,请使用setTimeOut基于冲突持续时间的。

这不是错误,只是一条简单的消息。要执行此消息
请将


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">示例更改

<!DOCTYPE html>(Firefox源期望如此),


该消息显示在Google Chrome 74和Opera 60中。
更改后很明显,0为冗长。


解决方案

本文地址:http://javascript.askforanswer.com/weifanchangshijianyunxingdejavascriptrenwuhuafeilexxhaomiao.html
文章标签: ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!