Internet Explorer зависает, когда выполняется действие мыши с щелчком мыши. Как определить причину этого? - PullRequest
0 голосов
/ 18 октября 2011

Я работаю над приложением JavaScript для создания простых диаграмм, и у меня есть некоторые проблемы с производительностью в Internet Explorer (версия 8).

Приложение может использоваться для рисования линий на диаграмме (см. Рисунок),Есть два основных обработчика для рисования линии.Событие ONMOUSEUP собирает щелчки пользователя, которые указывают на то, что пользователь хочет разместить точку на линии и начать новый сегмент (строки состоят из нескольких сегментов).

Обработчик ONMOUSEMOVE рисует затемненный сегмент каквизуальная помощь пользователю, когда он рисует линию.

Пожалуйста, обратитесь к этим изображениям для скриншота процесса рисования линии: http://imgur.com/TuueR http://i51.tinypic.com/fxjqf.jpg

Если пользователь щелкает мышью(mousedown), но не освобождает его и вместо этого начинает перетаскивать мышь, IE полностью зависает.Через некоторое время он разморозится и продолжит работу как обычно.

С другой стороны, Chrome отлично справляется с этим (во время операции перетаскивания обработчик MOUSEMOVE выполняет свою работу, и точка помещается только послесобытие ONMOUSEUP срабатывает.

Моя теория состоит в том, что Explorer может быть однопоточным, в этом случае он получает события MOUSEMOVE, но выполняет их только после завершения события ONMOUSEUP (что означает, что по существу ничего не делается длядлительность операции перетаскивания), но я не знаю, как проверить, верно ли это, или как это исправить.

Я провел некоторое профилирование с помощью встроенного в IE8 профилировщика JS и обоих обработчиков.Вызываются обычное количество раз, нет функций, вызываемых тысячи раз, которые могли бы вызвать зависание. Профилировщик заморожен, а IE заморожен и ничего не выводит, пока не разморозится, после чего результаты выглядят так же, как если бы не былодействие замораживания.

РЕДАКТИРОВАТЬ: Вот график временидля инструмента профилирования dynaTrace: http://i51.tinypic.com/348sxty.jpg.

1 Ответ

0 голосов
/ 18 октября 2011

Проблема в том, что обновление DOM является очень дорогой операцией. Теперь событие mousemove запускается постоянно, если не регулируется, и старые браузеры просто не успевают за ним, если вы обновляете DOM при каждом запущенном событии mousemove.

Решение может задушить событие перемещения мыши по крайней мере на 200 миллисекунд. Это означает, что вы будете обновлять DOM только после того, как мышь перестанет двигаться в течение 200 миллисекунд, что даст браузеру некоторое время для восстановления.

Вот как вы бы подавили событие 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) для операций рисования.

...