• How JavaScript Works: Under the hood of CSS and JS animations + How to optimize their Performance
  • Originally written by Alexander Zlatkov
  • The Nuggets translation Project
  • Permanent link to this article: github.com/xitu/gold-m…
  • Translator: NoName4Me
  • Proofread by Colafornia, LVINYEH

This is the 13th article in a series devoted to exploring JavaScript and its building components. Along the way of identifying and describing the core elements, we also shared some rules of thumb for building SessionStack, a powerful and high-performance JavaScript application designed to help users view and reproduce flaws in their Web applications in real time.

If you missed the previous chapters, you can find them here:

  1. How JavaScript works: An overview of the engine, runtime, call stack
  2. How JavaScript works: 5 Tips for Optimizing Code in V8
  3. How does JavaScript work: Memory management + Handling four common memory leaks
  4. How JavaScript works: Event loops and the rise of asynchronous programming + 5 tips for better async/await coding
  5. How JavaScript works: Take a deep dive into WebSockets and HTTP/2 with SSE, and make the right choice between the two
  6. How JavaScript works: To compete with WebAssembly why WebAssembly is better than JavaScript in some situations
  7. How does JavaScript work: The internals of Web workers and 5 scenarios in which you should use it
  8. How does JavaScript work: The Web Worker lifecycle and use cases
  9. How JavaScript works: A Web push notification mechanism
  10. How does JavaScript work: Use MutationObserver to track DOM changes
  11. How JavaScript works: Rendering engines and performance tuning tips
  12. How JavaScript works: How can it be optimized for performance and security inside the network layer

An overview of

As you know, animation plays an important role in creating appealing Web apps. As users increasingly turn their attention to user experience and businesses begin to realize the importance of a perfect and enjoyable user experience, Web apps become more important and UIs become more dynamic. All of this requires more complex animation to achieve smoother state transitions in user use. Today, this is not even considered special. Users are becoming more selective and expect responsive and interactive user interfaces by default.

But dynamically implementing your interface is not that simple. What to animate, when to animate, and what to animate are tricky questions.

JavaScript and CSS animation

The two main ways to create web animation are using JavaScript and CSS. There is no absolute superiority or inferiority; It all depends on your goals.

CSS animations

Animations with CSS are the easiest way to make things move on screen.

We’ll use a quick example to show how to move a 50 pixel element along the X and Y axes. This is done by setting up a CSS transition that takes 1000 ms.

.box {
  -webkit-transform: translate(0, 0);
  -webkit-transition: -webkit-transform 1000ms;

  transform: translate(0, 0);
  transition: transform 1000ms;
}

.box.move {
  -webkit-transform: translate(50px, 50px);
  transform: translate(50px, 50px);
}
Copy the code

When class move is added, the value of transform changes and the transition begins.

In addition to the duration of the transition, there are other options for easing, and that’s the nature of the animation that you see. We’ll discuss easing in more detail later in this article.

If you create a separate CSS class to manage animations like the code snippet above, you can use JavaScript to toggle each animation on and off.

Suppose you have an element like this:

<div class="box">
  Sample content.
</div>
Copy the code

You can then toggle each animation on and off using JavaScript:

var boxElements = document.getElementsByClassName('box'),
    boxElementsLength = boxElements.length,
    i;

for (i = 0; i < boxElementsLength; i++) {
  boxElements[i].classList.add('move');
}
Copy the code

The code snippet above takes all the elements that have a Box class and adds a Move class to trigger the animation.

Doing so provides a good balance for your app. You can focus on managing state using JavaScript and simply set the appropriate classes on the target element and let the browser handle the animation. If you go down this route, you can listen for events on the transitionEnd element, but only if you can drop support for older Versions of Internet Explorer:

Listen for events triggered when the transition has ended, as follows:

var boxElement = document.querySelector('.box'); // Get the first element with the box class.
boxElement.addEventListener('transitionend', onTransitionEnd, false);

function onTransitionEnd() {
  // The processing transition is complete.
}
Copy the code

In addition to CSS transitions, you can also use CSS animations, which give you more control over animation keyframes, duration, and repetition.

Keyframes are used to indicate to the browser what values the CSS property should have at a given point and to fill in the gaps.

Let’s look at an example:

/** * This is a simplified version without the browser attribute prefix * if added, it will be more verbose! * /
.box {
  /* Specify the animation */
  animation-name: movingBox;

  /* Animation length */
  animation-duration: 2300ms;

  /* Number of animation repeats */
  animation-iteration-count: infinite;

  /* The animation alternates */
  animation-direction: alternate;
}

