Home >Web Front-end >JS Tutorial >A detailed explanation of performance optimization in JavaScript
Below I will share with you an article based on JavaScript performance optimization tips. It has a good reference value and I hope it will be helpful to everyone. Let’s follow the editor and take a look.
JavaScript, as the most common literal scripting language at present, has been widely used in web application development. In order to improve the performance of web applications, it would be a good choice to start with JavaScript performance optimization.
This article explains JavaScript performance optimization techniques from multiple aspects such as loading, context, parsing, compilation, execution and bundling, so that more front-end developers can master this knowledge.
What is high-performance JavaScript code?
Although there is currently no absolute definition of high-performance code, there is a user-centered performance model that can be used as a reference: the RAIL model.
Response
If your application can respond to the user's action within 100 milliseconds, the user will consider the response to be real time. This applies to clickable elements, not scrolling or dragging operations.
Animation
On a 60Hz monitor we want 60 frames per second when animation and scrolling, in this case each frame is about 16ms. Of that 16ms, there's really only 8-10ms to do all the work, the rest of the time is taken up by browser internals and other differences.
Idle work
If you have a task that takes a long time and needs to run continuously, make sure to break it into small chunks to allow the main thread to React to user input operations. There should not be a task that delays user input by more than 50ms.
Loading
Page loading should complete within 1000 milliseconds. On mobile, this is a difficult goal to achieve because it involves interaction with the page rather than just rendering and scrolling on the screen.
Modern Loading Best Practices (Chrome Dev Summit 2017)
53% of users abandon a mobile site if it takes more than three seconds to load Visit
50% of users expect a page to load in less than 2 seconds
77% of mobile websites take more than 10 seconds to load on 3G networks
19 seconds is the average load time for a mobile site on a 3G network required time. Specifically, it’s the download, parsing, compilation, and execution time of JavaScript. There seems to be no other way than loading fewer JavaScript files or loading them more flexibly.
Besides launching the website, how does JavaScript code actually work? Before doing code optimization, consider what you are currently building. Are you building a framework or a VDOM library? Does your code need to perform thousands of operations per second? Are you making a time-critical library that handles user input and/or animation? If not, you need to redirect your time and energy to more impactful areas. Writing high-performance code is not that important because it usually has little impact on the grand scheme of things. 50k ops/s sounds better than 1k ops/s, but in most cases the overall time won't change.
Parse, compile and execute
Fundamentally speaking, most JavaScript performance problems do not lie in running the code itself, but in A series of steps that must be taken before code can start executing.
We are discussing the level of abstraction here. Most code that runs on a computer is in compiled binary format. This means that, except for all operating system level abstractions, the code can run natively on the hardware with no preparation required. JavaScript code is not precompiled, it is readable on the browser. JavaScript code is first parsed, that is, read and converted into a structure that can be used for compilation of computer indexes, then compiled into bytecode, and finally compiled into machine code for device/browsing processor execution.
Another very important aspect: JavaScript is single-threaded and runs on the browser's main thread. This means that only one process can be running at a time. If your DevTools performance timeline is filled with yellow spikes and CPU usage reaches 100%, you will experience dropped frames. This is a common and annoying situation when scrolling.
All this parsing, compilation and execution work needs to be completed before JavaScript code can be run. In the ChromeV8 engine, parsing and compilation account for about 50% of the total JavaScript execution time.
So in this part, you should know two things:
1. Although JavaScript parsing The length of time is not completely linear with the size of the bundle, but the less JavaScript that needs to be processed, the less time it takes.
2. Every JavaScript framework you use (React, Vue, Angular, Preact...) is another level of abstraction (unless it's a precompiled one). Not only will this increase the size of your bundle, but it will also make your code slower since you're not talking directly to the browser.
There are ways to mitigate this, such as using service workers to perform part of the work in another thread in the background, or using asm.js to write code that compiles more easily to machine instructions.
All we can do is avoid using JavaScript animation libraries. Only use these libraries if it is completely impossible to achieve using regular CSS transitions and animations.
Even though these JavaScript animation libraries use CSS transitions, compositing properties, and requestAnimationFrame(), they still run on the main thread of JavaScript. Basically these libraries access the DOM every 16ms using inline styles. You need to ensure that all JavaScript is completed within 8ms of each frame to maintain the smoothness of the animation.
On the other hand, CSS animations and transitions will run in the main thread, and if they can be executed efficiently, they can avoid relayout/reflow situations.
Considering that most animations run during loading or user interaction, this can provide your web application with very important adjustments.
The web Animations API is an upcoming feature set that enables high-performance JavaScript animations to be executed off the main thread. But for now, technology like CSS transitions will need to continue to be used.
Bundle size is very important
It is no longer necessary to include multiple 3f1c4e4b6b16bbbd69b2ee476dc4f83a before the 36cc49f0c466276486e50c850b7e4956 closing tag. era. A wide variety of toolkits can now be found on npm, and these can be bundled with Webpack in a single 1MB JavaScript file, alerting the user's browser to crawl when the data plan is complete.
This allows you to use less JavaScript, which also means your project may no longer need the entire Lodash library. If you must use a JavaScript library, consider using something other than React, such as Preact or HyperHTML, which are only 1/20 the size of React.
Webpack 3 has amazing features called code splitting and dynamic imports. It does not bundle all JavaScript modules into a single app.js package, but uses the import() syntax to automatically split the code and load it asynchronously.
You don’t need to use frameworks, components, and client-side routing to get these benefits. You simply need to write the following in the main JavaScript file:
if (document.querySelector('.mega-widget')) { import('./mega-widget'); }
If your application requires this widget on the page, it will dynamically load the required supporting code.
Also, Webpack needs runtime to work and inject it into all .js files it generates. If you use the commonChunks plugin, you can use the following to extract the runtime into chunks:
new webpack.optimize.CommonsChunkPlugin({ name: 'runtime', }),
Ensure that Webpack has finished loading before the main JavaScript bundle, then the runtime in all other chunks will be stripped into their own file, this case is also called runtime.js. For example:
<script src="runtime.js"> <script src="main-bundle.js">
Then comes the part of compiling code and polyfills. If you're writing modern JavaScript code (ES6), you can use Babel to convert it to ES5-compatible code. Compilation not only increases file size but also adds complexity and often suffers from performance degradation compared to native ES6 code.
In addition to this, you will most likely use the babel-polyfill package and whatwg-fetch to fix missing functionality in older browsers. So if you are writing async/await, you also need to use the generator package regenerator-runtime to compile it.
The problem is, you're adding nearly 100KB to your JavaScript package, which is not only a huge file, but also represents a huge overhead in parsing and executing it to be able to support older browsers.
一种方法是创建两个独立的 bundle,并根据实际条件来加载它们。Babel 转换编译器在 babel-preset-env 的帮助下,会使同时面临新旧两种浏览器的情况更加容易处理。
一个并不规范但行之有效的方法,是将以下内容放在一个内联脚本中:
(function() { try { new Function('async () => {}')(); } catch (error) { // create script tag pointing to legacy-bundle.js; return; } // create script tag pointing to modern-bundle.js;; })();
如果浏览器无法识别 async 函数,则会被认为是旧版本的浏览器,此时就会用到 polyfill 包。如果能识别,用户则将得到现代浏览器的处理。
结论
想要提高网站的运行速度,就需要确保网站能快速的加载 JavaScript 文件,以实现快速的互动。你的 JavaScript 代码应该被分成更小的、可管理的 bundle,同时尽可能地进行异步加载。在服务器端,请确保启用了 HTTP 2.0,以便实现更快的并行传输和 gzip/Brotli 压缩,从而大大减少了 JavaScript 的传输大小。
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
The above is the detailed content of A detailed explanation of performance optimization in JavaScript. For more information, please follow other related articles on the PHP Chinese website!