Home > Web Front-end > JS Tutorial > JavaScript Performance Optimization Tips: An Overview

JavaScript Performance Optimization Tips: An Overview

William Shakespeare
Release: 2025-02-15 09:17:11
Original
538 people have browsed it

JavaScript Performance Optimization Tips: An Overview

This article explores many aspects of how to optimize JavaScript performance in the ever-changing JavaScript ecosystem. We will follow the principle of "tools, not rules" and try to avoid using too much JavaScript jargon. Due to limited space, all aspects of JavaScript performance optimization cannot be covered, be sure to read the reference link and delve into it yourself.

Before we dive into the details, let's first understand this question from a more macro perspective: What is high-performance JavaScript and how does it fit into a broader web performance metric?

Key Points

  • JavaScript consumes a lot of performance and should be used with caution. Be sure to test the website performance in low-end devices and real network environments. The website should load quickly and interact as soon as possible.
  • It is crucial to reduce the amount of JavaScript code and speed up loading as fast as possible. The code should always be compressed, split into smaller, easier to manage packages, and load asynchronously where possible.
  • On the server side, make sure HTTP/2 is enabled for faster parallel transfers and use gzip/Brotli compression to significantly reduce JavaScript transfer size.
  • The convenience of isolating components in npm and frameworks brings a drawback: the first way for developers to solve problems becomes adding more JavaScript code. Try to reduce the amount of JavaScript code and consider using lighter frameworks such as Preact or HyperHTML.
  • JavaScript parsing time is proportional to the package size. The less JavaScript code, the better. Each JavaScript framework you use is another layer of abstraction that increases package size and slows down code.

Background settings

First of all, we need to be clear: If you only test on desktops, you exclude more than 50% of users.

JavaScript Performance Optimization Tips: An Overview

This trend will only continue to evolve as emerging market users access the internet primarily through Android devices priced under $100. The era of desktops as the main device for accessing the Internet has ended, and the next batch of one billion Internet users will access your website mainly through mobile devices.

Testing in device mode with Chrome DevTools is not a substitute for testing on real devices. Using CPU and network current limiting helps, but it is essentially different. Please test it on real devices.

Even if you are testing on a real mobile device, you may be testing with your brand new $600 flagship phone. The problem is, this is not the device your users have. The median device is similar to the Moto G1 – a device with less than 1GB of memory, very weak CPU and GPU.

Let's see how it performs when parsing average JS packages.

JavaScript Performance Optimization Tips: An Overview Addy Osmani: Average time for JS parsing and evaluation.

Oh no. While this image covers only the parsing and compilation time of JS (more on this later) rather than overall performance, it is closely related to overall performance and can be used as a metric for overall JS performance.

Quoted Bruce Lawson: "This is the World Wide Web, not the wealthy Western Web." Therefore, your web performance goal is a device about 25 times slower than your MacBook or iPhone. Think about this carefully. But it's even worse. Let's see what our actual goals are.

What is high-performance JS code?

Now that we know the target platform, we can answer the next question: What is High-performanceJS code?

While there is no absolute classification to define high-performance code, we do have a user-centric performance model that can be used as a reference: the RAIL model.

JavaScript Performance Optimization Tips: An Overview Sam Saccone: Performance Planning: PRPL

Respond (Respond)

If your app responds to user actions within 100 milliseconds, the user will consider the response to be instant. This works for clickable elements, but not for scrolling or dragging.

Animation (Animate)

On a 60Hz display, we want to achieve a constant frame rate of 60 frames per second while animation and scrolling. This means there are about 16 milliseconds per frame. In this 16 millisecond budget, you actually have only 8-10 milliseconds to do all the work, the rest of the time is taken up by the browser's internal mechanisms and other differences.

Idle work (Idle work)

If you have an expensive and continuously running task, make sure to split it into smaller chunks so that the main thread can respond to user input. You should not have a task that delays user input by more than 50 milliseconds.

Load (Load)

