Hello, I recently listened to a new edition of Web Standards and there was a moment with a discussion of the article “Time of Variables” where the author decided to experiment with CSS variables and create an analog clock based on them. Everything looks gorgeous and most importantly works, but I have a lot of questions and I decided to experiment a bit and tell you my conclusions at the same time.
Do not think anything bad, I love CSS variables and everything new in CSS, but as always there are a couple but. First of all, I personally don’t really like the idea of writing to the DOM every second, because everything connected with it is resource intensive, but here I’m not quite sure how bad it can be. Secondly, despite the fact that CSS variables are very convenient to use, you still need to use them wisely, because each time you change a variable, you cause a redraw of each element that uses it. And here I see the main problem for myself.
The Rendering tab in the Chrome console helped confirm the fact of redrawing:
We see a redraw every second and an average fps of 50 frames, and this is on the page where we have only one clock.
But first, we will create our own clocks, with which we will conveniently move the arrow using only the transform property. Create a dial with all hands:
The idea here is this: if you put each arrow into a separate container, which will be in the center of the clock, then rotating this container relative to the center, we will also rotate the arrow itself. Here is an example of such container styles for the hour hand:
.clock__hand { margin-left: -0.5em; margin-top: -0.5em; font-size: inherit; position: absolute; display: block; height: 1em; width: 1em; left: 50%; top: 50%; } .clock__hand--hour::after { content: ""; border-radius: 0.015em 0.015em 0.01em 0.01em; background-color: #000; margin-bottom: -0.02em; margin-left: -0.025em; font-size: inherit; position: absolute; display: block; height: 0.25em; width: 0.05em; bottom: 50%; left: 50%; }
.clock__hand--hour { animation: clock-hand-rotate 43200s linear infinite; } .clock__hand--minute { animation: clock-hand-rotate 3600s linear infinite; } .clock__hand--second { animation: clock-hand-rotate 60s linear infinite; } @keyframes clock-hand-rotate { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }
No redraws and stable 60 fps
var date = new Date(), hours = date.getHours(), minutes = date.getMinutes(), seconds = date.getSeconds(); if (hours > 12) { hours -= 12; } var secondsStartDegree = 360 / 60 * seconds, minutesStartDegree = 360 / 60 * minutes + 6 / 60 * seconds, hoursStartDegree = 360 / 12 * hours + 30 / 60 * minutes + 0.5 / 60 * seconds; var style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = '\ @keyframes clock-hand-rotate--hour {\ from {transform: rotate(' + hoursStartDegree + 'deg)}\ to {transform: rotate(' + (hoursStartDegree + 360) + 'deg)}\ }\ @keyframes clock-hand-rotate--minute {\ from {transform: rotate(' + minutesStartDegree + 'deg)}\ to {transform: rotate(' + (minutesStartDegree + 360) + 'deg)}\ }\ @keyframes clock-hand-rotate--second {\ from {transform: rotate(' + secondsStartDegree + 'deg)}\ to {transform: rotate(' + (secondsStartDegree + 360) + 'deg)}\ }\ .clock__hand--hour {\ animation: clock-hand-rotate--hour 43200s linear infinite;\ }\ .clock__hand--minute {\ animation: clock-hand-rotate--minute 3600s linear infinite;\ }\ .clock__hand--second {\ animation: clock-hand-rotate--second 60s steps(60) infinite;\ }'; document.getElementsByTagName('head')[0].appendChild(style);
And I would say that it is not always worthwhile to rush for new technologies, if the old ones still can do enough. And the most important thing is that it is better to use reliable tools than to simply try to put in a new, incredible feature of the language everywhere.
And in terms of browser resources, I would never have thought that a simple drawing would take as many frames.
I hope you were interested too, thanks for reading.
Source: https://habr.com/ru/post/350884/
All Articles