When I read the book High Performance JavaScript, I saw this sentence:
Putting scripts at the top of the page in this way typically leads to a noticeable delay, often in the form of a blank white page, before the user can even begin reading or otherwise interacting with the page.
The explanation is as follows:
Placing the script script in the head will cause a significant delay, usually as follows: The page opens blank and the user cannot read or interact with it.
My understanding is: putting js in the head, the loading and execution of js causes page rendering to be delayed. If js is placed at the end, since the page rendering precedes the loading or execution of js, it can be presented to the user first without being affected by the blocking of js.
In order to verify, the following experiment was done:
<p>hello world</p><script type="text/javascript"> function f() { var t = +new Date(); //运行5秒 while(true) { if(+new Date() - t > 5) { break; } } } f(); // ①</script>
The experimental results are interesting: hello world waited for 5 seconds before it came out.
In-depth verification: Introduce the above script as a js external link or load it dynamically. The result still came out after waiting for 5 seconds.
This means that the rendering of the page must occur only after all js are loaded and executed. There is something wrong with the above paragraph.
Does this mean that as long as js does not involve dom operations, placing it at the head and tail will have the same effect? of course not. For example, when there are pictures or other resources in the html, if js is placed at the head, the download of the picture needs to wait until js is finished running before starting. However, if js is placed at the tail, since the download of the picture does not block the running of js, you can Achieve parallel downloading of images and running of js.
Is this the end of the problem? Of course not. A very important part of front-end work is performance optimization. How to optimize the above js? So I thought of setTimeout.
setTimeout is used to delay the execution of js code. It has the advantage that it will not block the execution of js behind it. So I guess setTimeout will also not block the rendering of the page.
Option 1: Replace the ① part above with:
setTimeout(f,0);Copy after login
As a result, hello world still has to wait for 5 seconds before it comes out. But if you are careful, you will find that the load symbol on the browser label is missing.
Continue to guess, 0 is too small, causing the browser to find that there is no js code behind setTimeout and immediately execute the content in setTimeout, that is, the f function. So change the time to 100ms.
Option 2: Replace the ① part above with:
setTimeout(f, 100);Copy after login
The result is hello world pops up instantly. A little excited. Interested students can continue testing. At this time, you will find that there will be a critical value (different browsers have different critical values). When the second parameter of setTimeout is greater than this critical value, hello world will pop up instantly. Otherwise, you need to wait. It will pop up after the function inside is completed.
It’s amazing, why does this happen? To answer this question, we must study the browser's threading mechanism.
We know that there are at least two threads inside the browser: the thread that parses js and the thread that renders the interface. Here we temporarily call them JS thread and UI thread.
Since js can manipulate the DOM, if you modify the properties of these elements while rendering the interface (that is, the JS thread and the UI thread run at the same time), the element data obtained before and after the rendering thread may be inconsistent. Therefore, in order to prevent unpredictable rendering results, the browser controls the JS thread and the UI thread to execute synchronously in a queue.
Back to the above question, when setTimeout is executed, a new timer thread will be opened. This is exactly when the JS thread is running. When the JS thread is completed, it is found that setTimeout will start executing immediately (that is, the time is less than The above critical value), in order to avoid the bad experience caused by the serious delay of setTimeout caused by the UI thread running for too long, the browser chooses to wait until setTimeout expires, and then runs the js inside. If it is found that setTimeout will take a long time to expire, in order to avoid wasting time, the browser chooses to switch to the UI thread immediately.
Conclusion: setTimeout can be used to process time-consuming js code, but be careful not to set the second parameter too small, otherwise you will see the same blank page. It is recommended to be around 100ms, which can satisfy all browsers. Of course, if you can't be compatible with IE, abandon setTimeout and web workers will be a good choice.
In HTML4, programs created by js are single-threaded. Web Workers are new in HTML5 and are a technology used to implement background processing in web applications. It is very easy to create a thread running in the background using this API:
var worker = new Worker('*.js');// 后台线程是不能访问页面或窗口对象的// 但可通过发送消息和接受消息与后台线程传递数据worker.onmessage = function (e) {}; worker.postMessage = function (e) {};
The above is the detailed content of A brief analysis of the setTimeou thread mechanism. For more information, please follow other related articles on the PHP Chinese website!