Переход CSS в Chrome останавливается или дергается во время рендеринга изображения

Я работаю над сенсорной галереей изображений html5+css3. Целевыми устройствами являются в основном планшеты и другие мобильные устройства. Изображения достаточно большие (около 1000x1500), а галерея может содержать от 100 до 200 изображений. Галерея представляет собой карусель, и пользователь может проводить пальцем влево и вправо, чтобы перемещаться по галерее. Это работает так, что изображения размещаются в div (с именем #ribbon), который перемещается влево, когда вы проводите пальцем влево, таким образом перемещая следующее изображение в поле зрения.

<div id="carousel">
  <div id="ribbon">
    <div class="slide"><img src=""></div>
    <div class="slide"><img src=""></div>

Чтобы ограничить потребление полосы пропускания и время первоначальной загрузки, в html фактически вставляются только первые 10-15 контейнеров изображений. Когда вы проводите пальцем к центру карусели, первый контейнер изображения переходит в конец карусели, а новое изображение загружается по окончании анимации. В Safari и на iOS это работает как по маслу.

Я знаю лучше, чем трогать DOM без необходимости, особенно во время выполнения переходов CSS, и код должен быть в основном оптимальным в этом отношении. Но тем не менее, в Chrome (как на десктопе, так и на Android) происходит сбой в анимации каждый раз, когда устанавливается следующий src изображения. Я вижу это в инструментах разработчика, события, которые, по-видимому, вызывают икоту, - это изменение размера и рендеринг изображения.

Чтобы попытаться сделать анимацию более плавной, каждый раз, когда запускается событие перетаскивания, все изображения (кроме текущего, левого и правого) устанавливаются в белый пиксель GIF. Это также помогает, когда вы быстро пролистываете галерею, потому что пропускаете загрузку ненужных изображений.

Есть ли способ смягчить эту проблему?

пример jsFiddle

Упрощенный пример. Не уверен, что этого достаточно, чтобы продемонстрировать проблему, но я пытаюсь синхронизировать события смахивания, чтобы прервать декодирование и рендеринг изображения.

http://jsfiddle.net/YevMC/

Дополнительные примечания

  • Я попытался изменить размер изображения с помощью холста и установить для src изображения значение canvas.toDataUrl(), но, похоже, это не помогает. Может быть, мне стоит попробовать веб-воркеры?
  • Я уже использую 3D-преобразования.
  • Применяются все хаки CSS, translate3d, perspective: 1000 (что очень помогает в Chrome).
  • backface-visibility: hidden вызывает нежелательные побочные эффекты, например. показывает только часть изображения.
  • Включение 3D для самих элементов img помогает в Chrome, но пагубно влияет на производительность анимации в iOS. К счастью, есть объект window.chrome, который упрощает обнаружение хрома.

Хромовая шкала Chrome

Временная шкала Chrome показывает, что рисование изображения занимает около 200 мс


person Davorin    schedule 10.03.2013    source источник
comment
Не могли бы вы создать скрипку для этого?   -  person Stefan Fisk    schedule 10.03.2013
comment
Может быть, я мог бы сделать рабочий пример, чтобы продемонстрировать проблему. Это займет некоторое время.   -  person Davorin    schedule 10.03.2013


Ответы (1)


Попробуйте использовать requestAnimationFrame вместо setTimeout.

person Andy Davies    schedule 08.04.2013