У меня есть несколько элементов, которые я анимирую, и которые я разработал таким образом, чтобы они не появлялись в браузере. Если я включаю «Мигание краски» в Chrome Devtools, я вообще не вижу мигания краски. Однако, если я записываю производительность, то график показывает, что на рисование тратится много времени. Время от времени FPS составляет всего 15 кадров в секунду.
На самом деле я построил это во Vue, и в результате скомпилированного кода слишком много кода, чтобы вставить сюда. Я понимаю, что анимация несколько нарушена, мне все еще нужно определить время и т. д., Но в целях этого вопроса меня беспокоит только производительность.
Я разместил скомпилированный код здесь, на CodePen:
https://codepen.io/IOIIOOIO/pen/gjBqyg
Кажется, StackOverflow требует, чтобы я разместил здесь некоторый код, поэтому вот скомпилированный код только для одного элемента:
.circle {
position: relative;
width: 100%;
padding-top: 100%;
border-radius: 50%;
overflow: hidden;
}
.circle::before {
content: "";
background-color: black;
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
animation-name: switch;
animation-iteration-count: infinite;
animation-timing-function: steps(1);
animation-duration: 3s;
animation-delay: inherit;
}
.rotating-circle {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 50%;
}
.rotating-circle--first-cycle {
background-color: black;
animation-name: rotate, toggle-first;
animation-duration: 3s, 3s;
animation-iteration-count: infinite, infinite;
animation-timing-function: linear, steps(1);
animation-delay: 1800ms;
}
.rotating-circle--second-cycle {
opacity: 0;
animation-name: rotate, toggle-second;
animation-duration: 3s, 3s;
animation-iteration-count: infinite, infinite;
animation-timing-function: linear, steps(1);
animation-delay: 1800ms;
}
@keyframes rotate {
0% {
transform: rotate3d(0, 1, 0, 0deg);
}
50% {
transform: rotate3d(0, 1, 0, 180deg);
}
}
@keyframes toggle-first {
0% {
opacity: 1;
}
25% {
opacity: 0;
}
75% {
opacity: 1;
}
}
@keyframes toggle-second {
0% {
opacity: 0;
}
25% {
opacity: 1;
}
75% {
opacity: 0;
}
}
@keyframes switch {
0% {
transform: translatex(0);
}
50% {
transform: translatex(100%);
}
100% {
transform: translatex(0);
}
}<div class = "circle" style = "background-color: rgb(255, 0, 0); animation-delay: 0ms;">
<div class = "rotating-circle rotating-circle--first-cycle" style = "animation-delay: 0ms;">
</div>
<div class = "rotating-circle rotating-circle--second-cycle" style = "background-color: rgb(255, 0, 0); animation-delay: 0ms;">
</div>
</div>

Похоже, что вся работа велась на Composite Layers, и не обязательно только на Painting. Я обнаружил, что добавление transform: translateZ(0) или will-change к отдельным анимированным элементам не очень помогает. Однако, если я добавлю transform: translateZ(0) к родительскому элементу .circle, то время, потраченное на Composite Layers и Painting, значительно сократится.
Он по-прежнему работает довольно медленно, но я думаю, что это может быть просто потому, что на моем компьютере есть встроенная графика и 4 ГБ оперативной памяти.
Так что я думаю, что это так хорошо, насколько это возможно, но был бы признателен за любые дальнейшие предложения.
Вот пример, в котором я добавил transform: translateZ(0) к родительскому элементу:
https://codepen.io/IOIIOOIO/pen/gjBqyg
РЕДАКТИРОВАТЬ:
Я обнаружил значительное улучшение, удалив border-radius на родительском элементе, который я установил на overflow: hidden для создания маски:
Перед:
.circle {
border-radius: 50%;
overflow: hidden;
}
Вместо этого я использовал clip-path в качестве маски:
После
transform: translateZ(0);
clip-path: circle(49% at 50% 50%);
Я уверен, вы сразу заметите, что это намного лучше:
https://codepen.io/IOIIOOIO/pen/OwBBJV
Мы будем очень признательны за любое дальнейшее понимание того, почему это работает.