Аппаратное ускорение анимации

Автор: Евгений Рыжков Дата публикации: 16.01.2012

Проблема

Рендеринг страницы браузер предоставляет процессору. Если мы на странице делаем простую анимацию (например, пермещаем <div> из точки А в точку Б) это тоже выполняет процессор. Выполнение подобной работы процессором не лучшим образом сказывается на производительности. В качестве примера плавная смена изображения с помощью opacity:

img {
	position: fixed;
	top: 110px;
	left: 0;
}
#img2 {
	opacity: 0;
}
[...]
$("#hoverPanel").hover (
function(){
	$("#img2").fadeTo(1000, 1);
},
function()
{
	$("#img2").fadeTo(1000, 0);
	
});	
[...]
<div id="hoverPanel">Наведи на меня</div>
<img src="img/back-color.jpg" width="100%" alt="" />
<img src="img/back.png" width="100%" alt="" id="img2" />

посмотреть в живую. На этот пример стоит взглянуть в Safari: у меня досточно современный CPU (4-х ядерный Pentium), а анимация изрядно тормозит.

Решение

Современные браузеры решили подключить видеоадаптер для обработки некоторых CSS анимаций. Используя CSS анимации вместо обычного Javascript получаем ощутимый прирост производительности. Предыдущий пример, но уже используя аппартное ускорение:

img {
	position: fixed;
	top: 110px;
	left: 0;
}
#img2 {
	opacity: 0;
}
@-webkit-keyframes fadeIn {
  0%   { -webkit-transform: none; opacity:0; }
  100% { -webkit-transform: none; opacity:1; }
}
@-webkit-keyframes fadeOut {
  0%   { -webkit-transform: none; opacity:1; }
  100% { -webkit-transform: none; opacity:0; }
}
@-moz-keyframes fadeIn {
  0%   { -moz-transform: none; opacity:0; }
  100% { -moz-transform: none; opacity:1; }
}
@-moz-keyframes fadeOut {
  0%   { -moz-transform: none; opacity:1; }
  100% { -moz-transform: none; opacity:0; }
}
[...]
$(document).ready(function(){
 var cssAmimationSupport = false;
 
 if(Modernizr.csstransforms && Modernizr.csstransitions)
 {
 	cssAmimationSupport = true;
 
 	var mozCssFadeIn = {'-moz-animation-duration':'1s','-moz-animation-name':'fadeIn','-moz-opacity':'1'},
 		mozCssFadeOut = {'-moz-animation-duration':'1s','-moz-animation-name':'fadeOut','-moz-opacity':'0'},
		webkitCssFadeIn = {'-webkit-animation-duration':'1s','-webkit-animation-name':'fadeIn','opacity':'1'},
 		webkitCssFadeOut = {'-webkit-animation-duration':'1s','-webkit-animation-name':'fadeOut','opacity':'0'},
		cssFadeIn,
		cssFadeOut;
		
	if($.browser.mozilla)
	{
		cssFadeIn = mozCssFadeIn;
		cssFadeOut = mozCssFadeOut;
	}
	else if($.browser.webkit)
	{
		cssFadeIn = webkitCssFadeIn;
		cssFadeOut = webkitCssFadeOut;
	}
	else cssAmimationSupport = false;
	
}
 
$("#hoverPanel").hover (
function(){
	
	if(cssAmimationSupport)	$("#img2").css(cssFadeIn);
	else $("#img2").fadeTo(1000, 1);
	
},
function()
{
	if(cssAmimationSupport)	$("#img2").css(cssFadeOut);
	else $("#img2").fadeTo(1000, 0);
	
});	

});

посмотреть в живую.

Заметки

  • подобные ускорения должны работать в webkit, ff4+, opera 11+, ie10+;
  • не смотря на поддежку CSS3 анимаций соверменными браузерами, ее применение нужно тестировать: не увсегда это дает прирост производительности, а иногда даже наоборот;
  • не все CSS3 анимации имеют аппартное ускорение: трансформации дают (transform), а переходы (transition) нет (это из личного наблюдения, может что-то не так делал);
  • jQuery вроде собирается включить в свои анимации автоматическое определение поддержки браузером CSS3 анимаций и для таких выполнять с помощью CSS. Сейчас для подобных целей можно воспользоваться плагином.

Материалы