为什么Chrome在隐藏大型Knockout元素时使用更多的CPU?
我有一个使用Knockout.js 2.2.1的单页web应用程序来显示来自服务器的信息stream(使用socket.io,尽pipe我不这么认为)。 这个应用程序还包含一个大型的数据表,它是使用Knockout的foreach
绑定从一个JSON对象创build的。 (桌子很大,但不是很大:20列,200列左右。)
由于表格很大,用户可以通过点击button来打开/closures表格。 数据<table>
被放置在一个<div>
元素中,我可以使用jQuery的.show()
和.show()
方法隐藏/显示(基本上通过设置和清除<div>
上的CSS display: none
)。
所有这些function的作品。 不过,我注意到,在closures(隐藏)大数据表之后,如果Knockout生成的表足够大,Chrome的CPU使用率将跳转至100%。 更有趣的是, 这只发生在用户点击包含表格的<div>
元素内的某个地方之后。 当表被隐藏(并且CPU使用率高)时,单击页面上的其他位置将使CPU使用率恢复正常。 这个过程将会重复。
另一个可能有用的注意事项:如果我停止从服务器的stream数据,这个问题不会发生(或者,CPU使用率不明显)。 在此页面上有一个Knockout视图模型,它pipe理来自服务器的stream式数据以及从JSON对象创build此数据表。 这两组数据在其他方面是完全分开的 – 没有任何更改的数据显示在表中,并且表中不包含事件绑定回到视图模型。 就好像Knockout模型的stream式数据更新正在导致数据表上的工作,即使没有stream数据被绑定到表上。 而且只有当表格不显示时才这样做!
快速总结:
- Web应用程序在加载页面时使用Knockout来呈现大型数据表。
- 这个表在
$(document).ready
中启动时隐藏了.show()
,但是在点击一个button之后使用.show()
显示,并且可以再次隐藏 - 如果鼠标在数据表内部被点击,则表格被隐藏后,Chrome中的CPU使用率将跳至100%。
- 单击页面上的任何其他内容都会使CPU使用恢复正常。
其他相关信息:
- Chrome浏览器JavaScript分析器显示CPU使用率高,但它被简单地分类为(程序)时间。
- Windows上的IE10和Firefox 20都没有显示这个问题。
任何想法这里发生了什么事情,或build议更多的疑难解答?
的jsfiddle:
示例: http : //jsfiddle.net/CTYMv/6/
加载小提琴后查看CPU使用情况,应该是低的。 点击“Show Table”,然后点击popup的div内的某个地方(灰色背景)。 然后点击“隐藏表” – CPU使用率将显着增加。 然后点击其他任何地方(白色背景),CPU将恢复正常。
我认为我们现在可以认为这是webkit引擎中的一个bug。 这个错误只出现在使用CSS属性display:none;
。 这是由于使用webkit的GPU如何渲染隐藏的元素? 那么,我仍然不知道…
看DEMO
这是我可以想到的最简单的解决方法,这不应该干扰你的任何其他代码:{eg knockout observable}
CSS:{按照Brandon的build议添加指针事件}
.hidden{opacity:0;pointer-events:none} //don't use display:none here
JS:
//don't use hide/show jq methods as internally it set display none (fadeOut() methods too) $('#btn_show').click(function(){ $('#bigdatadiv').removeClass('hidden'); }); $('#btn_hide').on('click',function(){ $('#bigdatadiv').addClass('hidden') });
我知道这只是一个解决方法,仍然不能回答你的问题:为什么发生这种情况?
Thankyou为这个线程; 你会认为这个bug在2年后会被修复。
window.getSelection()。removeAllRanges()解决了我的事情,是最简单的适合我的代码。
在window.getSelection().removeAllRanges()
之前使用window.getSelection().removeAllRanges()
.hide();
为一个大块。 为我工作得很好。 这是愚蠢的,但这是真的。