Недавно я пытался улучшить анимацию на своем веб-сайте, в частности раскрывающийся список навигации на мобильных устройствах.
В этой связи я наткнулся на следующий случай, который я надеюсь получить.некоторые более глубокие знания о.
Дело в том, что при переходе / анимации transform: translate3d()
кажется, что браузер требует больше вычислений, когда он применяется с использованием %
вместо px
.Например, в моих тестах кажется, что переход с transform: translate3d(0, 500px, 0)
на transform: translate3d(0,0,0)
требует меньше вычислений и работает более плавно, чем переход с transform: translate3d(0, 100%, 0)
.
Обновление: При дальнейшем тестировании я обнаружилчто использование 100vh
/ 100vw
обходит / смягчает проблему использования процентов.Это может быть полезно в тех случаях, когда элемент имеет известную процентную ширину окна или является полной шириной, и, таким образом, повышается производительность.На самом деле кажется, что использование этого значения ведет себя так, как если бы оно было присвоено значению px
в Chrome.
Вот пара изображений временной шкалы из каждой анимации.Временные шкалы получены с помощью инструментов Google Dev в разделе «Производительность».Чтобы лучше показать разницу, производительность в Chrome Dev Tools была ограничена до уровня «low-end mobile» (6-кратное замедление ЦП).
Преобразование с использованием процентов:
![Transform performance using percent (%)](https://i.stack.imgur.com/Ymcrs.png)
Преобразование с использованием пикселя (px):
![Transform performance using pixel (px)](https://i.stack.imgur.com/fntnh.png)
Как можноИз рисунков видно, что при рендеринге %
вместо px
происходит гораздо больше рендеринга и рисования.Имеет большой смысл, что браузер должен вычислять процентные значения для каждого кадра (я полагаю?), Но я удивлен, что это занимает намного больше по сравнению с использованием значения в пикселях.
Также обратите внимание, что частота кадров на рисунке, показывающая временную шкалу в процентах, никогда не достигает ~ 60 кадров в секунду, а в среднем составляет около 40 кадров в секунду.
Ниже приведены фрагменты, чтобы повторить случай.Один использует проценты, а другой использует пикс.
$(document).on("click", function(){
$(".bb").toggleClass("active");
});
.aa{
height:50px;
background:blue;
position:fixed;
top:0;
width:100%;
}
.bb{
position:fixed;
top:0px;
background:none;
height:100%;
width:100%;
left:0;
transform:translateZ(0);
overflow:hidden;
pointer-events:none;
}
.cc{
height:100%;
transform:translate3d(0,500px,0);
width:100%;
transition:transform .5s ease-in;
background:red;
}
.bb.active .cc{
transform:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click the document to start animation<p>
<div class="bb">
<div class="cc">
<ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul><ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul>
</div>
</div>
$(document).on("click", function(){
$(".bb").toggleClass("active");
});
.aa{
height:50px;
background:blue;
position:fixed;
top:0;
width:100%;
}
.bb{
position:fixed;
top:0px;
background:none;
height:100%;
width:100%;
left:0;
transform:translateZ(0);
overflow:hidden;
pointer-events:none;
}
.cc{
height:100%;
transform:translate3d(0,100%,0);
width:100%;
transition:transform .5s ease-in;
background:red;
}
.bb.active .cc{
transform:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Click the document to start animation<p>
<div class="bb">
<div class="cc">
<ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul><ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul>
</div>
</div>
Чтобы решить эту «проблему», в которой использование процентов в transform
может привести к ухудшению производительности анимации, я сделал следующее предложение:может улучшить производительность.Однако мне интересно услышать другие мнения, так как я не совсем уверен, нужно ли это и почему (?).
В основном я просто использую jQuery для применения transform
значение в пикселях, а не в процентах.Для производственных случаев это, естественно, потребует обновления при изменении размеров окна.
Результирующая временная шкала для этого подхода:
![enter image description here](https://i.stack.imgur.com/KAuZS.png)
$(document).ready(function(){
var bbWidth = $("#bb .cc").css('transform').split(',')[5].slice(0,-1);
$("#bb .cc").css("transform", "translate3d(0," + bbWidth + "px,0");
$(document).on("click", function(){
$("#bb").toggleClass("active");
});
});
.aa{
height:50px;
background:blue;
position:fixed;
top:0;
width:100%;
}
#bb{
position:fixed;
top:0px;
background:none;
height:100%;
width:100%;
left:0;
transform:translateZ(0);
overflow:hidden;
}
.cc{
height:100%;
transform:translate3d(0,100%,0);
width:100%;
transition:transform .5s ease-in;
background:red;
position:absolute;
top:0;
}
#bb.active .cc{
transform:none!important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="bb">
<div class="cc">
<ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul><ul>
<li>Point one</li>
<li>Point two</li>
<li>Point three</li>
<li>Point four</li>
<li>Point five</li>
<li>Point six</li>
<li>Point seven</li>
</ul>
</div>
</div>
Вопрос:
- Правильно ли это поведение (назначениезначение в
px
работает лучше, чем %
), и если да, то почему это происходит?Как упоминалось ранее, для меня это имеет смысл, так как должно, но мне действительно не хватает каких-то технических / подробных объяснений. - Есть ли лучший способ обойти эту проблему, чем мое предложение?Использование
transform: translate()
, например, для того, чтобы скрыть навигацию за пределами экрана, очень косвенно, если вы «не можете» использовать %
и если вы хотите одновременно плавную анимацию.