You should control the page loading time to less than 1000 milliseconds. After this time, your users will begin to feel impatient. This is a rather difficult goal for the page to be interactive, not just to draw it on the screen and scrollable. In fact, the time is shorter:

JavaScript Performance Optimization Tips: An Overview Fast By Default: Modern Loading Best Practices (2017 Chrome Dev Summit)

In fact, the goal is 5 seconds of interaction time. This is the metric that Chrome uses in its Lighthouse audit.

Since we know the indicators, let's look at some statistics:

  • If the mobile website loads for more than three seconds, 53% of visits will be abandoned.
  • One of every two people hopes the page will be loaded in two seconds.
  • 77% of mobile websites load over 10 seconds on 3G networks.
  • On 3G networks, the average loading time for mobile websites is 19 seconds.

and more information provided by Addy Osmani:

  • It takes 8 seconds to interact on desktop (using cables) and 16 seconds to mobile devices (Moto G4 via 3G).
  • In the median case, the developer provided 410KB of gzip compressed JS code to his page.

Do you feel depressed enough? very good. Let's get started and fix the web. ✊

Context is crucial

You may have noticed that the main bottleneck is the time it takes to load the website. Specifically, it is the JavaScript download, parsing, compiling and execution time. There is nothing else to do except load less JavaScript code and load more intelligently.

But what about the work your code actually performs besides launching the website? There must be some performance improvements there, right?

Before digging into the code, consider what you are building. Are you building a framework or a VDOM library? Does your code require thousands of operations per second? Are you writing a time-critical library for processing user input and/or animation? If not, you may need to shift your time and energy to a more effective place.

This is not to say that writing high-performance code is not important, but that it usually has little impact on the overall situation, especially when talking about micro-optimization. So before you start arguing about .map versus .forEach versus for loops on Stack Overflow and comparing the results on JSperf.com, make sure you see the forest, not just the trees. On paper, 50k ops/s may sound 50 times better than 1k ops/s, but in most cases it doesn't make any difference.

Analysis, compilation and execution

Fundamentally, the problem with most non-high performance JS is not the running code itself, but all the steps that are required to be performed before the code starts to execute. We are talking about the level of abstraction here. The CPU in your computer runs machine code. Most of the code running on your computer is in a compiled binary format. (Thinking about all Electron applications today, I'm talking about code not

programs

.) This means that, except for all OS-level abstractions, it's in you run natively on the hardware without any preparation. JavaScript is not precompiled. It arrives in your browser in the form of readable code, and for all intents and purposes it is the "operating system" of your JS program. The code first needs to be parsed - that is, read and converted into a structure that can be indexed by the computer for compilation. Then compile it into bytecode and finally into machine code before it can be executed by your device/browser.

Another very important thing to mention is that JavaScript is single threaded and runs on the main thread of the browser. This means that only one process can be run at a time. If your DevTools performance timeline is full of yellow peaks that keep your CPU running to 100%, you will run into long/dropping frames, stuttering scrolling, and all sorts of other annoying things.

Paul Lewis: When everything matters, nothing matters! .

JavaScript Performance Optimization Tips: An Overview So, before your JS starts working, you need to do all this. In Chrome's V8 engine, parsing and compiling account for up to 50% of the total JS execution time.

Addy Osmani: JavaScript startup performance.

JavaScript Performance Optimization Tips: An Overview Two things you should remember from this section:

Although it is not necessarily linear, the JS parsing time is proportional to the packet size. The smaller the amount of JS code, the better.
  1. Every JS framework you use (React, Vue, Angular, Preact...) is another layer of abstraction (unless it is precompiled, such as Svelte). Not only will it increase the package size, it will also slow down the code because you are not talking directly to the browser.
  2. There are ways to mitigate this, such as using a service worker thread to execute jobs in the background and on another thread, using asm.js to write code that is easier to compile into machine instructions, but this is another topic.

What you can do, however, is to avoid using JS animation frameworks for everything and understand what triggers drawing and layout. These libraries are only used if regular CSS transitions and animations are absolutely impossible to implement animations.

