加载和执行一个网页的顺序?
我已经完成了一些基于Web的项目,但是我并不太关心普通网页的加载和执行顺序。 但现在我需要知道细节。 很难找到Google或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>
所以这里是我的问题:
我有以下的理解:
<script>
,加载将被阻塞,并等待JS文件加载并执行,然后继续。 或者是这样的:
浏览器解析html(DOM)并以数组或堆栈式结构获取外部资源。 加载html后,浏览器开始在并行结构中加载外部资源并执行,直到加载所有资源。 然后,根据JS,DOM将根据用户的行为进行更改。
任何人都可以给出详细的解释,当你得到html页面的响应时会发生什么? 这在不同的浏览器中有所不同吗? 有关这个问题的任何参考?
谢谢。
编辑:
我用Firebug在Firefox上做了一个实验。 它显示为以下图像:
根据你的样本,
<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>
大致执行流程如下:
<script src="jquery.js" ...
jquery.js
被下载并解析 <script src="abc.js" ...
abc.js
被下载,解析并运行 <link href="abc.css" ...
abc.css
被下载并解析 <style>...</style>
<script>...</script>
<img src="abc.jpg" ...
abc.jpg
被下载并显示 <script src="kkk.js" ...
kkk.js
被下载,解析并运行 请注意,由于浏览器的行为,下载可能是异步和非阻止的。 例如,在Firefox中,此设置限制了每个域的同时请求数。
还取决于组件是否已被缓存,组件可能不会在近期请求中再次被请求。 如果组件已被缓存,组件将从缓存中加载,而不是实际的URL。
当解析结束并且文档准备好并加载时, onload
事件被触发。 因此,当onload
被触发时, $("#img").attr("src","kkk.png");
运行。 所以:
$("#img").attr("src", "kkk.png");
kkk.png
被下载并加载到#img
$(document).ready()
事件实际上是所有页面组件加载并准备就绪时触发的事件。 阅读更多关于它:http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
编辑 - 这部分详细阐述了平行或非平行的部分:
默认情况下,根据我目前的理解,浏览器通常以3种方式运行每个页面:HTML解析器,Javascript / DOM和CSS。
HTML解析器负责解析和解释标记语言,因此必须能够调用其他2个组件。
例如,当解析器遇到这一行时:
<a href="#" onclick="alert('test');return false;" style="font-weight:bold">a hypertext link</a>
解析器将进行3个调用,其中两个用于Javascript,另一个用于CSS。 首先,解析器将创建该元素并将其注册到DOM名称空间中,以及与此元素相关的所有属性。 其次,解析器将调用将onclick事件绑定到该特定元素。 最后,它会再次调用CSS线程以将CSS样式应用于此特定元素。
执行是自顶而下,单线程。 Javascript可能看起来是多线程的,但事实是Javascript是单线程的。 这就是为什么当加载外部JavaScript文件时,主HTML页面的解析被暂停。
但是,CSS文件可以同时下载,因为总是应用CSS规则 - 也就是说元素总是用最新定义的CSS规则重新绘制 - 从而使其不受阻挡。
一个元素在解析后才会在DOM中可用。 因此,在处理特定元素时,脚本始终放置在窗口onload事件之后或之内。
这样的脚本会导致错误(在jQuery上):
<script type="text/javascript">/* <![CDATA[ */
alert($("#mydiv").html());
/* ]]> */</script>
<div id="mydiv">Hello World</div>
因为在解析脚本时, #mydiv
元素仍未定义。 相反,这将工作:
<div id="mydiv">Hello World</div>
<script type="text/javascript">/* <![CDATA[ */
alert($("#mydiv").html());
/* ]]> */</script>
要么
<script type="text/javascript">/* <![CDATA[ */
$(window).ready(function(){
alert($("#mydiv").html());
});
/* ]]> */</script>
<div id="mydiv">Hello World</div>
1)HTML被下载。
2)HTML被逐步解析。 当资产请求到达时,浏览器将尝试下载资产。 大多数HTTP服务器和大多数浏览器的默认配置是并行处理两个请求。 IE可以重新配置为并行下载无限数量的资产。 在互联网上,Steve Souders可以同时下载100多个请求。 例外情况是脚本请求在IE中阻止并行资产请求。 这就是为什么强烈建议将所有JavaScript放在外部JavaScript文件中,并将请求放在HTML中关闭正文标签之前。
3)一旦HTML被解析,DOM就会被渲染。 几乎在所有用户代理中,CSS都呈现为与DOM呈现并行。 因此,强烈建议将所有CSS代码放入文档的<head> </ head>部分中要求尽可能高的外部CSS文件中。 否则,页面呈现出现在DOM中的CSS请求位置,然后从顶部开始渲染。
4)只有在DOM被完全呈现并且页面中的所有资源的请求被解析或超时JavaScript执行onload事件。 IE7,我不确定IE8,如果没有收到资产请求的HTTP响应,不会很快超时。 这意味着通过JavaScript内嵌到页面的资源,即写入HTML标签中的JavaScript不包含在函数中,可以阻止onload事件在数小时内执行。 如果内联代码存在于页面中,并且由于导致代码崩溃的命名空间冲突而无法执行,则可能触发此问题。
在上述步骤中,占用CPU最多的步骤是解析DOM / CSS。 如果您希望更快地处理页面,那么可以通过消除重复指令并将CSS指令合并到尽可能少的元素引用中来编写高效的CSS。 减少DOM树中的节点数量也会产生更快的渲染。
请记住,您通过HTML或者CSS / JavaScript资源请求的每项资产都需要使用单独的HTTP标头。 这消耗了带宽并且需要按照请求处理。 如果您想尽可能快地加载页面,请减少HTTP请求的数量并减少HTML的大小。 你不会仅仅通过HTML来平均180k的页面权重来做你的用户体验。 许多开发人员订阅了一些谬误,用户在6纳秒内对网页内容的质量作出了决定,然后从服务器清除DNS查询,并在不满意的情况下烧毁他的计算机,所以他们提供了最美丽的页面250k的HTML。 保持您的HTML简短而甜蜜,以便用户可以更快地加载您的页面。 没有什么能像快速响应的网页那样改善用户体验。
在Firefox中打开您的页面并获取HTTPFox插件。 它会告诉你所有你需要的。
在archivist.incuito上找到这个:
http://archivist.incutio.com/viewlist/css-discuss/76444
当您第一次请求一个页面时,浏览器向服务器发送一个GET请求,该请求将HTML返回给浏览器。 浏览器然后开始解析页面(可能在所有页面都被返回之前)。
当它找到对CSS文件,图像文件,脚本文件,Flash文件或页面外部任何其他外部实体(无论是否在同一个服务器/域中)的外部实体的引用时,它会准备制作该资源的另一个GET请求。
但是,HTTP标准指定浏览器不应该向同一个域发出两个以上的并发请求。 因此,它将每个请求放入一个队列中的特定域,并且在每个实体返回时,它会启动该域的队列中的下一个请求。
实体返回所需的时间取决于其大小,服务器当前正在经历的负载以及运行浏览器的计算机与服务器之间的每台计算机的活动。 这些机器的列表原则上可以针对每个请求而不同,以至于一幅图像可能从美国传到我在大西洋上的英国,而来自同一服务器的另一幅从太平洋,亚洲和欧洲出来,这需要更长时间。 因此,您可能会得到如下所示的序列,其中页面(按此顺序)引用三个脚本文件和五个图像文件,所有大小都不相同:
简而言之:任何旧命令,取决于服务器在做什么,互联网的其他部分在做什么,以及是否有任何错误并且必须重新获取。 这可能看起来像是一种奇怪的做事方式,但如果没有这样做,互联网(不仅仅是WWW)在任何程度上都不可能工作。
此外,浏览器的内部队列可能无法按照它们在页面中显示的顺序来获取实体 - 这不是任何标准所要求的。
(哦,不要忘了缓存,无论是在浏览器中还是缓存ISP使用的缓存代理缓解网络负载。)
链接地址: http://www.djcxy.com/p/88869.html