Javascript
Load and execution sequence of a web page
Understanding the load and execution sequence of a web page is crucial for web developers aiming to optimize website performance and deliver a seamless user experience. From the moment a user enters a URL to the final rendering of the page, a complex series of events unfolds behind the scenes. This process involves the browser requesting resources, parsing HTML, executing JavaScript, and rendering the content. By grasping the intricacies of this sequence, developers can identify bottlenecks, improve loading times, and ensure their websites are both efficient and user-friendly. Optimizing this sequence not only enhances the user experience but also positively impacts SEO, as search engines prioritize fast-loading and well-structured websites. Knowing how browsers interpret and execute web page elements allows for strategic optimization, leading to faster rendering and better overall performance. This knowledge is essential for building modern, high-performing web applications.
The Initial Request and HTML Parsing
The journey of a web page begins the moment a user enters a URL or clicks a link. The browser then sends an HTTP request to the server hosting the website. This request is essentially asking the server to send back the HTML document associated with that URL. Once the server receives the request, it responds by sending the HTML document back to the browser. This initial HTML document is the foundation upon which the entire web page is built.
Upon receiving the HTML document, the browser begins the process of parsing it. Parsing involves reading the HTML code and converting it into a Document Object Model (DOM) tree. The DOM tree represents the structure of the HTML document as a hierarchical tree of objects. Each HTML element becomes a node in the DOM tree, and the relationships between elements are represented by the tree’s branches. This DOM tree is crucial because it allows JavaScript to interact with and manipulate the elements of the web page. The browser creates the DOM incrementally, as it reads the HTML. According to Google’s Web Fundamentals documentation, “The browser constructs the DOM incrementally as it parses the HTML markup.” Google Web Fundamentals offers detailed insights into this process.
During the parsing process, the browser identifies other resources that the page needs, such as CSS stylesheets, JavaScript files, images, and other media. It then makes separate requests for each of these resources. The order in which these requests are made and processed significantly impacts the overall loading time of the web page. Optimizing the order in which these resources are loaded is a key aspect of web performance optimization.
CSSOM Construction and Render Tree
While the browser is constructing the DOM, it also encounters CSS stylesheets, either linked externally or embedded within the HTML. These stylesheets are responsible for defining the visual style of the web page, including colors, fonts, layout, and other visual properties. The browser parses these CSS rules and constructs a CSS Object Model (CSSOM). Similar to the DOM, the CSSOM is a tree-like structure that represents the CSS rules and their relationships. The CSSOM is crucial for determining how the elements in the DOM will be visually rendered.
The DOM and CSSOM are then combined to create the Render Tree. The Render Tree includes only the visible elements of the DOM and their associated styles. Elements that are not visible (e.g., elements with display: none;) are excluded from the Render Tree. The Render Tree represents the final structure of the web page that will be displayed to the user. This step is critical because it defines how the browser will paint the page.
The creation of the Render Tree is a crucial step in the load and execution sequence of a web page. It determines which elements are displayed and how they are styled. This process is also affected by JavaScript, which can dynamically modify both the DOM and the CSSOM, leading to re-calculations and re-rendering of the page. Understanding how these components interact is essential for optimizing web page performance. For a deeper dive, explore resources from Mozilla Developer Network (MDN) on how browsers work.
JavaScript Execution and DOM Manipulation
JavaScript plays a significant role in the interactivity and dynamic behavior of web pages. When the browser encounters a
However, modern browsers provide mechanisms to mitigate this blocking behavior. The async and defer attributes can be added to the
JavaScript can dynamically manipulate the DOM, adding, removing, or modifying elements and their attributes. This allows for creating interactive and dynamic user interfaces. However, excessive or poorly optimized DOM manipulation can lead to performance issues, such as slow rendering and unresponsive user interfaces. Therefore, it’s essential to optimize JavaScript code for performance and minimize unnecessary DOM manipulations. Tools like Lighthouse can help identify performance bottlenecks related to JavaScript execution. Optimizing JavaScript significantly improves the load and execution sequence of a web page.
Rendering and Painting
Once the Render Tree is constructed, the browser proceeds to the rendering and painting stages. Rendering involves calculating the exact position and size of each element in the Render Tree within the viewport. This process is also known as layout or reflow. Reflow can be a performance-intensive operation, especially when it’s triggered frequently by JavaScript or CSS changes. Therefore, it’s essential to minimize reflows by optimizing CSS and JavaScript code.
Painting involves filling in the pixels on the screen to display the elements of the Render Tree. This process is also known as rasterization. Painting can also be a performance-intensive operation, especially when dealing with complex graphics or animations. Modern browsers use hardware acceleration to speed up the painting process, but it’s still important to optimize graphics and animations to minimize the workload on the browser. This section explains the final visual steps of the load and execution sequence of a web page.
After painting, the browser may perform compositing, which involves combining different layers of the page into a final image. Compositing can be used to improve performance by allowing the browser to independently update different parts of the page without re-painting the entire page. For example, animations and transitions can be implemented using compositing to achieve smooth and efficient visual effects. Proper rendering ensures that the user sees the content as intended and that the page is responsive and interactive.
- Key aspects of rendering include layout calculations, painting, and compositing.
- Optimizing CSS and JavaScript can minimize reflows and repaints.
Here are several strategies for optimizing the load and execution sequence of a web page:
- Minimize HTTP requests: Reduce the number of files the browser needs to download by combining CSS and JavaScript files.
- Optimize images: Compress images to reduce their file size without sacrificing quality. Use appropriate image formats (e.g., WebP) for better compression.
- Use a Content Delivery Network (CDN): Distribute your website’s files across multiple servers to reduce latency and improve loading times for users around the world.
- Enable browser caching: Configure your server to allow browsers to cache static resources, such as CSS, JavaScript, and images.
- Minify CSS and JavaScript: Remove unnecessary characters from CSS and JavaScript files to reduce their file size.
- Load JavaScript asynchronously or deferred: Use the async or defer attributes to prevent JavaScript from blocking HTML parsing.
- Optimize CSS delivery: Inline critical CSS to render above-the-fold content quickly, and load non-critical CSS asynchronously.
- Prioritize above-the-fold content for faster initial rendering.
- Use asynchronous loading for non-critical resources.
Featured Snippet: The load and execution sequence of a web page is a multi-step process that begins with the browser sending a request to the server for the HTML document. The browser then parses the HTML to create the DOM, constructs the CSSOM from CSS stylesheets, combines the DOM and CSSOM to create the Render Tree, executes JavaScript code, performs rendering and painting, and finally displays the fully rendered web page to the user. Understanding this sequence is crucial for optimizing website performance and delivering a seamless user experience. This process utilizes various resources and techniques to ensure optimal loading times and user satisfaction.
FAQ: Load and Execution Sequence
- What is the DOM?
- The DOM (Document Object Model) is a tree-like structure that represents the HTML document as a hierarchical tree of objects. Each HTML element becomes a node in the DOM tree.
- What is the CSSOM?
- The CSSOM (CSS Object Model) is a tree-like structure that represents the CSS rules and their relationships. It is used to determine how the elements in the DOM will be visually rendered.
- What is the Render Tree?
- The Render Tree is a tree-like structure that includes only the visible elements of the DOM and their associated styles. It represents the final structure of the web page that will be displayed to the user.
- Why is JavaScript execution blocking?
- JavaScript execution is typically blocking because JavaScript can modify the DOM, and the browser needs to ensure that the DOM is up-to-date before continuing to parse the HTML. However, the async and defer attributes can be used to prevent JavaScript from blocking HTML parsing.
Now that you have a better understanding of how web pages load, consider auditing your own website’s performance. Use tools like Google PageSpeed Insights to identify areas for improvement and implement the optimization strategies discussed. By taking these steps, you’ll not only enhance the user experience but also improve your website’s search engine ranking. Explore further topics such as “Critical Rendering Path” and “Lazy Loading” to continue honing your web development skills.
Question & Answer :
I have done some web based projects, but I don’t think too much about the load and execution sequence of an ordinary web page. But now I need to know detail. It’s hard to find answers from Google or SO, so I created this question.
A sample page is like this:
<html> <head> <script src="jquery.js" type="text/javascript"></script> <script src="abc.js" type="text/javascript"> </script> <link rel="stylesheets" type="text/css" href="abc.css"></link> <style>h2{font-wight:bold;}</style> <script> $(document).ready(function(){ $("#img").attr("src", "kkk.png"); }); </script> </head> <body> <img id="img" src="abc.jpg" style="width:400px;height:300px;"/> <script src="kkk.js" type="text/javascript"></script> </body> </html>
So here are my questions:
- How does this page load?
- What is the sequence of the loading?
- When is the JS code executed? (inline and external)
- When is the CSS executed (applied)?
- When does $(document).ready get executed?
- Will abc.jpg be downloaded? Or does it just download kkk.png?
I have the following understanding:
- The browser loads the html (DOM) at first.
- The browser starts to load the external resources from top to bottom, line by line.
- If a
<script>is met, the loading will be blocked and wait until the JS file is loaded and executed and then continue. - Other resources (CSS/images) are loaded in parallel and executed if needed (like CSS).
Or is it like this:
The browser parses the html (DOM) and gets the external resources in an array or stack-like structure. After the html is loaded, the browser starts to load the external resources in the structure in parallel and execute, until all resources are loaded. Then the DOM will be changed corresponding to the user’s behaviors depending on the JS.
Can anyone give a detailed explanation about what happens when you’ve got the response of a html page? Does this vary in different browsers? Any reference about this question?
Thanks.
EDIT:
I did an experiment in Firefox with Firebug. And it shows as the following image: 
Edit: It’s 2022. If you are interested in detailed coverage on the load and execution of a web page and how the browser works, you should check out https://browser.engineering/ (open sourced at https://github.com/browserengineering/book)
According to your sample,
<html> <head> <script src="jquery.js" type="text/javascript"></script> <script src="abc.js" type="text/javascript"> </script> <link rel="stylesheets" type="text/css" href="abc.css"></link> <style>h2{font-wight:bold;}</style> <script> $(document).ready(function(){ $("#img").attr("src", "kkk.png"); }); </script> </head> <body> <img id="img" src="abc.jpg" style="width:400px;height:300px;"/> <script src="kkk.js" type="text/javascript"></script> </body> </html>
roughly the execution flow is about as follows:
- The HTML document gets downloaded
- The parsing of the HTML document starts
- HTML Parsing reaches
<script src="jquery.js" ... jquery.jsis downloaded and parsed- HTML parsing reaches
<script src="abc.js" ... abc.jsis downloaded, parsed and run- HTML parsing reaches
<link href="abc.css" ... abc.cssis downloaded and parsed- HTML parsing reaches
<style>...</style> - Internal CSS rules are parsed and defined
- HTML parsing reaches
<script>...</script> - Internal Javascript is parsed and run
- HTML Parsing reaches
<img src="abc.jpg" ... abc.jpgis downloaded and displayed- HTML Parsing reaches
<script src="kkk.js" ... kkk.jsis downloaded, parsed and run- Parsing of HTML document ends
Note that the download may be asynchronous and non-blocking due to behaviours of the browser. For example, in Firefox there is this setting which limits the number of simultaneous requests per domain.
Also depending on whether the component has already been cached or not, the component may not be requested again in a near-future request. If the component has been cached, the component will be loaded from the cache instead of the actual URL.
When the parsing is ended and document is ready and loaded, the events onload is fired. Thus when onload is fired, the $("#img").attr("src","kkk.png"); is run. So:
- Document is ready, onload is fired.
- Javascript execution hits
$("#img").attr("src", "kkk.png"); kkk.pngis downloaded and loads into#img
The $(document).ready() event is actually the event fired when all page components are loaded and ready. Read more about it: http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
Edit - This portion elaborates more on the parallel or not part:
By default, and from my current understanding, browser usually runs each page on 3 ways: HTML parser, Javascript/DOM, and CSS.
The HTML parser is responsible for parsing and interpreting the markup language and thus must be able to make calls to the other 2 components.
For example when the parser comes across this line:
<a href="#" onclick="alert('test');return false;" style="font-weight:bold">a hypertext link</a>
The parser will make 3 calls, two to Javascript and one to CSS. Firstly, the parser will create this element and register it in the DOM namespace, together with all the attributes related to this element. Secondly, the parser will call to bind the onclick event to this particular element. Lastly, it will make another call to the CSS thread to apply the CSS style to this particular element.
The execution is top down and single threaded. Javascript may look multi-threaded, but the fact is that Javascript is single threaded. This is why when loading external javascript file, the parsing of the main HTML page is suspended.
However, the CSS files can be download simultaneously because CSS rules are always being applied - meaning to say elements are always repainted with the freshest CSS rules defined - thus making it unblocking.
An element will only be available in the DOM after it has been parsed. Thus when working with a specific element, the script is always placed after, or within the window onload event.
Script like this will cause error (on jQuery):
<script type="text/javascript">/* <![CDATA[ */ alert($("#mydiv").html()); /* ]]> */</script> <div id="mydiv">Hello World</div>
Because when the script is parsed, #mydiv element is still not defined. Instead this would work:
<div id="mydiv">Hello World</div> <script type="text/javascript">/* <![CDATA[ */ alert($("#mydiv").html()); /* ]]> */</script>
OR
<script type="text/javascript">/* <![CDATA[ */ $(window).ready(function(){ alert($("#mydiv").html()); }); /* ]]> */</script> <div id="mydiv">Hello World</div>