Transferred from: http://blog.csdn.net/u012251421/article/details/50536265
Description
The browsers mentioned in this article refer to Chrome.
The "script tag" refers to an ordinary, non-additional attribute of the external JavaScript.
Web performance optimization means is not black or white, and some means too much to reduce performance, so in the discussion of conditions and conclusions, although many conditions themselves will bring other subtle negative or positive effects, in order not to lose focus on the discussion, will not expand too open.
First, from a face of the question.
In front of the interview I like to ask questions that seem to be common sense. For example: Why do people generally put <script src=""></script>
such code at the bottom of the body? (For the sake of communication efficiency, I will agree with each other in advance of all the discussions with Chrome as an example)
The candidate will generally answer: because the browser generates a DOM tree in a row of HTML code, the script tag on the last side will not affect the previous page rendering.
I am a chicken thief to continue to ask: Since the DOM tree is fully generated after the page can be rendered, the browser must read all the HTML to generate a complete DOM tree, the script tag is not placed on the bottom of the body is not the same?
This is actually an open question, in which the definition of the concept involved is very important.
What does "page render" mean?
Strictly speaking, my last question is ambiguous: we need to unify what we often say "page rendering"-Refers to "the first screen is displayed" or "the page is fully Loaded" (hereafter collectively referred to as STEPC)?
If the first screen is displayed, then the problem comes again: Assume that the first screen of the page has a picture, where the "first screen" refers to "show the first screen of all Pictures" (hereafter collectively referred to as STEPB) or "No picture of the first screen" (hereafter collectively referred to as STEPA).
Make sure "page rendered" refers to which of Stepa, STEPB, Stepc is critical (although no one has tried to do so so far), if "page rendered" refers to Stepc, then my last question is yes- The script tag is not placed at the bottom of the body and does not slow down the full load time of the page.
Obviously, we tend to be more concerned about the first screen time, so if the "page rendered out" specifically "no picture of the first screen", then my last question becomes the following, and how to answer it?
Now that the DOM tree is fully generated to display the "No picture of the first screen", the browser must read all the HTML to generate the full DOM tree, the script tag is not placed on the bottom of the body is not the same?
Trap
However, there is still a trap in the above question- 既然Dom树完全生成好后才能显示“没有图片的首屏”
this sentence is deceptive, "the first screen without pictures" is not necessary to "complete dom tree". In other words: in the process of generating the DOM tree, as long as certain conditions are available, "No picture of the first screen" can be displayed.
So, aside from these ambiguities and pitfalls, my question becomes:
Does the location of the script tag affect the first screen time?
The answer is not so obvious, however, from the browser's rendering mechanism. (again: The browser mentioned in this article refers to Chrome)
Second, the browser rendering mechanism
Google Web Fundamentals is a great document that covers everything from the web to the browser to the front end. I summarize the contents of the Ilya Grigorik Critical rendering path Browser rendering mechanism section below:
Several concepts
1, dom:document Object Model, the browser parses HTML into a tree-shaped data structure, referred to as DOM.
2, Cssom:css Object Model, the browser parses the CSS code into a tree-shaped data structure.
3. Both DOM and CSSOM generate the Bytes → characters → tokens → nodes → object model.
final data in such a way. As shown in the following:
The construction of the DOM tree is a deep traversal process: All the child nodes of the current node are built before the next sibling node of the current node is built.
4. Render Tree:dom and CSSOM after merging to generate the render Tree, such as:
The Render tree, like the DOM, preserves the CSS properties of each node, the attributes of the node itself, and the child nodes of the node as a multi-pronged tree.
Note: display:none
the node will not be added to the Render Tree, and visibility: hidden
then it will, so if a node is not displayed at the very beginning, set to display:none
be more optimal. (see here for details)
The browser's rendering process
Create/update Dom and request Css/image/js: After the browser requests to the HTML code, at the beginning of the generation DOM (should be bytes→characters), the parallel launch of CSS, pictures, JS request, Whether they're in the head or not.
Note: The download request for the JS file does not require the DOM to process the script node, for example: simple regular matching can do this, although in fact it does not necessarily pass the regular:). This is a lot of people in understanding the rendering mechanism of the existence of the misunderstanding.
Create/update Render cssom:css File Download complete, start building CSSOM
Create/update Render tree: All the CSS files are downloaded, and after the Cssom is built, the render tree is generated with the DOM.
Layout: With the render Tree, the browser can already know what nodes are in the Web page, the CSS definitions for each node, and their dependencies. The next step, called Layout, is to calculate the position of each node in the screen as the name implies.
After Painting:layout, the browser already knows which nodes to display (which nodes is visible), what CSS properties are for each node (their computed styles), where each node is located in the screen (geometry). Entered the final step: Painting, according to the calculated rules, through the video card, the content to the screen.
All of the previous five steps in the first 3 steps are all using "create/update" because the DOM, CSSOM, and Render tree may have been updated several times after the first painting, such as JS modifying the DOM or CSS properties.
Layout and Painting will also be repeated, in addition to the DOM, Cssom update reasons, the picture download will need to call layout and Painting to update the page.
See Timeline, at a glance
I picked up a piece of code that liked the PC home page and ran it through node. node as the server side, to /js/jquery.js
do the deferred 2s return processing, and put in the <script src="http://127.0.0.1:8080/js/jquery.js"></script>
navigation bar below, the result is this:
From the above timeline we can see:
There is no definite relationship between the first screen time and the Domcontentload event.
Early loading of all CSS is the key to reducing the first screen time
The download and execution of JS blocks the construction of the DOM tree (which is strictly interrupted by an update of the DOM tree), so the script tag will truncate the contents of the first screen in the HTML snippet in the first-screen range.
The script tag is placed at the bottom of the body, does not do async or defer processing, does not affect the first screen time, but affect the time of domcontentload and load, and thus affect the start time of the execution of the dependent code.
Iii. answers to the questions
Back to the previous question:
Does the location of the script tag affect the first screen time?
The answer is: no impact (if the first screen here refers to the page from the Whiteboard to the web screen-that is, the first time painting), but it is possible to truncate the first screen content, so that it only shows the above section.
Why is that "possible"? , if the JS download is faster than the CSS, or the script tag is not in the first screen of HTML, actually does not affect. It is important to understand this boundary, so that we can look at the page performance bottlenecks. For example: In the second screen of the Web page has a general-purpose module, in fact, we can put its JS logic independent into a file, the module's HTML and JS tags together into a separate template introduced (if its JS is small or because more than one file will occupy a TCP connection and bandwidth, This is actually another topic, please refer to the statement at the beginning of my article).
Iv. Summary and further
So, finally, we know the common sense. Let's sum it up:
If the location of the script tag is not in the first screen, it does not affect the first screen time
It makes sense that all script tags should be placed on the bottom of the body.
However, from a performance-optimized point of view, even the script tag at the bottom of the body slows down the first screen, because the browser requests its corresponding JS file at the very beginning, which takes up a limited number of TCP links, bandwidth, and even the CPU required to run it. This is one reason why the script tag has an async or defer attribute.
However, in complex practical scenarios, there may be problems in implementing these conclusions, such as:
Your page is a sub-module to write, each module has its own HTML, JS and even CSS, when these modules into a page will appear JS naturally appear in the middle part of the HTML. It's hard for you to put the script tag on the bottom.
Even if you put the script tag at the bottom, the existence of the script tag slows down the first screen time, Domcontendload, and loaded. If there is only one script tag, we can add an async, but the result of multiple async script tags is that the JS file is executed in random order, which is obviously not what we want.
We also had this problem, so we made an open-source project: Tiny-loader--a small Loader that load css/js on best way for page performance easy to use.
[Go] Browser rendering mechanism--must be placed on the bottom of the body JS reference