Even if they may use CSS transitions, synthetic properties, and requestAnimationFrame(), they are still running in JS, on the main thread. They basically just smack your DOM with inline style every 16 milliseconds because there is almost nothing else to do. To keep the animation smooth, you need to make sure that all JS can be executed within 8 milliseconds per frame.

CSS animations and transitions, on the other hand, run outside the main thread—if implemented efficiently, run on the GPU without causing relayout/repaint.

Considering that most animations run during loading or user interaction, this can provide much-needed breathing space for your web application.

Web Animations API is an upcoming feature set that allows you to perform high-performance JS animations outside of the main thread, but for the moment, stick with technologies like CSS transitions and FLIP.

Back size is crucial

Now, it's all about packing. Bower and at the end

Dozens of marks before marks The era of marks has passed.

Now it's all about installing any shiny new toys you find on NPM, bundling them into a huge 1MB JS file using Webpack and causing slowness in your user's browser while limiting Their data plan.

Try to reduce the amount of JS code. Your project may not require the entire Lodash library. Do you absolutely need to use JS framework? If so, have you considered using other frameworks other than React, such as Preact or HyperHTML, which are less than 1/20 of React? Do you need TweenMax to implement scrolling to top animation? The convenience of isolating components in npm and frameworks brings a drawback: the first way for developers to solve problems becomes adding more JavaScript code. Everything looks like a nail when you have only a hammer. After finishing pruning weeds and reducing the amount of JS code, try to deliver it more

smartly. Deliver what you need when needed.

Webpack 3 has amazing

features called code segmentation and dynamic import. Instead of bundling all JS modules into a single app.js package, it can automatically split the code using the import() syntax and load it asynchronously.

You also don't need to use frameworks, components, and client routing to get its benefits. Suppose you have a complex piece of code that supports your .mega-widget, which can be located on any number of pages. You just need to write the following in the main JS file:

If your app finds the widget on the page, it will dynamically load the required auxiliary code. Otherwise, everything is normal.

if (document.querySelector('.mega-widget')) {
    import('./mega-widget');
}
Copy after login
Copy after login
In addition, Webpack requires its own runtime to work, and it injects it into all .js files it generates. If you use the commonChunks plugin, you can extract the runtime into its own block using the following method:

It strips the runtime from all other blocks into its own file, in this case called runtime.js. Just make sure it is loaded before the main JS package. For example:

new webpack.optimize.CommonsChunkPlugin({
  name: 'runtime',
}),
Copy after login

Then there is the topic of translating the code and polyfill. If you are writing modern (ES6) JavaScript, you may be using Babel to translate it into ES5-compatible code. Translation not only increases file size due to all redundancy, it also increases complexity, and it often reduces performance compared to native ES6 code.

<🎜>
<🎜>
Copy after login
Apart from that, you may also be using the babel-polyfill package and whatwg-fetch to patch missing features in older browsers. Then, if you are writing code using async/await you also need to use a generator to translate it to include regenerator-runtime…

The key is that you add nearly 100 kilobytes of data to the JS package, which is not only huge in file size, but also huge in parsing and execution costs, aiming to support older browsers.

However, it makes no sense to punish users who use modern browsers. One method I use, and one that Philip Walton introduced in this post, is to create two separate packages and load them conditionally. Babel uses babel-preset-env to do this easily. For example, you have one package that supports IE 11 and another package that does not contain polyfill for the latest version of modern browsers.

A inefficient but effective way is to put the following in an inline script:

if (document.querySelector('.mega-widget')) {
    import('./mega-widget');
}
Copy after login
Copy after login

If the browser cannot evaluate the asynchronous function, we assume it is an old browser and just deliver the package containing the polyfill. Otherwise, users will get a simple and modern version.

Conclusion

We hope you will get from this article that JavaScript consumes a lot of performance and should be used with caution.

Ensure you test website performance in low-end devices and real network environments. Your website should load quickly and interact as quickly as possible. This means reducing the amount of JS code and speeding up loading as fast as possible. Your code should always be compressed, split into smaller, easier to manage packages, and load asynchronously where possible. On the server side, make sure HTTP/2 is enabled for faster parallel transfers and use gzip/Brotli compression to significantly reduce JS transfer size.

