Chrome / V8 замедляет onmousemove() над определенными элементами

#javascript #jquery #google-chrome #drag-and-drop #lag

#javascript #jquery #google-chrome #перетаскивание #задержка

Вопрос:

Я разрабатываю музыкальный проигрыватель на основе jQuery, который имеет длинный список элементов в главном разделе (неупорядоченный список, с элементами <div> в каждом <li>, для получения информации об исполнителе, альбоме и названии).

Вы можете получить доступ к его временной общедоступной версии здесь: http://music.sixteennet.co.uk/?anonymous

(Все песни являются недействительными ссылками в общедоступной версии, поэтому не беспокойтесь о воспроизведении: P)

Во-первых, краткое описание того, что именно это такое:

Слева находится боковая панель, отображающая список предстоящих песен. Пользователь выбирает песни в главном списке (щелчок, щелчок shift, щелчок ctrl, вы знаете, как это делается) после поиска / щелчка исполнителей и добавляет их в список воспроизведения слева, либо нажимая, либо перетаскивая. У меня все это работает (этот вопрос не касается того, как создать пользовательский интерфейс Javascript).

Проблема: $(window).mousemove() , .mouseup() и .mousedown() содержат функции для отображения окна высотой в пикселях (16 * количество выбранных песен в главном списке) [каждая <li> имеет высоту 16 пикселей]. При перемещении мыши это поле перемещается вместе с ним, пока при наведении курсора мыши на список воспроизведения список воспроизведения не изменит цвет, и если пользователь решит нажать mouseup() (отменить щелчок), выбранные песни будут добавлены в список воспроизведения.

Единственное, когда мышь перемещается с отображаемым в данный момент полем выбранных песен, в Google Chrome движение окна невероятно замедляется, но только когда мышь находится над основным списком песен (однако загрузка процессора остается на уровне 100% в течение всего времени отображения окна).). В Firefox 6 и IE 9 движение происходит плавно, а загрузка процессора не составляет 100% (даже на Athlon 64 3500 ). Этот тест был повторен (мной) на двух компьютерах, один из которых работает под управлением Windows 7, а другой — под управлением Ubuntu Linux.

Я очень подозреваю, что это ошибка в Google Chrome, но если у кого-нибудь хватит доброй воли просмотреть исходный код и сказать мне, в чем проблема (если она есть)…ты для меня Бог 🙂

РЕДАКТИРОВАТЬ: причина, по которой я сказал Chrome / V8, заключается в том, что Safari, использующий тот же движок рендеринга (WebKit), не имеет этой проблемы (хотя она не такая гладкая, как Firefox / IE9 / Opera)

Ответ №1:

Я собираюсь ответить на свой собственный вопрос, поскольку я нашел решение:

Запуск этой функции jQuery в окне исправил проблему с задержкой:

 $.fn.disableSelection = function() {
  return this.each(function() {
    $(this).attr('unselectable', 'on')
    .css({
      '-moz-user-select':'none',
      '-webkit-user-select':'none',
      'user-select':'none',
      '::selection':'none',
    })
    .each(function() {
      this.onselectstart = function() { return false; };
    });
  });
};
 

Ответ №2:

Я не вижу никаких задержек в моем компьютере…

В любом случае, возможно, вы можете попробовать уменьшить частоту, с которой может вызываться ваш обработчик событий, используя что-то вроде функции дроссельной заслонки подчеркивания

Комментарии:

1. О, подождите, это потому, что при анонимном входе в систему в браузерах почти нет исполнителей и альбомов. Задержка как-то связана с большим размером DOM. В любом случае, я попробую то, что вы сказали. Спасибо 🙂

2. Хм … спасибо за предложение, но оно не сработало. Хотя эта библиотека подчеркивания выглядит довольно круто, и вы заставили меня реорганизовать мои функции $ (window) в приятный объект JS: D

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

4. Ну, целевым элементом события являются jQuery()’d и parents()’d, чтобы увидеть, должна ли «гореть» боковая панель (т. е. если курсор находится над боковой панелью). Однако, даже если я закомментирую весь этот раздел, Chrome все равно сделает то же самое.