14 JavaScript code optimization tips

JavaScript has become one of the most popular programming languages ​​of all time. According to W3Tech's data, nearly 96% of the world's websites are using it. A key fact about the Web is that you cannot control the hardware specifications of the devices used by the users who visit the website. When end users visit your website, they may use high-end equipment or low-end equipment, and the network connection conditions may vary. This means that you must optimize your website as much as possible to meet the needs of any user.

This article lists some tips that can help you write better JavaScript code to improve performance.

By the way, please share and reuse your JS components to maintain the proper balance between high-quality code (it takes time to write) and reasonable delivery time. You can use popular tools such as Bit to share components in any project (common JS, TS, React, Vue, etc.) to Bit's component center without much effort.

1. Delete unused code and functions The more code your application contains, the more data needs to be transmitted to the client. The browser also needs more time to analyze and interpret the code. Sometimes, you may pack a lot of features that you don't use at all. It is best to keep these extra codes in the development environment instead of pushing them to the production environment, so as not to burden the client's browser.

Keep asking yourself whether a certain function or code segment is necessary. You can manually remove unused codes, or you can use tools like Uglify or Google's Closure Compiler to delete them. You can even use a technique called tree shake optimization to remove unused code from your application. Packaging software such as Webpack provides this technology. For details, please refer to here. If you want to delete unused npm packages, you can use the command npm prune. For details, refer to the NPM documentation.

2. Cache the cache as much as possible to reduce latency and network traffic, thereby reducing the time required to display the resource representation, so as to improve the speed and performance of the website. Caching can be achieved with the help of Cache API or HTTP caching. You may want to know what happens when the content changes. When certain conditions are met (such as publishing new content), the above caching mechanism can process and regenerate the cache.

3. Avoid memory leaks As a high-level language, JS will be responsible for some low-level management tasks, such as memory management. Garbage collection is a process common to most programming languages. In layman terms, garbage collection is the collection and release of memory that has been allocated to an object, but has not yet been used in any part of the program. In a programming language like C, developers must use malloc() and dealloc() functions to handle memory allocation and deallocation operations.

Although garbage collection is performed automatically in JavaScript, it is not perfect in some cases. In JavaScript ES6, Map and Set and their "weaker" sibling objects were introduced. The "weak" counterparts called WeakMap and WeakSet hold "weak" references to objects. They enable unreferenced values ​​to be garbage collected, thereby preventing memory leaks. You can read more about WeakMaps here.

4. Break the loop as soon as possible. Large loops will definitely consume a lot of precious time, so you should break them as soon as possible. You can use the break keyword and continue keyword to do this. It is your responsibility to write the most efficient code. In the example below, if you don't break from the loop, your code will run 1000000000 times in the loop, which will obviously be overloaded.

let arr = new Array(1000000000).fill('----');
arr[970] = 'found';for (let i = 0; i < arr.length; i++) {  if (arr[i] === 'found') {        console.log("Found");        break;
    }
}

In the example below, if you do not continue when the loop does not meet your criteria, you will still run the function 1000000000 times. We only deal with it when the array element is in an even position. This reduces the loop execution by nearly half.

let arr = new Array(1000000000).fill('----');
arr[970] = 'found';for (let i = 0; i < arr.length; i++) {  if(i%2!=0){        continue;
    };
    process(arr[i]);
}

You can learn more about the relationship between cycle and performance here.

5. Minimize the number of variable calculations In order to reduce the number of calculations of variables, closures can be used. In layman's terms, closures in JavaScript allow you to access the scope of external functions from internal functions. A closure is created every time a function is created (not called). The inner function will have access to variables in the outer scope, even after returning to the outer function. Let's look at two examples. These examples are from Bret's blog.

function findCustomerCity(name) {  const texasCustomers = ['John', 'Ludwig', 'Kate']; 
  const californiaCustomers = ['Wade', 'Lucie','Kylie'];  
  return texasCustomers.includes(name) ? 'Texas' : 
    californiaCustomers.includes(name) ? 'California' : 'Unknown';
};

If you call the above function multiple times, a new object will be created each time. Each time it is called, the variables texasCustomers and CaliforniaCustomers will cause unnecessary memory reallocation.

function findCustomerCity() {  const texasCustomers = ['John', 'Ludwig', 'Kate']; 
  const californiaCustomers = ['Wade', 'Lucie','Kylie'];  
  return name => texasCustomers.includes(name) ? 'Texas' : 
    californiaCustomers.includes(name) ? 'California' : 'Unknown';
};let cityOfCustomer = findCustomerCity();
cityOfCustomer('John');//TexascityOfCustomer('Wade');//CaliforniacityOfCustomer('Max');//Unknown

In the above example, with the help of the closure, the inner function returning to the variable cityOfCustomer can access the constant of the outer function findCustomerCity(). Moreover, whenever the internal function is called with the passed name as a parameter, there is no need to instantiate the constant again. To learn more about closures, I suggest you read Prashant's blog post.