@keyframes movingBox {
  0% {
    transform: translate(0, 0);
    opacity: 0.4; 25%} {opacity: 0.9; 50%} {transform: translate(150px, 200px);
    opacity: 0.2; 100%} {transform: translate(40px, 30px);
    opacity: 0.8; }}Copy the code

The effect of it is such a (quick demos) – sessionstack. Making. IO/blog/demos /…

With CSS animations, you can define the animation itself independently of the target element and select the desired animation using the animation-name property.

CSS animations sometimes still require a browser property prefix, -webkit- for Safari, Safari Mobile, and Android. Chrome, Opera, Internet Explorer and Firefox all work without a prefix. A number of tools can help you create the browser property prefixes you need for CSS, allowing you to write prefix-free versions of the CSS in your source files.

JavaScript animation

Creating animations using JavaScript is more complex than using CSS transitions or animations, but it generally provides more power to developers.

JavaScript animations are written inline as part of the code. You can also wrap them in other objects. Here are the CSS transitions you’ll need to write in JavaScript to recreate the ones described above:

var boxElement = document.querySelector('.box');
var animation = boxElement.animate([
  {transform: 'translate(0)'},
  {transform: 'translate(150px, 200px)'}].500);
animation.addEventListener('finish'.function() {
  boxElement.style.transform = 'translate(150px, 200px)';
});
Copy the code

By default, Web animation only modifies the display of elements. If you want your object to stay where it was moved to, then you should modify its underlying style when the animation is complete. That’s why we listen for the Finish event and set the box.style.transform property to Translate (150px, 200px), which is the same as the second transform of our animation.

With JavaScript animation, you have complete control over the style of elements at every step. This means you can slow down animation, pause animation, stop animation, reverse animation, and manipulate elements as needed. This is especially useful if you’re building complex object-oriented apps, because you can encapsulate your behavior appropriately.

What is slow motion?

Natural motion makes your users feel more comfortable with your Web app, leading to a better user experience.

In nature, nothing moves linearly from one point to another. In fact, things tend to speed up or slow down as they move through the physical world around us, because we’re not in a vacuum and there are different factors that affect that. The human brain is conditioned to expect this kind of movement, so you should use this knowledge to your advantage when animating your app.

A few terms to know:

  • Ease-in – Start slow, then speed up.
  • “Ease out” – Start fast, then slow down.

The two can be combined, such as “ease in out”.

Slow motion makes the animation feel more natural.

Slow key word

CSS transitions and animations allow you to choose the type of easing you want to use. There are different key words that affect animation easing. Of course, you can always use custom easing.

Here are some keywords you can use to control easing in CSS:

  • linear
  • ease-in
  • ease-out
  • ease-in-out

Let’s go through them one by one and see what they mean.

Linear (linear) animation

An animation without any easing is called a linear animation.

Here is a diagram of the linear transition:

Over time, the values will increase by the same amount. When you use linear motion, it always feels unnatural. In general, you should avoid linear motion.

Here’s a simple way to implement linear animation:

transition: transform 500ms linear;

Slow (ease-out) animation

As mentioned earlier, slowdowns start faster and then slow down compared to linear animations. This is what it looks like:

In general, slowing down is the best choice for user interface work, because a quick start gives you a feeling of quick response, while slowing down at the end of inconsistent motion feels natural.

There are many ways to cache the effect, but the easiest is to use CSS keywords:

transition: transform 500ms ease-out;
Copy the code

Slowly into the (ease-in) animation

It is the opposite of a slow release – it starts slowly and ends quickly. The illustration is as follows:

In contrast to slow out, slow in feels less natural because it starts to slow down and gives a feeling of unresponsiveness. The quick ending is also strange because the whole animation is speeding up, whereas in the real world things tend to slow down when they come to a sudden stop.

To use slow animation, similar to slow or linear animation, use keywords:

transition: transform 500ms ease-in;
Copy the code

Slow in and slow out (ease-in-out) animation

It is a combination of slow in and slow out, as shown below:

Do not use animations that last too long, as it will make your user interface seem unresponsive.

Ease-in-out animations using CSS keywords ease-in-out animations:

transition: transform 500ms ease-in-out;
Copy the code

Custom easing

You can define your own easing curve to have more control over how the project animation feels.

In fact, the keywords ease-in, ease-out, Linear, ease can correspond to predefined Bessel curves, as specified in the CSS transition specification and the Web animation specification.

