Keywords: Web Page Load Sequence | HTML Parsing | JavaScript Execution | CSS Application | Parallel Resource Download | $(document).ready | Browser Performance Optimization
Abstract: This article delves into the core mechanisms of web page load and execution sequence, based on the interaction between HTML parsing, CSS application, and JavaScript execution. Through analysis of a typical web page example, it explains in detail how browsers download and parse resources in order, including the timing of external scripts, CSS files, and inline code execution. The article also discusses the role of the $(document).ready event, parallel resource loading with blocking behaviors, and potential variations across browsers, providing theoretical insights for developers to optimize web performance.
In modern web development, understanding the load and execution sequence of web pages is crucial for optimizing performance and ensuring functional correctness. This article analyzes the complete process of browser handling HTML documents through a concrete example, covering resource downloading, parsing order, and the interaction mechanisms between JavaScript and CSS.
Basic Flow of HTML Parsing and Resource Loading
When a browser receives an HTML response, it first initiates the HTML parser, processing the document content line by line. This process is sequential, but certain resources can be downloaded in parallel to enhance efficiency. Below is a typical web page code example that serves as the basis for our analysis:
<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>
The parser processes the document from top to bottom, with specific steps as follows:
- Download and begin parsing the HTML document.
- Upon encountering the <script src="jquery.js"> tag, pause HTML parsing, download and execute jquery.js.
- Continue parsing, encounter <script src="abc.js">, similarly block parsing until abc.js is downloaded and executed.
- Parse the <link href="abc.css"> tag, initiate CSS file download, but continue parsing without blocking.
- Process inline CSS rules within the <style> tag, parsing and applying them immediately.
- Encounter the inline <script> tag, execute the JavaScript code, including registration of the $(document).ready callback.
- Enter the <body>, parse the <img src="abc.jpg"> tag, initiate image download.
- Finally, parse <script src="kkk.js">, download and execute kkk.js.
- HTML parsing completes, triggering the document ready event.
JavaScript Execution Timing and Blocking Behavior
JavaScript execution has a blocking effect on HTML parsing. When the parser encounters a <script> tag, whether external or inline, it pauses document parsing until the script is downloaded (if needed) and executed. This is because JavaScript may manipulate the DOM, and the parser must ensure state consistency. For example, in the sample, loading jquery.js and abc.js delays rendering of subsequent content.
Inline scripts follow the same rule. The code $(document).ready(function(){...}) registers the callback immediately during parsing, but the callback function itself executes only after the document is fully ready. This is illustrated by the following rewritten code example:
// Simplified implementation simulating $(document).ready
function onDocumentReady(callback) {
if (document.readyState === 'complete') {
callback();
} else {
document.addEventListener('DOMContentLoaded', callback);
}
}
// Register event
onDocumentReady(function() {
document.getElementById('img').setAttribute('src', 'kkk.png');
});
This mechanism ensures DOM elements are fully parsed, preventing access to undefined nodes. If a script executes before an element, as in this error example:
<script>
alert(document.getElementById("mydiv").innerHTML);
</script>
<div id="mydiv">Hello World</div>
An error will be thrown because mydiv does not yet exist in the DOM. The correct approach is to place the script after the element or use a ready event.
CSS Loading and Application Mechanisms
Unlike JavaScript, CSS resource loading is typically non-blocking. When the parser encounters a <link> or <style> tag, it initiates CSS downloading or parsing but continues processing HTML. CSS rules are applied immediately as they become available, enabling progressive rendering. For instance, the abc.css file may contain style rules that the browser applies incrementally while downloading, without interrupting the document flow.
Inline CSS is parsed directly via the <style> tag, such as h2{font-wight:bold;} in the example, with these rules taking effect instantly upon parsing. CSS application is based on selector matching, with browsers maintaining a style calculation thread that works in parallel with HTML parsing to ensure visual consistency.
Parallelism in Resource Downloading and Cache Impact
Modern browsers support parallel resource downloading to improve load speed. Typically, browsers allow multiple simultaneous HTTP requests from the same domain (the number varies by browser settings, e.g., Firefox defaults to 6). In the example, abc.css and abc.jpg might download concurrently, while scripts load sequentially due to blocking nature.
Caching mechanisms significantly affect downloading behavior. If a resource (e.g., jquery.js) is cached, the browser may load it from local storage, skipping network requests and speeding up parsing. This is demonstrated by the following simulated code:
// Simplified resource loading logic
function loadResource(url, isScript) {
if (isCached(url)) {
return getFromCache(url); // Retrieve from cache
}
fetch(url).then(response => {
if (isScript) {
executeScript(response.text()); // Execute script
} else {
applyResource(response); // Apply other resources
}
});
}
Experimental data (such as Firebug screenshots) often show resource timelines, revealing parallel downloads and cache hits, helping developers optimize resource order and caching strategies.
Execution of $(document).ready and Image Replacement
In the example, the $(document).ready callback function executes after document parsing completes, triggering image source replacement. The specific process is as follows:
- HTML parsing ends, all blocking resources are loaded, and the DOM is fully constructed.
- The
DOMContentLoadedor similar event is triggered, executing registered ready callbacks. - The code
$("#img").attr("src", "kkk.png")in the callback changes the img element's src attribute to "kkk.png". - The browser downloads kkk.png and displays it, while abc.jpg may have been downloaded but is replaced.
This answers a key question: abc.jpg is downloaded because it is requested as the initial src during parsing, but it may be overwritten by kkk.png, resulting in the latter being displayed. Code is rewritten for clarity:
// Image replacement logic
const imgElement = document.getElementById('img');
imgElement.src = 'kkk.png'; // Triggers new download
// abc.jpg may have been downloaded but is no longer displayed
Browser Variations and Performance Optimization Recommendations
While the main flow follows standards, browser implementations vary. For example, differences exist in parallel request limits, preload scanning (early resource discovery), and support for script deferral/async attributes (e.g., async or defer). Developers should test cross-browser behavior and use tools like Chrome DevTools to analyze load sequences.
Based on this analysis, optimization recommendations include:
- Place non-critical JavaScript at the bottom of the document or use
async/deferattributes to reduce blocking. - Minify and cache CSS/JavaScript files to shorten download times.
- Utilize CDNs for resource distribution to enhance parallel download efficiency.
- Monitor real user data to adjust resource order according to network conditions.
By deeply understanding load sequences, developers can build faster, more reliable web applications, improving user experience.