diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/performance/css_javascript_animation_performance | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/web/performance/css_javascript_animation_performance')
-rw-r--r-- | files/ru/web/performance/css_javascript_animation_performance/index.html | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/files/ru/web/performance/css_javascript_animation_performance/index.html b/files/ru/web/performance/css_javascript_animation_performance/index.html new file mode 100644 index 0000000000..264fc1ea9b --- /dev/null +++ b/files/ru/web/performance/css_javascript_animation_performance/index.html @@ -0,0 +1,80 @@ +--- +title: Производительность CSS и JavaScript анимации +slug: Web/Performance/CSS_JavaScript_animation_performance +tags: + - CSS + - FPS + - Transitions + - requestAnimationFrame + - Анимация + - Производительность +translation_of: Web/Performance/CSS_JavaScript_animation_performance +--- +<p class="summary">Анимация является критичным инструментов для улучшения пользовательнского опыта во многих приложениях. Существует много путей создания анимации в web, например, основанные на CSS-свойствах {{cssxref("transition","transitions")}}/{{cssxref("animation","animations")}} или на JavaScript (using {{domxref("Window.requestAnimationFrame","requestAnimationFrame()")}}). В этой статье мы проанализируем производительность CSS и JavaScript анимаций и сравним их.</p> + +<h2 id="CSS_transition_и_animation">CSS transition и animation</h2> + +<p>Оба этих свойства могут использоваться для создания анимации. Каждое из них имеет своё специфичное назначение:</p> + +<ul> + <li>CSS {{cssxref("transition","transitions")}} предоставляет простой способ создать анимацию, которая происходит при переходе от текущего состояния к конечному, например, переход от обычной кнопки к кнопке в состоянии hover. Даже если элемент в середине перехода от одного стиля к другому, новый эффект transition стартует немедленно, вместо того, чтобы дожидаться, пока запущенный ранее эффект завершится. Подробнее здесь: <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions">Использование CSS transitions</a>.</li> + <li>CSS {{cssxref("animation","animations")}}, с другой стороны, позволяет разработчикам создавать анимацию, основанную на ключевых кадрах (keyframes), которые указывают этапы, которые должна пройти анимация от начального до финального состояния. CSS animation состоит из двух компонент: описание свойства, которое указывает на анимацию, а так же набор ключевых кадров, которые указывают начальное, финальное и промежуточные состояния элемента. Подробнее здесь: <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_animations">Использование CSS animations</a>.</li> +</ul> + +<p>Если говорить о производительности - между этими двумя подходами нет разницы. Оба подхода основаны на одном и том же механизме, которые описаны далее.</p> + +<h2 id="requestAnimationFrame">requestAnimationFrame</h2> + +<p>API {{domxref("Window.requestAnimationFrame","requestAnimationFrame()")}} предоставляет эффективный способ создания анимаций в JavaScript. Функция (callback), которую вы передаете в этот метод, будет вызываться перед каждой следующей отрисовкой нового фрейма. Главное отличие от {{domxref("WindowTimers.setTimeout","setTimeout()")}}/{{domxref("WindowTimers.setInterval","setInterval()")}} в том, что здесь вам не нужно указывать время, через которое функция запустится. <code>requestAnimationFrame()</code> работает гораздо эффективнее, учитывая частоту кадров и производительность системы. Разработчики могут создавать анимацию, просто изменяя стили элемента каждый раз, когда происходит подготовка нового кадра (или когда обновляется полотно Canvas или в других случаях).</p> + +<div class="note"> +<p><strong>Заметка</strong>: Подобно CSS transition и animation, <code>requestAnimationFrame()</code> приостанавливает работу, когда текущий таб переводится в фоновый режим (например, при смене фокуса)</p> +</div> + +<p>Для подробностей ознакомьтесь с <a href="https://hacks.mozilla.org/2011/08/animating-with-javascript-from-setinterval-to-requestanimationframe/">анимирование с JavaScript: от setinterval до requestAnimationFrame</a>.</p> + +<h2 id="Сравнение_производительности_transitions_и_requestAnimationFrame">Сравнение производительности:<br> + transitions и requestAnimationFrame</h2> + +<p>По факту, в большинстве случаев, производительность анимаций CSS практически идентична анимациям на JavaScript. По крайней мере в Firefox. Авторы некоторых JavaScript библиотек для анимации, например GSAP или Velocity.JS, даже берутся утверждать, что их решения могут работать быстрее, чем аналогичные решения на CSS. Такое возможно, потому что CSS transitions/animations просто заново вычисляют стили элементов в основном потоке процессора сразу перед тем, как срабатывает событие repaint, что примерно то же самое, что вычислять стили заново с помощью <code>requestAnimationFrame()</code>. Если обе анимации выполняются в одном потоке, то разницы в производительности не будет.</p> + +<p>В следующей секции мы пройдемся по тестам производительности, используя Firefox, чтобы увидеть, какие методы анимации работают эффективнее.</p> + +<h3 id="Включение_измерения_частоты_кадров_FPS">Включение измерения частоты кадров FPS</h3> + +<p>Для начала нам нужно включить инструменты измерения частоты кадров (FPS Tools), чтобы иметь возможность видеть текущую частоту кадров</p> + +<ol> + <li>В поле ввода URL наберите <em>about:config</em>; Нажмите на кнопку <em>I’ll be careful, I promise!, чтобы войти на страницу конфигурации</em>.<br> + <img alt="" src="https://mdn.mozillademos.org/files/11137/Pic1.png" style="height: 349px; width: 600px;"><br> + </li> + <li>В поле поиска введите <code>layers.acceleration.draw-fps</code>.</li> + <li>Нажмите два раза на ячейку, чтобы присвоить значение <code>true</code>. Теперь вы видите три розовых блока в верхнем левом углу окна. Первый блок указывает FPS.<br> + <img alt="" src="https://mdn.mozillademos.org/files/11139/Pic2.png" style="height: 215px; width: 562px;"></li> +</ol> + +<h3 id="Запуск_теста">Запуск теста</h3> + +<p>Для начала, в нашем тесте мы будем анимаировать 1000 элементов {{htmlelement("div")}} с помощью CSS.</p> + +<p><span style="line-height: 16.7999992370605px;">{{JSFiddleEmbed("https://jsfiddle.net/zt94oew2/1/","","480")}}</span></p> + +<p>Нажав на кнопку, вы можете переключить метод анимации на <code>requestAnimationFrame()</code>.</p> + +<p>Попробуйте запустить оба метода и сравнить FPS. Скорее всего, вы увидите, что частота кадров отличается - анимации с CSS заметно быстрее. В следующей главе мы разберём - почему.</p> + +<h3 id="Анимация_вне_основного_потока_процесса">Анимация вне основного потока процесса</h3> + +<p>Браузерный JavaScript является строго однопоточным языком, то есть он не может одновременно работать над двумя задачами. В этом кроется проблема анимации с помощью JavaScript. Выполняя такую анимацию, вы занимаете процессор, который мог бы в это время заниматься другими функциями. В противоположность этому, CSS анимации могут быть выделены в отдельный поток, то есть при выполнении таких анимаций браузер не блокирует выполнение других процессов. </p> + +<p>Для того, чтобы выделить анимацию CSS в отдельный процесс, нам нужно убедиться, что изменяемые свойства не запускают этапы reflow/repaint (подробнее здесь: <a href="http://csstriggers.com/">CSS triggers</a>). Если изменяемые CSS свойства не делают этого, то мы можем вынести операции по вычислению стилей в отдельный поток. Наиболее известное свойство - это CSS Transform, которое выводит элемент в отдельный <a href="https://wiki.mozilla.org/Gecko:Overview#Graphics">слой</a>. Если элемент представляет из себя отдельный слой, то вычисление каждого следующего кадра может быть сделано на графическом процессоре (GPU). Это радикально улучшает производительность, особенно на мобильных устройства. Подробности здесь: <a href="https://wiki.mozilla.org/Platform/GFX/OffMainThreadCompositing">OffMainThreadCompositing</a>.</p> + +<p>Вы можете отключить выведение анимации в отдельный поток, чтобы посмотреть, как эта особенность влияет на FPS. Для этого в настройках Firefox найдите флаг <code>layers.offmainthreadcomposition.async-animations</code>. И переключите его в <code>false</code>.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/11141/Pic3.png" style="height: 210px; width: 536px;"></p> + +<p>После выключения этой опции вы увидите, что FPS при использовании CSS стал таким же, как и при использовании JS.</p> + +<h2 id="Итог">Итог</h2> + +<p>Браузеры способы оптимизировать рендеринг не только программно, но и аппаратно. В целом, вам нужно стараться использовать CSS transitions/animations везде, где это возможно. Если же ваши анимации действительно сложны - помните, что писать анимацию на JavaScript нужно только с использованием <code>requestAnimationFrame()</code> .</p> |