执行单击+拖动鼠标操作时,Internet Explorer会冻结。如何检测原因?

时间:2011-10-18 12:12:43

标签: javascript performance internet-explorer profiling freeze

我正在开发一个用于创建简单图表的JavaScript应用程序,我在Internet Explorer(版本8)中遇到了一些性能问题。

该应用程序可用于在图表上绘制线条(见图片)。绘制线条有两个主要处理程序。 ONMOUSEUP事件获取用户的点击,表示用户想要在线上放置一个点并开始一个新的线段(线条由多个线段组成)。

ONMOUSEMOVE处理程序在绘制线条时为用户绘制一个淡出的段作为视觉帮助。

请参考这些图片以获取线条绘制过程的屏幕截图: http://imgur.com/TuueR http://i51.tinypic.com/fxjqf.jpg

如果用户点击鼠标(mousedown)但将其释放,而是开始拖动鼠标,IE会完全冻结。过了一段时间,它将解冻并继续照常进行。

另一方面,

Chrome可以很好地处理这个问题(当拖动操作正在进行时,MOUSEMOVE处理程序可以正常工作,并且只有在ONMOUSEUP事件触发后才会放置该点。

我的理论是资源管理器可能是单线程的,在这种情况下,他会选择MOUSEMOVE事件,但只有在ONMOUSEUP事件完成后执行它们(这意味着在拖动操作的持续时间内根本没有做任何事情),但是我不知道如何检查这是否属实,或者如何解决它。

我已经使用IE8内置的JS探查器进行了一些分析,并且两个处理程序都被称为通常的次数,没有任何函数被调用数千次会导致冻结。当IE被冻结时,分析器被冻结,并且在解冻之前不输出任何内容,之后结果看起来与没有冻结动作的结果相同。

编辑:以下是根据dynaTrace探查器工具的时间轴:http://i51.tinypic.com/348sxty.jpg

1 个答案:

答案 0 :(得分:0)

问题是更新DOM是一项非常昂贵的操作。现在,如果没有限制,mousemove事件会不断触发,如果你在每次触发的mousemove事件上更新DOM,旧的浏览器就无法跟上。

解决方案可能将mousemove事件限制至少200毫秒。这意味着只有在鼠标停止移动200毫秒后才会更新DOM,从而为浏览器提供一些时间来恢复。

这是你如何限制mousemove事件:

jQuery( "#element").bind( "mousemove", function(){
//Code to react to mousemove goes here
//Also add code here to check if the position has actually changed from last time,
//So you don't update the DOM for nothing
}.throttle( 200 ) );

油门方法所需的代码:

Function.prototype.throttle = function( delay ) {
var timeridto = 0, callback = this;

    function r(){
    var     args = Array.prototype.slice.call( arguments ),
        self = this;
        clearTimeout( timeridto );
        timeridto = setTimeout( function(){callback.apply( self, args ); }, delay );
    };

    r.cancel = function(){
     clearTimeout( timeridto );   
    }

    return r;
};

如果这不能解决问题,那么您可以使用html5 canvas或(excanvas用于IE)进行绘图操作。