网页的加载和执行顺序?

Zhu*_*Tao 239 html javascript css

我已经完成了一些基于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>
Run Code Online (Sandbox Code Playgroud)

所以这是我的问题:

  1. 这个页面如何加载?
  2. 加载的顺序是什么?
  3. 什么时候执行JS代码?(内联和外部)
  4. 什么时候执行CSS(应用)?
  5. $(文件).ready什么时候执行?
  6. 请下载abc.jpg吗?或者只是下载kkk.png?

我有以下理解:

  1. 浏览器首先加载html(DOM).
  2. 浏览器开始逐行从上到下加载外部资源.
  3. 如果<script>满足a,则将阻止加载并等待加载并执行JS文件,然后继续.
  4. 其他资源(CSS /图像)并行加载并在需要时执行(如CSS).

或者是这样的:

浏览器解析html(DOM)并获取数组或类似堆栈结构的外部资源.加载html后,浏览器开始并行加载结构中的外部资源并执行,直到加载所有资源.然后,根据JS,DOM将根据用户的行为进行更改.

任何人都可以详细解释当你得到html页面的响应时会发生什么?这在不同的浏览器中有所不同?关于这个问题的任何参考?

谢谢.

编辑:

我用Firebug在Firefox上做了一个实验.它显示如下图: 替代文字

mau*_*ris 271

根据你的样本,

<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>
Run Code Online (Sandbox Code Playgroud)

大致的执行流程大致如下:

  1. 下载HTML文档
  2. 开始解析HTML文档
  3. HTML解析到达 <script src="jquery.js" ...
  4. jquery.js 下载并解析
  5. HTML解析到达 <script src="abc.js" ...
  6. abc.js 下载,解析并运行
  7. HTML解析到达 <link href="abc.css" ...
  8. abc.css 下载并解析
  9. HTML解析到达 <style>...</style>
  10. 解析和定义内部CSS规则
  11. HTML解析到达 <script>...</script>
  12. 内部Javascript被解析并运行
  13. HTML解析到达 <img src="abc.jpg" ...
  14. abc.jpg 下载并显示
  15. HTML解析到达 <script src="kkk.js" ...
  16. kkk.js 下载,解析并运行
  17. HTML文档的解析结束

请注意,由于浏览器的行为,下载可能是异步和非阻塞的.例如,在Firefox中,此设置限制了每个域的同时请求数.

此外,根据组件是否已被缓存,可能不会在近期请求中再次请求该组件.如果组件已缓存,则将从缓存而不是实际URL加载组件.

解析结束并且文档已准备好并加载时,将onload触发事件.因此,当onload被解雇时,$("#img").attr("src","kkk.png");运行.所以:

  1. 文档准备就绪,onload被触发.
  2. Javascript执行命中 $("#img").attr("src", "kkk.png");
  3. 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>
Run Code Online (Sandbox Code Playgroud)

解析器将进行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>
Run Code Online (Sandbox Code Playgroud)

因为解析脚本时,#mydiv仍未定义元素.相反,这将工作:

<div id="mydiv">Hello World</div>
<script type="text/javascript">/* <![CDATA[ */
  alert($("#mydiv").html());
/* ]]> */</script>
Run Code Online (Sandbox Code Playgroud)

要么

<script type="text/javascript">/* <![CDATA[ */
  $(window).ready(function(){
                    alert($("#mydiv").html());
                  });
/* ]]> */</script>
<div id="mydiv">Hello World</div>
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.但是你提到*由于浏览器*的行为,下载可能是异步和非阻塞的,所以可以在asyn中下载哪种组件(以FF作为实例)?`<script>`会阻止其他组件,对吧?有关每个浏览器的规范的任何参考? (4认同)
  • 在DOM完成时触发$(document).ready(),而不是在加载所有页面组件时触发 (4认同)
  • 只是为了澄清...常规window.onload发生在#17之后......那么#jquery的$(document).ready()的代码是什么运行的?#12?但是DOM本身加载到#1对吗? (3认同)
  • @Pierre by page components我指的是DOM - > DOM中的任何组件. (2认同)

小智 33

1)下载HTML.

2)逐步解析HTML.当达到资产请求时,浏览器将尝试下载资产.大多数HTTP服务器和大多数浏览器的默认配置是并行处理两个请求.IE可以重新配置为并行下载无限数量的资产.Steve Souders已经能够在IE上并行下载超过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的大小.通过将页面权重平均为180k,仅使用HTML,您就不会对用户体验任何好处.许多开发人员订阅了一些谬论,即用户在6纳秒内决定页面内容的质量,然后从他的服务器清除DNS查询并在不满意时烧毁他的计算机,因此他们提供了最美好的可能页面250k的HTML.保持您的HTML简短和甜蜜,以便用户可以更快地加载您的页面.没有什么能像快速响应的网页那样改善用户体验.

  • *将CSS指令整合到尽可能少的元素中引用*听起来很奇怪.如果我需要设计三个元素,我需要准确引用三个元素.我不能参考一个十号,我可以吗?或详细说明 (2认同)

tah*_*e09 12

在Firefox中打开您的页面并获取HTTPFox插件.它会告诉你所需要的一切.

在archivist.incuito上找到了这个:

http://archivist.incutio.com/viewlist/css-discuss/76444

当您第一次请求页面时,您的浏览器会向服务器发送GET请求,该服务器会将HTML返回给浏览器.然后浏览器开始解析页面(可能在返回所有页面之前).

当它找到对外部实体的引用时,例如CSS文件,图像文件,脚本文件,Flash文件或页面外部的任何其他内容(无论是否在同一服务器/域上),它都准备进行对该资源的进一步GET请求.

但是,HTTP标准指定浏览器不应向同一域发出两个以上的并发请求.因此,它将每个请求放入队列中的特定域,并且在返回每个实体时,它将启动该域的队列中的下一个.

返回实体所需的时间取决于其大小,服务器当前正在经历的负载以及运行浏览器的计算机与服务器之间的每台计算机的活动.对于每个请求,这些机器的列表原则上可以是不同的,只要一个图像可能从英国经过大西洋从美国到达我,而来自同一服务器的另一个图像通过太平洋,亚洲和欧洲出来,这需要更长的时间 因此,您可能会得到如下所示的序列,其中页面(按此顺序)引用三个脚本文件,以及五个不同大小的图像文件:

  1. GET script1和script2; script3和images1-5的队列请求.
  2. script2到达(它比script1小):GET script3,queue images1-5.
  3. script1到了; GET image1,队列图像2-5.
  4. image1到达,GET image2,队列图像3-5.
  5. 由于网络问题,script3无法到达 - 再次GET脚本3(自动重试).
  6. image2到了,script3仍然不在这里; GET image3,队列图像4-5.
  7. 图像3到达; GET image4,队列image5,script3仍然在路上.
  8. image4到了,GET image5;
  9. image5到了.
  10. script3到了.

简而言之:任何旧订单,取决于服务器正在做什么,互联网的其余部分正在做什么,以及是否有任何错误并且必须重新获取.这看起来似乎是一种奇怪的做事方式,但如果没有这样做的话,互联网(不仅仅是WWW)就无法以任何程度的可靠性工作.

此外,浏览器的内部队列可能无法按照它们在页面中出现的顺序获取实体 - 任何标准都不需要它.

(哦,不要忘记在浏览器和ISP使用的缓存代理中缓存,以减轻网络负载.)


a p*_*erd 6

如果您因为想要加快网站速度而问这个问题,请查看雅虎关于加速网站最佳实践的页面.它有很多加速您网站的最佳实践.