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

JavaScript任务长时间运行,耗时234ms 执行JavaScript时强制回流花了45毫秒

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

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

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

[违规]Handler占用了231ms的运行时(允许50ms


当前回答

在这里添加我的见解,因为这个帖子是关于这个主题的“go to”stackoverflow问题。

我的问题是在一个材质ui应用程序(早期阶段)

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

当我做了一些计算强制渲染页面时 (其中一个组件“显示结果”取决于其他组件“输入部分”中设置的内容)。

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

其他回答

这不是一个错误,只是一个简单的消息。执行此消息更改 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">(示例) 来 <!DOCTYPE html>(Firefox源代码期望此) 该消息显示在谷歌Chrome 74和Opera 60。改变后它是清晰的,0 verbose。 解决方法

不管怎样,这是我在遇到

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

警告。所讨论的页面是由用户内容生成的,因此我对DOM的大小实际上没有多大影响。在我的例子中,问题是一个有两列的表,可能有数百甚至数千行。(没有按需行加载实现,对不起!)

使用jQuery,在按下键时,页面选择一组行并切换它们的可见性。我注意到,在该集合上使用toggle()比显式使用hide() & show()更容易触发警告。

有关此特定性能场景的更多详细信息,请参见本文。

这里有几个想法:

删除一半的代码(可能通过注释)。 问题还在吗?太好了,你缩小了可能性!重复。 问题不在那里吗?好吧,看看你评论掉的那一半! 你是否使用任何版本控制系统(例如Git)?如果是,git签出一些最近的提交。这个问题是什么时候提出的?查看提交,看看问题第一次出现时到底修改了哪些代码。

为了确定问题的根源,运行你的应用程序,并记录在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毫秒:

Now:

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个节点)。