Bessel curve

Let’s look at how bezier curves work. The Bezier curve has four values, or more precisely, it requires two pairs of numbers. Each pair describes the X and Y coordinates of the control points of the cubic Bezier curve. The bezier curve starts at (0, 0) and ends at (1, 1). You can set these two groups. The X values of the two control points must be within the [0, 1] range, and the Y values of each control point can exceed the [0, 1] limit, although the specification does not say by how much.

Even a slight change in the X and Y values at each control point gives you a completely different curve. Let’s look at two Bessel graphs where the coordinates of the points are similar but different.

and

As you can see, the two graphs are quite different. The vector difference of the first control point of the two curves is (0.045, 0.183), and the difference of the second control point is (-0.427, -0.054).

The CSS for the second curve is as follows:

transition: transform 500ms cubic-bezier(0465.. 0183.. 0153.. 0946.);
Copy the code

The first two numbers are the X and Y coordinates of the first control point, and the last two numbers are the X and Y coordinates of the second control point.

Performance optimization

Whenever you animate, you should keep it at 60 FPS, otherwise it will have a negative impact on the user experience.

Like everything else in the world, animation comes at a price. Some properties are cheaper to animate than others. For example, animation that changes the width and height of an element changes its shape, and may cause other elements on the page to move and change their shape. This process is called layout. We discussed layout and rendering in detail in a previous article.

In general, you should avoid animating properties that trigger layouts or draws. For most modern browsers, this means limiting animations (modified properties) to opacity and transform.

will-change

You can use [will – change] (https://dev.w3.org/csswg/css-will-change/) to inform browsers are you going to change the attribute of the element. The browser makes the most appropriate optimization before you make a change. But don’t overuse will-change, because doing so can waste browser resources and cause more performance problems.

You can add will-change to transform and opacity like this:

.box {  will-change: transform, opacity; }Copy the code

Chrome, Firefox and Opera have excellent browser support.

JavaScript or CSS?

As you probably know — there is no right or wrong answer to this question. Just keep these things in mind:

  • Css-based animations and native-supported Web animations are typically handled on threads called “synthesizer threads.” It differs from the browser’s “main thread,” where styling, layout, drawing, and JavaScript are performed. This means that if the browser runs some time-consuming task on the main thread, these animations can continue to run without interruption.
  • In many cases,transformsopacityCan be handled in the synthesizer thread.
  • If any animation starts with drawing, layout, or both, then the “main thread” will do the work. This is the same for csS-BASED or javascript-based animation; the overhead of layout or drawing makes the associated CSS or JavaScript performing work and rendering meaningless.

Select the appropriate object to animate

Good animation makes your project more enjoyable and engaging for your users. Whether you like width, height, position, color or background, you can make any animation you like, but you need to be aware of potential performance bottlenecks. Poorly chosen animations can negatively impact the user experience, so animations need to be both performance and appropriateness. The less animation, the better. Animate just to make your user experience feel natural, but don’t overdo it.

Use animations to enhance interaction

Don’t animate just because you can. Instead, use strategically placed animations to enhance user interaction. Avoid unnecessary interruptions or animations that impede user activity.

Avoid expensive animation properties

The only thing worse than poorly placed animations are those that cause the page to stall. This type of animation makes users frustrated and unhappy.

Using animation in SessionStack is very simple. In general, we follow the above approach, but due to the complexity of the UI, we have more scenarios that utilize animation. SessionStack must recreate, like a video, everything that happens when the user encounters a problem browsing the Web app. To do this, SessionStack only utilizes data collected by our library during the session: user events, DOM changes, network requests, exceptions, debug messages, and so on. Our players are highly optimized to properly render and use all the collected content data in order to provide a pixel-level simulation of the end user’s browser and everything that happens in it from a visual and technical perspective.

To ensure natural replication, especially in long and heavy user sessions, we used animations with proper instructions for loading/buffering and followed best practices on how to implement them so that we didn’t take up too much CPU time and let event polling render the session freely.

If you want to try SessionStack, there’s a free solution.

resources

  • Developers.google.com/web/fundame…
  • Developers.google.com/web/fundame…
  • Developers.google.com/web/fundame…

The Nuggets Translation Project is a community that translates quality Internet technical articles from English sharing articles on nuggets. The content covers Android, iOS, front-end, back-end, blockchain, products, design, artificial intelligence and other fields. If you want to see more high-quality translation, please continue to pay attention to the Translation plan of Digging Gold, the official Weibo, Zhihu column.