最近,我收到了这样的警告,这是我第一次收到:
JavaScript任务长时间运行,耗时234ms
执行JavaScript时强制回流花了45毫秒
我正在做一个小组项目,我不知道这是从哪里来的。这在以前从未发生过。突然,当其他人参与到这个项目中时,它出现了。如何查找导致此警告的文件/函数?我一直在寻找答案,但主要是关于如何解决它的解决方案。如果我连问题的根源都找不到,我就解决不了。
在这种情况下,警告只出现在Chrome上。我尝试使用Edge,但没有收到任何类似的警告,而且我还没有在Firefox上测试它。
我甚至从jquery.min.js中得到错误:
[违规]Handler占用了231ms的运行时(允许50ms
我在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
});
插入这个恶作剧代码后,所有警告消息都消失了。
我在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
});
插入这个恶作剧代码后,所有警告消息都消失了。
我在我的代码中找到了这条消息的根,它搜索并隐藏或显示节点(脱机)。这是我的代码:
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个节点)。
在这里添加我的见解,因为这个帖子是关于这个主题的“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 />
//...