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

Дата публикации: 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. Сейчас для подобных целей можно воспользоваться плагином.