为什么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(); 为一个大块。 为我工作得很好。 这是愚蠢的,但这是真的。