I have realized that CSS animations with keyframes are really hungry for resources.
I've already eliminated the shadows, which increased performance by almost 50% in my case. I've also heard that I should include a rotateZ(360deg) to trick the browser into using GPU acceleration. But even with those "tricks" applied, my star background is really resource-hungry. As soon as you open my website, CPU and GPU usage goes up drastically and remains at a pretty high level.
I'm wondering if there is a better way to perform my desired animation without wasting so much CPU or GPU power.
I wanted a background of moving stars on my website. My solution to this was to create a div for each star, giving it a size, background colour and CSS animation with keyframes. The opacity, x and y position, as well as the speed of the animation are randomized.
The keyframes are the following:
#keyframes linear-translate {
0% {
left: -10%;
transform: rotateZ(360deg); /* rotateZ tricks the browser to use GPU acceleration for better performance */
}
100% {
left: 110%;
}
}
#keyframes linear-translate-initial {
0% {
transform: translateX(0) rotateZ(360deg);
}
100% {
left: 110%;
}
}
Here is an example for one of the div elements (with tailwind CSS classes):
<div class="absolute block bg-gray-200 rounded-full"
style="left: 1%; top: 8%; width: 3px; height: 3px; opacity: 0.381289;
animation: 90.0069s linear 0s 1 normal none running linear-translate-initial,
110.007s linear 90.0069s infinite normal none running linear-translate;"></div>
Link to codesandbox with a working example:
https://codesandbox.io/s/starbackgroundreacttailwindcss-wzers?file=/src/Starfield.tsx
Any ideas on why those animations are consuming so much power and on how to make them more efficient? It's just a horizontal translation after all...
Update:
I tried to layer the stars in div elements of different speeds as suggested by Marco.
My result can be found here:
https://codesandbox.io/s/layeredstarbackgroundreacttailwindcss-wj71q?file=/src/App.tsx:392-445
Unfortunately, the "improvement" is not that great. The CPU usage went a little down, but the GPU usage increased drastically.
I've played around a bit with your sandbox and yes the solution is that simple - there are just to many / different animations / items to handle for the CPU you can see that easily when opening the task manager and checkout the CPU usage while the sandbox is idle with your page. On my "small" machine Firefox uses up to 53% CPU. when i decrease the amount of stars in your script (down to 10) it goes down to around 18%.
I had a similar problem with a "moving div" background with shadows / gradient colors and rotations while moving from left to right...
Interesting project so far.
An idea might be to have a limited amount of layers with multiple stars fixed there and then to move the whole layer (even if you have 10 layers then there are just 10 objects that moves)...
Yes you will not have the same strong effect like calculating / moving each star by its own but with 10 layers as a background (i think its a Background right?) it should not make any markable difference to the viewer...
Related
Is using CSS transition to move text from off screen to a place on the screen ADA (Americans with Disability Act) compliant?
h1 {
text-align: center;
position: relative;
animation: heading;
animation-duration: 3s;
animation-fill-mode: forwards;
}
#keyframes heading {
0% {top: -50px;}
100% {top: 30vh;}
}
https://codepen.io/KuanaxBon/full/OJVLOmm
The parts of WCAG that are applicable here are SC 2.2.2 pause, stop, hide and SC 2.3.3 motion from interaction.
In your example provided, the animation is automatically started on page load, so it doesn't require interaction, and as such you can bypass 2.2.3 if you want.
Similarly, 2.2.2 specifies that it's only applicable if an animation lasts longer than 5 seconds, and your example is 3 seconds.
Non-sighted visitors shouldn't have a problem with the animations, as long as the DOM order is correct.
So, in my interpretation, your example will be compliant with WCAG 2.1 as-is, but if you want to make it more useful for real human visitors, I would recommend implementing the CSS reduce-motion query for visitors who may have issues with moving text. For some people, moving text on a webpage can cause vertigo, dizziness, and/or nausea.
I am currently faced with a situation, for which I need to constantly render a flickering animation within a web page. This is currently done by means of CSS, using animation: 0.05s step-end infinite keyframe_name. The keyframe changes the button's background-color at 0% and 50%. As can be expected, using Chrome's Dev tools, this area is constantly being re-painted by the browser, which is leading to an overall poor performance.
I am aware that the use of certain properties, such as the will-change property, or even using the transform: translate3d(0, 0, 0) hack, will enable hardware accelerated rendering. However, opting for either of these options, still hasn't resulted in the desired performance improvement.
The following shows some basic code for what I am trying to achieve (optimizations are not included in code snippet):
#keyframes keyframe_name
{
0% { background-color: red; }
50% { background-color: blue; }
}
button
{
animation: 0.05s step-end infinite keyframe_name;
}
According to a number of online resources, it seems that only the transform and opacity CSS properties make it possible for the browser to optimize compositing. Since neither of these properties can be used to achieve my desired goals, which other approach/es could possibly lead to a performance enhancement, when it comes to the in-browser rendering of such a resource-intensive graphic?
I'm facing a little problem with Firefox : when there is large blurred elements displayed on the dom, everything is stupidly slow.
A few things I noticed :
On some modest configurations, a reflow event can even freeze the tab
On high-end GPU, the FPS is slightly better, so I guess this filter is GPU activated
Chrome & Safari are running very smoothly
Even without animation the CPU usage is very high and any interaction is laggy
Ok show me the code
Make sure to click on expand the window so that all the images can show up, otherwise the animation will stay smooth.
I am creating a reflow event with a padding animation to intentionally stress the browser, but the overall interactions are laggy.
On a more complex webpage like CodePen the FPS is way worse : https://codepen.io/creaforge/pen/mLPqNg
Even without firing the transform editing this pen shows some performance issue (try to select blocks of code)
div {
background-color: #eaeaea;
transition: all .5s;
padding: 20px;
}
div:hover {
padding-bottom: 100px;
}
img {
filter: blur(40px);
}
<div>Hover me --> slow animation</div><br/>
<img src="http://www.placecage.com/c/200/600">
<img src="http://www.placecage.com/c/200/610">
<img src="http://www.placecage.com/c/200/620">
<img src="http://www.placecage.com/c/200/630">
<img src="http://www.placecage.com/c/200/640">
Use translate instead of padding. Animating with padding is quite heavy for your computer.
I found an interesting article about will-change property in CSS (which allows to tell the browser beforehand what will change and react proactively). The main reason behind this property is to improve the performance.
As far as I understood I can use it in the following way: jsFiddle (click on the square)
<div class="element"></div>
.element {
width: 50px;
height: 50px;
margin:30px;
background: red;
transition: transform 1s ease-out;
}
.element:hover {
will-change: transform;
}
.element:active {
transform: rotate(90deg);
}
So far so good, but in order to speak about improving in performance, there should be a way to measure this improvement.
So is there a way to measure performance, CPU/GPU utilization with and without will-change?
At the time of writing of this article, only Chrome Canary 36+, Opera
Developer 23+, and Firefox Nightly support the will-change property.
There is an intent to ship it to the stable channel too.
This is the compactability as of today::
http://caniuse.com/#search=will-change
You can Enable the
1. FPS meter
2.Show paint rectangles
in rendering tab in google chrome console.
The FPS rate won't decrease from 60 FPS if you are using will-change property.
Also the show paint rectangle won't be shown.
Will-change property will be most effective if we add to fixed elements.(When scrolling)
I'm working on a CSS3-based animation, where I have a div that has a linear-gradient as the background, and then I use a PNG as the mask using the -webkit-mask-image property.
To make it animated, I want to move the mask on top of the gradient. It's working fine and looks gorgeous, but my issue is it kinda kills the CPU.
Here's the animation:
#keyframes moveMask {
0% { -webkit-mask-position: 0px 0px;}
100% { -webkit-mask-position: 2000px 0px; }
}
And I'm calling it using this:
animation: moveMask 200s linear infinite alternate;
I've tried to add the following trick, but it didn't change anything:
transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);
Any idea on how I can optimize it?
As Rich Bradshaw pointed out, I think you will find that it's just not very well optimized. To achieve a similar sort of effect though, you could create an animated GIF, double the canvas size, and then place a static version of the GIF on every frame of the other half of the canvas. That way, the animation would always be playing invisibly in the background and you'd just switch to it by changing the position of the image whenever you wanted to show the animated version.
A problem with this technique is that the animation won't necessarily start at the beginning when you trigger it. That may or may not be important for your particular animation.