Speaking of this, I want to end it with the following tweet:

I need to put in a lot of effort to achieve this. But seriously, friends, it's time to abandon your framework and see how fast the browser can be.

— Alex Russell (@slightlylate) September 15, 2016

FAQs about JavaScript Performance Optimization

What common JavaScript performance traps should be avoided?

JavaScript performance issues often stem from inefficient coding practices. These may include excessive DOM operations, memory leaks, and unnecessary calculations. To avoid these problems, it is important to understand how JavaScript works and use efficient coding practices. For example, limit the use of global variables, use event delegates to handle events efficiently, and avoid using with() and eval() because they can cause performance issues.

How to optimize JavaScript loops to improve performance?

Loops are common features in JavaScript, but they can also be the source of performance issues if not optimized correctly. One way to optimize a loop is to minimize the work done within the loop. For example, instead of calculating the length of the array in each iteration, calculate it once before the loop starts. Another way is to use the most efficient loop according to your needs. For example, the forEach() method may be slower than the traditional for loop.

How does JavaScript enhancement affect performance?

Elevation is a mechanism in JavaScript where variables and function declarations are moved to the top of their included scope during the compilation phase. If not understood correctly, this can lead to unexpected behavior and potential performance issues. For example, if a large amount of data is raised but not used immediately, the promotion may result in unnecessary memory usage. Understanding elevation and using let and const instead of var can help alleviate these problems.

How to prevent memory leaks in JavaScript?

When no longer needed memory is not released, a memory leak occurs, causing performance to decline over time. Common causes of memory leaks in JavaScript include forgotten timers or callbacks, separate DOM elements, and global variables. To prevent memory leaks, make sure to clear intervals and timeouts, delete event listeners when they are no longer needed, and avoid global variables when possible.

How to use JavaScript's built-in performance tools to optimize my code?

JavaScript provides a variety of built-in tools for performance analysis and optimization. The Performance API allows you to measure the time spent on different parts of your code and helps you identify bottlenecks. The Memory API helps you track memory usage and identify potential leaks. Additionally, browser developer tools often provide performance analysis capabilities that can help you optimize your code.

How does asynchronous programming in JavaScript affect performance?

Asynchronous programming allows JavaScript to perform non-blocking operations, improving performance by allowing other code to run while waiting for the asynchronous operation to complete. However, incorrect use of asynchronous programming can lead to performance problems. For example, using too many Promise or callbacks can lead to "callback hell" and performance degradation. Learning how to use async/await, promise, and callbacks correctly can help optimize your asynchronous code.

How to optimize JavaScript for mobile devices?

Optimizing JavaScript for mobile devices requires consideration of factors such as limited CPU capabilities and network latency. Techniques for mobile optimization include minimizing the amount of JavaScript code sent over the network, using efficient coding practices to reduce CPU usage, and using progressive enhancements to ensure your website works properly even on low-power devices.

How does JavaScript compression and compression improve performance?

Compression and compression reduce the size of JavaScript files, which speeds up downloads and improves performance. Compression involves deleting unnecessary characters such as spaces and comments, while compression involves encoding data in a more efficient format. Both technologies can significantly improve website loading speeds, especially for users with slower networks.

How to use JavaScript's requestAnimationFrame to optimize performance?

The

requestAnimationFrame method allows you to call an animation function before the next repaint of the browser, creating a smooth animation. This can lead to more efficient animations than using setInterval or setTimeout, as it allows the browser to optimize animations based on the current device and loading conditions.

How to use Web Workers in JavaScript to optimize performance?

Web Workers allows you to run JavaScript on a separate thread in the background without blocking the main thread. This is useful for performing compute-intensive tasks without slowing down the user interface. However, Web Workers have some limitations and costs, such as the overhead of starting a new worker thread and the ability to operate the DOM directly, so they should be used with caution.

The above is the detailed content of JavaScript Performance Optimization Tips: An Overview. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template