Hello everyone, I'm Casson.
In the Chinese community, there has been a saying that has been circulating for so many years:
JS thread is responsible for executing
GUI The rendering thread is responsible for rendering, the two are mutually exclusive, so
But with the increasing use of
Dev Tools , I gradually began to doubt the above statement. This article will explain why
JS block rendering with an actual case.
Welcome to join the human high-quality front-end framework group , with flying
how many threads
In the article explaining the mutual exclusion of
JS thread and
GUI thread, the threads included in the rendering process are usually listed, such as:
- event trigger thread
- timed trigger thread
However, let's take Baidu's search page as an example, open the
Performance panel to start recording:
In the recording results above:
IOthread's task record, user input, network, device-related events are related to him
Rasterrecord rasterization thread pool task,
GPUsynthesize the thread's task of synthesizing the bitmap,
Compositorrecord 33 tasks above, All three are related to browser rendering
Mainrecord tasks in the main thread of the rendering process
From this point of view, the actual thread situation of the browser is not the same as those described in the
GUI thread related articles.
main thread tasks
Next, let's go to
Main . The gray blocks of different lengths in the red frame are the tasks executed in the main thread.
Pay attention to the green block in the red box
FP , which represents
First Paint (first drawing):
So what tasks should be performed before the first draw? You can see that there are mainly 3
The first task is to request
When the request returns the
HTML byte stream, start the second task and parse the
HTML byte stream into
DOM , the name of this task is as shown in the figure Blue block
Parse HTML :
Note that some of them have different execution
Evaluate Script , these are the
JS code encountered during the parsing
These blocks can be seen from the
DOM tree generated
Their presence significantly lengthened the duration of
Parse HTML .
After parsing the
DOM tree (blue
Parse HTML ), the next task is purple
Recaculate Style :
He is responsible for
CSS style (outreach, inline) output
styleSheets has two functions:
- Can be combined with
DOMtree to bring style to the page
styleSheetschange page style
We can print from the console
document.styleSheets to intuitively feel his existence:
DOM tree and
styleSheets , then you need to generate a tree for the visible part of the view (for example
display: none part does not need to be displayed in this tree ).
This task is purple
Update Layer Tree
The page that the user sees is actually the result of overlapping multiple pages. Developers can use many means (such as
z-index ) to change the level of a certain part.
For example, the scroll bar will form its own independent level:
Since it is a multi-layer structure, you need to update the information of each layer. This task is purple
Update Layer Tree :
We can find that before
Update Layer Tree , after ---6aafb0fb62e0a37292a5e0dfbf8810e8--- only
Paint is left:
Literally, is this drawing ? Not really.
The task of
Paint is to organize the drawing information of each layer of pages to form a drawing list, and these data will be handed over to the synthesis thread for subsequent drawing operations.
It can be found that the specific drawing operation is completed by the synthetic thread, and the thread (main thread) where he and
JS are located are not mutually exclusive.
Why does JS block rendering
We now know that
Paint tasks both happen on the main thread.
The reason why the rendering is blocked is obvious: because the
Paint task is not executed in time, that is, the drawing list is not submitted to the compositing thread in time.
The reason why it is not executed in time may be because
JS the execution time is too long, resulting in no time for this frame to execute
For example, we open station B and record the tasks of the main thread.
It can be seen that there is
JS the execution time reaches 231.88ms, which exceeds the time of one frame. During this period, the main thread has no time to execute
JS reason why rendering is blocked is because
JS execution of rendering-related tasks competes for the limited resources of the main thread.
JS the execution time is too long, rendering-related tasks have no time to execute.