我做过一些基于web的项目,但我没有过多考虑一个普通网页的加载和执行顺序。但现在我需要知道细节。很难从谷歌或SO中找到答案,所以我创造了这个问题。
一个示例页面是这样的:
<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>
下面是我的问题:
这个页面是如何加载的?
装载的顺序是什么?
JS代码什么时候执行?(内联和外部)
CSS什么时候执行(应用)?
什么时候$(document)。准备好被处决了吗?
会下载abc.jpg吗?还是直接下载kkk.png?
我有以下认识:
浏览器首先加载html (DOM)。
浏览器开始逐行从上到下加载外部资源。
如果遇到<script>,加载将被阻塞,等待JS文件加载并执行,然后继续。
其他资源(CSS/图像)并行加载并在需要时执行(如CSS)。
或者是这样的:
浏览器解析html (DOM)并以数组或类似堆栈的结构获取外部资源。html加载后,浏览器开始并行加载结构中的外部资源并执行,直到所有资源都加载完毕。然后DOM将根据用户的行为(取决于JS)进行相应的更改。
有人能详细解释一下当你得到一个html页面的响应时发生了什么吗?这在不同的浏览器中是否有所不同?有关于这个问题的参考资料吗?
谢谢。
编辑:
我用Firebug在Firefox中做了一个实验。如下图所示:
1)下载HTML。
2) HTML is parsed progressively. When a request for an asset is reached the browser will attempt to download the asset. A default configuration for most HTTP servers and most browsers is to process only two requests in parallel. IE can be reconfigured to downloaded an unlimited number of assets in parallel. Steve Souders has been able to download over 100 requests in parallel on IE. The exception is that script requests block parallel asset requests in IE. This is why it is highly suggested to put all JavaScript in external JavaScript files and put the request just prior to the closing body tag in the HTML.
3)一旦HTML被解析,DOM就被渲染。在几乎所有的用户代理中,CSS与DOM的呈现是并行呈现的。因此,强烈建议将所有CSS代码放在外部CSS文件中,这些文件在文档的<head></head>部分中请求的位置尽可能高。否则,页面呈现到DOM中CSS请求位置的出现位置,然后从头开始呈现。
4) Only after the DOM is completely rendered and requests for all assets in the page are either resolved or time out does JavaScript execute from the onload event. IE7, and I am not sure about IE8, does not time out assets quickly if an HTTP response is not received from the asset request. This means an asset requested by JavaScript inline to the page, that is JavaScript written into HTML tags that is not contained in a function, can prevent the execution of the onload event for hours. This problem can be triggered if such inline code exists in the page and fails to execute due to a namespace collision that causes a code crash.
在上述步骤中,最消耗CPU的是DOM/CSS的解析。如果你想让你的页面处理得更快,那么通过消除冗余指令和将CSS指令整合到尽可能少的元素引用中来编写高效的CSS。减少DOM树中的节点数量也会产生更快的呈现速度。
Keep in mind that each asset you request from your HTML or even from your CSS/JavaScript assets is requested with a separate HTTP header. This consumes bandwidth and requires processing per request. If you want to make your page load as fast as possible then reduce the number of HTTP requests and reduce the size of your HTML. You are not doing your user experience any favors by averaging page weight at 180k from HTML alone. Many developers subscribe to some fallacy that a user makes up their mind about the quality of content on the page in 6 nanoseconds and then purges the DNS query from his server and burns his computer if displeased, so instead they provide the most beautiful possible page at 250k of HTML. Keep your HTML short and sweet so that a user can load your pages faster. Nothing improves the user experience like a fast and responsive web page.
AFAIK,浏览器(至少Firefox)在解析每个资源时立即请求它。如果它遇到一个img标记,它将在img标记解析完成后立即请求该图像。这甚至可以在它接收到HTML文档的全部之前……也就是说,当这种情况发生时,它可能还在下载HTML文档。
对于Firefox,有一些浏览器队列可以应用,这取决于它们在about:config中的设置方式。例如,它不会尝试一次从同一服务器下载超过8个文件…额外的请求将被排队。我认为有每个域的限制,每个代理的限制,以及其他东西,这些都在Mozilla网站上有文档,可以在about:config中设置。我在某处读到IE没有这样的限制。
jQuery ready事件在主HTML文档下载完成并对其进行DOM解析后立即触发。然后,一旦所有链接的资源(CSS、图像等)都下载并解析完毕,load事件就会触发。这在jQuery文档中有明确说明。
如果您想控制所有加载的顺序,我相信最可靠的方法是通过JavaScript。