6. Minimize DOM access. Compared with other JavaScript statements, the speed of accessing DOM is very slow. If you make a change to the DOM and trigger a redraw of the layout, you will have to wait a while. In order to reduce the number of visits to the DOM element, please visit it once and then use it as a local variable. After completing the requirements, be sure to set it to null to remove the value of the variable. This will prevent memory leaks, as this will trigger the garbage collection process.

7. Compressed files can reduce the size of JavaScript files through compression methods (such as Gzip). Smaller files will improve the performance of your website because the browser only needs to download smaller assets. This type of compression method can reduce the file size by up to 80%. Read more about compression here.

8. Shrinking the final code Some people think that shrinking and compressing are the same, but they are not. In compression, we use a special algorithm to change the output size of the file; when shrinking, we need to delete comments and extra spaces in the JavaScript file. Many tools and software packages can be found online to help with this process. Shrinking has become a standard practice for page optimization and one of the main steps in front-end optimization. Shrinking can reduce the file size by up to 60%. You can read more about zooming out here.

9. Using Throttle and Debounce, we can use these two techniques to strictly control the number of events the code needs to handle. Throttling is the maximum number of times the specified function can time out. For example, "execute the onkeyup event function at most once every 1000 milliseconds." In other words, even if you hit 20 keys per second, the event will only be triggered once per second. This will reduce the burden on the code. On the other hand, anti-shake is to specify the shortest duration of time to run the same function again since the last time the same function was executed. In other words, "This function will be executed at least 600 milliseconds after the last time the function was called". To learn more about articulated flow and anti-shake, here is a quick start. You can implement your own anti-shake and throttling functions, or you can import them from libraries such as Lodash and Underscore.

10. Avoid using the Delete keyword. The delete keyword is used to delete attributes from an object. The performance of this keyword is not very good, and it is expected to be fixed in a future update. Or, you can simply set the unwanted properties to undefined.

const object = {name:"Jane Doe", age:43};object.age = undefined;

You can also use the Map object, Bret thinks its delete method will be faster.

11. Use asynchronous code to prevent thread blocking. You should know that JavaScript is synchronous and single-threaded by default. But in some cases, your code requires a lot of calculations. Code is inherently synchronous, which means that while a piece of code is running, other code statements will be blocked from running until the former finishes execution. This will reduce overall performance. But we can avoid this situation through asynchronous code. Asynchronous code was previously written in the form of callbacks, but ES6 introduced a new style of handling asynchronous code. This new style is called Promise. You can learn more about callbacks and Promises in the official documentation of MDN. But wait... JavaScript is synchronous by default and is also single-threaded. How to run asynchronous code on a single thread? This is where many people are confused. To do this, it mainly relies on the JavaScript engine running in the background of the browser. A JavaScript engine is a computer program or interpreter that executes JavaScript code. The JavaScript engine can be written in multiple languages. For example, the V8 engine supporting the Chrome browser is written in C++, while the SpiderMonkey engine supporting the Firefox browser is written in C and C++. These JavaScript engines can process tasks in the background. According to Brian, the call stack can identify Web API functions and hand them to the browser for processing. After the browser completes these tasks, they will return and be pushed onto the stack as callbacks. You may be wondering how Node.js does these tasks, after all, it does not have the help of a browser. In fact, the V8 engine that supports Chrome is also the support behind Node.js. Here is a great blog post by Salil explaining this process in the Node ecosystem.

12. Use code splitting If you have experience using Google Light House, you will definitely be familiar with an indicator called "first contentful paint". It is one of the six metrics tracked in the Performance section of the Lighthouse report. First Contentful Paint (FCP) measures the time it takes for the browser to render the first DOM content after the user goes to your page. Images, non-white elements, and SVG on the page are considered DOM content; there is no content inside the iframe. One of the best ways to get a higher FCP score is to use code splitting. Code splitting is a technique in which only necessary modules are sent to the user at the beginning of the transmission. By reducing the size of the initially sent payload, this will greatly affect the FCP score. Popular module packers (such as webpack) can provide you with code splitting capabilities. You can also use native ES modules to load each module individually. You can learn more about native ES modules here.

13. Using async and defer In modern websites, scripts are more dense than HTML, their size is larger and they consume more processing time. By default, the browser must wait for the script to download and execute before processing the rest of the page. So clunky scripts may prevent web pages from loading. To avoid this situation, JavaScript provides us with two technologies called async and defer. You just need to add these attributes to

14. Use Web Workers to run CPU-intensive tasks in the background. Web Workers allow you to run scripts in background threads. If you have some high-intensity tasks, you can assign them to Web Workers, which can run them without interfering with the user interface. After creation, the Web Worker can post messages to the event handler specified by the code to communicate with the JavaScript code, and vice versa. To learn more about Web Workers, I suggest you read the MDN documentation.

【免责声明:本文图片及文字信息均由千锋重庆Java培训小编转载自网络,旨在分享提供阅读,版权归原作者所有,如有侵权请联系我们进行删除。】


Guess you like

Origin blog.51cto.com/15128443/2667962