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 JS
, GUI
The rendering thread is responsible for rendering, the two are mutually exclusive, so JS
render.
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:
-
GUI
Rendering thread -
JS
Engine thread - event trigger thread
- timed trigger thread
-
HTTP
request thread
Wait
However, let's take Baidu's search page as an example, open the Performance
panel to start recording:
In the recording results above:
-
Chrome_ChildIOThread
corresponds toIO
thread's task record, user input, network, device-related events are related to him -
Raster
record rasterization thread pool task,GPU
recordGPU
synthesize the thread's task of synthesizing the bitmap,Compositor
record 33 tasks above, All three are related to browser rendering -
Main
record 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 Task
(tasks):
The first task is to request HTML
data:
Parse HTML
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 DOM
tree.
These blocks can be seen from the DOM
tree DOM
tree generated JS
script:
Their presence significantly lengthened the duration of Parse HTML
.
Recaculate Style
After parsing the DOM
tree (blue Parse HTML
), the next task is purple Recaculate Style
:
He is responsible for HTML
in CSS
style (outreach, inline) output styleSheets
, styleSheets
has two functions:
- Can be combined with
DOM
tree to bring style to the page -
JS
can operatestyleSheets
change page style
We can print from the console document.styleSheets
to intuitively feel his existence:
Layout
With 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 Layout
:
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
:
Paint
We can find that before FP
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 JS
and 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 Paint
.
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 Paint
:
Summarize
JS
reason why rendering is blocked is because JS
execution of rendering-related tasks competes for the limited resources of the main thread.
When JS
the execution time is too long, rendering-related tasks have no time to execute.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。