The difference between DOMContentLoaded and load

(1) During the development process of the chrome browser, we will see these two values ​​in the network panel, which correspond to the marking lines on the network request. What do these two time values ​​represent?

(2) We have repeatedly emphasized that putting CSS at the head and js files at the tail is conducive to optimizing the performance of the page. Why can this method optimize performance?

(3) When using jquery, we usually write the function call in the ready method. What is the principle?

first look

DOMContentLoaded, as the name suggests, means that the DOM content is loaded. So what is the dom content loaded? Let's start by opening a web page. When a URL is entered, the display of the page will be blank at first, and after a while, the page will display the content, but some resources of the page, such as image resources, cannot be seen yet. At this time, the page can interact normally. After a period of time After the picture is finished displaying on the page. The DOMContentLoaded event is triggered from the page blank to the display of the page content. And this time is when the HTML document is loaded and parsed.

At this time, the question comes again, what is the HTML document being loaded and parsed. To solve this problem, we must understand how browser rendering works.

When we enter the URL in the browser address, the browser will send a request to the server, and the server will send the requested HTML document back to the browser. After the browser downloads the document, it starts parsing from top to bottom. Generate DOM. If there is css in the page, CSSOM will be formed according to the content of css, then DOM and CSSOM will generate a rendering tree, and finally the browser will calculate the exact size and position of each node in the page according to the content of the rendering tree, and draw it on the browser.

 

 Below is a snapshot of the browser during page loading and parsing

 

Above we saw that in the process of parsing html, the parsing of html will be interrupted, because javascript will block the parsing of dom. When the <script> tag is encountered during the parsing process, the parsing process will be stopped and the script will be processed instead. If the script is inline, the browser will execute the inline script first. If it is an external link , then the script will be loaded first, and then executed. After processing the script, the browser continues parsing the HTML document.

At the same time, the execution of javascript will be affected by the style file in front of the tag. If there is a style file before the tag, the script needs to be executed after the style file is loaded and parsed. This is because javascript can query the style of an object.

It should be noted here that in modern browsers, in order to reduce the rendering blocking situation, modern browsers use guess preloading. When parsing is blocked, the browser has a lightweight HTML (or CSS) scanner that continues to scan the document, looking for URLs of resource files that may be available in the future, and using them in the renderer Download it before.

Here we can specify the time calculated by DOMContentLoaded. When there is no script in the document, the browser can trigger the DOMContentLoaded event after parsing the document; if the document contains a script, the script will block the parsing of the document, and the script needs to wait in front of the script The css can only be executed after loading. In any case, the triggering of DOMContentLoaded does not need to wait for other resources such as images to be loaded.

Next, let's talk about load. The load event will not be triggered until all resources (images, audio, video, etc.) on the page are loaded. In short, the load event of the page will be triggered after DOMContentLoaded is triggered.

The $(document).ready(function() { // ...code... }); we often use in jQuery is actually listening to the DOMContentLoaded event, and $(document).load(function() { / / ...code... }); Listens for the load event. When using jquery, we usually write the function call in the ready method, that is, after the page is parsed, we can access all the dom elements of the entire page, which can shorten the interactive time of the page and improve the experience of the entire page.

Let's take a look at how to implement these two functions

1. onload event

   The onload event is supported by all browsers, so we don't need anything compatible, just by calling

window.onload = function(){
    
}

2. DOMContentLoaded event

Different browsers support DOMContentLoaded differently, so we need to be compatible with different browsers when implementing it.

1) If the DOMContentLoaded event is supported, use the DOMContentLoaded event;

2) IE6, IE7 do not support DOMContentLoaded, but it supports the onreadystatechange event, the purpose of which is to provide information about the loading state of the document or element.

3) Lower ie also has a unique method doScroll, which is called by interval: document.documentElement.doScroll("left");

  Can detect whether the DOM is loaded or not. When the page is not loaded, this method will report an error, and when doScroll no longer reports an error, it means that the DOM is loaded. This method is closer to the implementation of DOMContentLoaded.

function ready(fn){

    if(document.addEventListener) {
        document.addEventListener('DOMContentLoaded', function() {
            document.removeEventListener('DOMContentLoaded',arguments.callee, false);
            fn();
        }, false);
    }

    // If IE 
    else  if (document.attachEvent) {
         // Ensure that the event will still be triggered safely when the page is loaded in an iframe 
        document.attachEvent('onreadystatechange', function () {
             if (document.readyState == ' complete' ) {
                document.detachEvent('onreadystatechange', arguments.callee);
                fn();
            }
        });

        // If it is IE and the page is not in an iframe, poll the doScroll method to check whether the DOM is loaded 
        if (document.documentElement.doScroll && typeof window.frameElement === "undefined" ) {
             try {
                document.documentElement.doScroll('left');
            }
            catch(error){
                return setTimeout(arguments.callee, 20);
            };
            fn();
        }
    }
};

 Finally, let's answer this question: why do we repeatedly emphasize putting css at the head and js files at the end

During the interview process, someone often mentioned putting js at the bottom of the body tag in the optimization of the answer page. The reason is that when the browser generates the Dom tree, it reads the HTML code line by line, and the script tag is placed at the end. Does not affect the rendering of previous pages. Then the problem comes, since the page can only be rendered after the Dom tree is completely generated, the browser must read all HTML to generate a complete Dom tree, is it the same if the script tag is not placed at the bottom of the body, because the generation of the dom tree requires The entire document is parsed.

Let's take a look at chrome in the page rendering process. The green marker line is the time of First Paint. Nani, why does firstpaint appear, isn't the paint of the page after the rendering tree is generated? Actually in modern browsers for a better user experience, the rendering engine will try to display the content on the screen as soon as possible. It doesn't wait until all HTML is parsed to start building and laying out the render tree. The content of the section will be parsed and displayed. That is to say, the browser can render the incomplete dom tree and cssom, and reduce the time of the white screen as soon as possible. If we put js in the header, js will block parsing dom, and the content of dom will affect First Paint, causing First Paint to delay. So we will put js in the back to reduce the time of First Paint, but not reduce the time of DOMContentLoaded being triggered.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325216552&siteId=291194637