2009-04-29 48 views
6

我有一些传统的JavaScript,冻结表的tfoot/thead,并让身体滚动,它工作正常,除非在IE8中它非常缓慢。在IE8中的clientWidth性能

我追溯到读取tfoot/thead中的单元格的clientWidth属性在ie6/7和FireFox 1.5-3大约需要3ms读取clientWidth属性...在IE8它接管当表格中的单元数量增加时,200ms或更长。

这是一个已知的错误吗?有什么解决办法吗?

回答

2

我无法找到任何文件,这是一个已知的错误。为了提高性能,为什么不缓存clientWidth属性并定期更新缓存?也就是说,如果你的代码是:

var someValue = someElement.clientWidth + somethingElse; 

修改成:

// Note the following 3 lines use prototype 
// To do this without prototype, create the function, 
// create a closure out of it, and have the function 
// repeatedly call itself using setTimeout() with a timeout of 1000 
// milliseconds (or more/less depending on performance you need) 
var updateCache = function() { 
    this. clientWidthCache = $('someElement').clientWidth; 
}; 
new PeriodicalExecuter(updateCache.bind(this),1); 

var someValue = this.clientWidthCache + somethingElse 
0

你的问题可能与其他的东西(而不仅是clientwidth调用):是你更新/调整anyhting在DOM同时调用这个函数?

您的浏览器可能是IE8上的busy doing reflow,从而使客户端宽度变慢?

0

IE 8有能力在IE版本之间切换,并且还有兼容模式。 您是否尝试切换到兼容模式?这有什么区别吗?

+0

是的切换到兼容模式使其性能更好,但是它破坏了我的用户界面的其他部分,因为它不像IE7那样渲染。希望有一个不涉及兼容性的解决方案,但它可能是唯一的选择。 – Element 2009-07-29 01:31:51

+0

我不是说这是你的情况的问题,但上次我有渲染IE7和IE8之间的差异,我发现我的代码特别是HTML/CSS有错误。兼容模式似乎解决了这个问题,但我并不想接受这一点。所以我可能会开始通过验证器来运行代码。谁知道,你可能错过了一些东西。 - 我做到了。 ;) – 2009-07-29 10:00:39

6

如果你还有兴趣,我已经解决了这个问题。解决方案非常复杂。基本上,你需要附加一个简单的宏达元素和缓存其clientWidth /高度。

简单的HTC看起来是这样的:

<component lightweight="true"> 
<script> 
window.clientWidth2[uniqueID]=clientWidth; 
window.clientHeight2[uniqueID]=clientHeight; 
</script> 
</component> 

你需要使用CSS来连接HTC:

.my-table td {behavior: url(simple.htc);} 

请记住,你只需要附加行为IE8!

您再使用一些JavaScript用于缓存值创建干将:

var WIDTH = "clientWidth", 
    HEIGHT = "clientHeight"; 

if (8 == document.documentMode) { 

    window.clientWidth2 = {}; 
    Object.defineProperty(Element.prototype, "clientWidth2", { 
    get: function() { 
     return window.clientWidth2[this.uniqueID] || this.clientWidth; 
    } 
    }); 

    window.clientHeight2 = {}; 
    Object.defineProperty(Element.prototype, "clientHeight2", { 
    get: function() { 
     return window.clientHeight2[this.uniqueID] || this.clientHeight; 
    } 
    }); 

    WIDTH = "clientWidth2"; 
    HEIGHT = "clientHeight2"; 
} 

请注意,我创建的常量宽度/高度。你应该使用这些来获得你的元素的宽度/高度:

var width = element[WIDTH]; 

它很复杂,但它的工作原理。我遇到同样的问题,访问clientWidth的速度非常慢。这很好地解决了这个问题。它仍然不像IE7那么快,但它又回到了可用状态。

0

虽然我发现读取宽度属性时性能也很差。而且很可能有。

但是,我发现在我们的应用程序中对性能的主要影响是附加到窗口的resize事件的函数本身不知何故导致另一个调整大小,从而导致级联效应,尽管不是无限循环。我意识到这一点,当我看到函数的调用次数在IE8中比在IE7中大得多(喜欢IE开发工具)。我认为原因在于元素上的一些活动,比如设置元素宽度,现在可能导致IE8中的重排,IE7中没有这样做。

我通过设置窗口的resize事件来修复它:resize =“return myfunction();”而不是只调整大小=“myfunction();”并确保我的函数返回false;

我意识到原来的问题是几个月大,但我想我会张贴我的调查结果,以防其他人受益。