1. 程式人生 > >HTML檔案中元素的載入順序

HTML檔案中元素的載入順序

不清楚,不明白, 所以也就不知道我寫的js究竟何時執行的, 也就不知道為什麼很多高效能的建議是要將js置於一個 html底端的</body>之前.

如果你也不是很明確,請來和我一起學習吧.

具體分析

首先我們來看一個示例的html頁面,如下:

<html><head><script src="/static/jquery.js"type="text/javascript"></script><script src="/static/abc.js"type="text/javascript"></script><linkrel="stylesheets"type="text/css"href="/static/abc.css"></link><script> $(document).ready(function(){ $("#img").attr("src", "/static/kkk.png"); }); </script></head><body><div><imgid="img"src="/static/abc.jpg"style="width:400px;height:300px;"/><script src="/static/kkk.js"type="text/javascript"></script></body></html>

它有如下幾種資源:

  1. 3個外部js檔案,1個inline js程式碼
  2. 1個外部css檔案, 1個inline css程式碼
  3. 1個image檔案,及1個js請求的image

總共是6個http request.

在分析之前,我們來看看firefox對這個html請求的結果, 如下圖:

我們再看看chrome(linux)對這個html的請求結果,如下圖(圖比較小,可以在新標籤中開啟):

我們先分析下,然後再去說明這2種請求結果的不同.

請求分析

首先說明下面這些描述主要是基於自己google, 諮詢朋友和在 SO 和 IRC 上獲得, 我並沒有閱讀相關的spec(當然我很想閱讀,如果知道相關spec的朋友請留言謝謝), 不能保證其正確性和準確性,風險自擔 :D.

基於相關的調研, 我的理解為, 對於一個URI請求, 瀏覽器會按照下面的請求和執行順序進行:

  1. 一個執行緒對DOM進行下載(也就是html, 而不去管html中的外部資源)
  2. 另外一個執行緒會開始分析已經下載的DOM, 並開始下載其中的外部資源(如js, css, image等)
  3. 第三個執行緒(如果有的話)會去下載2正在下載的以外的外部資源
  4. 如果允許更多的連線, 更多的執行緒會繼續下載其它資源

一個請求可以同時有多少個connection(執行緒), 取決於不同的瀏覽器, http1.1 標準中規定的是對於同一個server/proxy(也就是hostname) 不超過2個connection, 但是在實際的瀏覽器實現中, 具體如下:

Firefox 2: 2Firefox 3: 6Opera 9.26: 4Opera 9.5 beta: 4Safari 3.0.4 Mac/Windows: 4IE 7: 2IE 8: 6

所以請根據這個實際情況來思考上面的下載順序.

然後我們看執行順序(js的執行, css的應用等):

  1. 只要瀏覽器"看到了"了js程式碼,它就會執行
  2. 瀏覽器是從上到下,一行一行地執行
  3. 如果js程式碼位於一個函式或者物件中,則只有當函式或者物件被呼叫時才會執行
  4. 而所謂的direct code(不處於函式或者物件中的程式碼),則會從上到下順序執行
  5. 當css檔案下載完成時, 相應的樣式也會應用到DOM上
  6. onload或者jquery的$(document).ready()是在DOM下載完成後執行

在實際的瀏覽器中, 一般遇到<script>標籤會自動block住其它執行緒的下載, 如firefox, 這也是為什麼 在web開發中常常推薦將<script>標籤置於</body>之前的原因.

但是並非所有的瀏覽器都block, 如chrome並不會block住其它的connection. 所以具體的load還需要參考具體的瀏覽器實現.

建議, 將<script></script>標籤置於</body>之前, 這樣可以在大多數情況下都得到較好的效能.

對Firefox和chrome的請求分析

我們回過頭來看下上面2個圖中的請求響應圖.

Firefox

有如下特徵:

  1. 首先下載html
  2. html下載完成後, 從上到下依次下載外部檔案(js, css,img)
  3. js會block其它外部檔案的下載
  4. 其它檔案會並行下載
chrome

有如下特徵:

  1. 首先下載html
  2. 從上到下依次下載外部檔案(js,css,img)
  3. 各個資源的下載順序是並行的

你可能會奇怪如果js可以並行下載,那麼可能位於DOM下面的程式碼會先執行, 首先可以肯定的是 即使下面的js先完成下載,也不會影響到整體的從上到下的執行順序,瀏覽器會維護這種順序的關係, chrome的這種方式也是未來瀏覽器的一種趨勢, 而這也是為什麼chrome能夠更快的原因之一.

有意思的一個插曲

在提出這個問題後,我便多方入手, 向朋友諮詢, 向 SO 提出問題, 甚至去Firefox的 IRC 進行了提問,

回答的朋友還都是很耐心的, 不過, 他們大多向我問了一個問題 做WEB開發, 你為什麼要了解這些細節.

對於這樣的問題,我還是比較納悶的, 我一直認為 一個好的程式設計師,不僅需要知道how, 還要知道what, 甚至why,

知道how,只說明你是一個合格的碼工,只會簡單地使用別人提供的東西來開發.

知道what, 說明你開始去關注背後是如何實現的, 隨著時間推進, 這時候你會逐漸成為一個有經驗的程式設計師.

知道why, 說明你開始向hacker的路邁進了, 開始逐步走向了技術牛人的路線了,長此以往你會有很大的成長的. 

讓我們去享受細節,本質的快樂吧,而不是隻停留在我會的層面那麼表面的快樂.

結論

瀏覽器是各大廠商搶佔的市場,無論是自主(Firefox, chrome, IE, Opera, Safari)或者基於一定的核心(遨遊, 搜狗, TT, 360等), 但是可以肯定的是瀏覽器會更加強大, 遵守規範, 更快的響應等, 而我們WEB程式設計師的日子也會好過很多.

本文部分細節還是比較含糊, 後面可能還會在寫一篇文章來進行更徹底,清晰的說明.

歡迎討論.

相關推薦

HTML檔案元素載入順序

不清楚,不明白, 所以也就不知道我寫的js究竟何時執行的, 也就不知道為什麼很多高效能的建議是要將js置於一個 html底端的</body>之前. 如果你也不是很明確,請來和我一起學習吧. 具體分析 首先我們來看一個示例的html頁面,如下: <html><head>&l

JavaScript—分析JavaScript在Html頁面載入順序

js程式碼執行順序比較的形象,使用者可以直觀的感受這種執行順序。但是,js程式碼的執行順序是比較複雜的。有時候我們會把js程式碼寫在html裡面,而html文件在瀏覽器中解析的過程是這樣:瀏覽器按照文件流從上到下逐步解析頁面結構和資訊。js程式碼作為嵌入的指令碼

動態引入的外部 JS 檔案在各瀏覽器載入順序不一致問題解決

標準參考 無。 問題描述 頁面開發過程中,為了避免頁面載入時引入過多外部 JS 檔案,導致阻塞頁面內容下載及渲染的情況出現。將會採用頁面內容載入完成後,動態載入外部 JavaScript 檔案的方法來解決此類問題。但是,需要注意的是,常用動態插入外部指令碼檔案的方法在各瀏覽器中的執行順序

html檔案元素

document :代表整個html文件,可以被用來訪問頁面中的所有元素。 Anchor:代表<a>元素,表示html中的超連結,錨通過href屬性實現。可以通過document中的anchors[ ]實現引用。 Area:代表影象對映中的,<area&g

UIWebView載入本地HTML檔案有本地圖片的索引

//    013-11-18 16:58:23.959 Sports[480:907] imgPath:/var/mobile/Applications/D0233988-9785-465A-BF95-81DF334B367C/Sports.app/SPBGLogo.png //    2013-11-1

怎麽打亂List元素順序

pan clas targe ++ 程序 rgs print ref blog 使用Collections類中shuffle隨機打亂List內部元素順序 原文地址:http://blog.csdn.net/warren2013/article/details/174147

使用JavaScript來選擇性改變HTML DOM元素的樣式,使用if語句。

javascrip 使用 style color () return cti .get turn <style> #p1 { color: red; } </style> </head> <body> <butto

SSM整合Freemarker並在html檔案使用freemarker標籤

FreeMarker是一個用Java語言編寫的模板引擎。它基於模板來生成文字輸出。Freemarker與web容器無關,即在web執行時,它並不知道servlet或者HTTP,它不僅可以用作表現層的實現技術,而且還可以用於生成XML,JSP或Java等。目前在企業中,主要用freemarker做靜態頁面或是頁

python學習之網站的編寫(HTML,CSS,JS)(十一)----------如何利用其它html檔案的CSS(也就是可以將共同的地方提取出來,放大一個檔案,利於使用)

首先說一下它的具體用處,我們已經知道,當我們寫一個html檔案的時候,不同的標籤想用相同的版式的時候,我們可以將它提取出來,然後再用一些選擇器進行應用,比如class選擇器。但是,但我們編寫多個html檔案中的時候,多個檔案都想用一些相同的版式該怎麼辦呢? 那麼就引入了這種連線的方式,首先寫一個

有關jsponclick事件無效的原因,以及jsp頁面載入順序的問題

今天在寫jsp頁面時遇到一個有關onclick事件無效的問題,在這裡分享一下: <body> <div> <input type="text" id="name"/> </div> <div id="hin

html檔案flash視訊格式(flv、swf)檔案的嵌入方法

flash檔案的格式:.FLV 和 .SWF  flash視訊格式有兩種副檔名可以使用:.flv和.swf。他們有什麼不同呢?  (1)一個.flv檔案(flash視訊)是基於圖片的視訊流和音訊。如果你在執行一個流服務,flv將是一個好的選擇。上游條件是,這個檔案的任何部分可以被客戶終端訪問,並且任何時間不

Spring 配置檔案 元素 屬性 說明

<beans /> 元素 該元素是根元素。<bean /> 元素的屬性 default-init // 是否開啟懶載入。預設為 false default-dependency-check // 預設為 none default-autowire // 是否自動轉配。預設

html檔案flash格式(flv、swf)檔案的嵌入

  flash檔案的格式:.FLV 和 .SWF flash視訊格式有兩種副檔名可以使用:.flv和.swf。他們有什麼不同呢? (1)一個.flv檔案(flash視訊)是基於圖片的視訊流和音訊。如果你在執行一個流服務,flv將是一個好的選擇。上游條件是,這個檔案的任何部分

AndroidManifest.xml檔案元素用法

AndroidManifest.xml檔案中<activity>元素用法 語法 <activity android:allowEmbedded=["true" | "false"] android:all

將小檔案/圖片嵌入html檔案

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBw

在php模版檔案html檔案引入js,css檔案錯誤解決

1,html檔案引入js一些資原始檔時候:可以寫相對路徑來引入,<script src="../lib/layer/layer.js"></script>     <script  src="../lib/jquer.min.js">&l

為什麼在.html檔案嵌入php程式碼沒效果

由於自學,很多常識都不知道、都不理解…… 問題: 如果是.html的字尾不會顯示php的列印,把字尾更改為.php後恢復正常(前提:伺服器搭建好) <!DOCTYPE html> <html lang="en"> &

Tomcat啟動時載入資料到快取[web.xmllistener載入順序]

最近用到在Tomcat伺服器啟動時自動載入資料到快取,這就需要建立一個自定義的快取監聽器並實現ServletContextListener介面,並且在此自定義監聽器中需要用到Spring的依賴注入功能.在web.xml檔案中監聽器配置如下: <li

$(function(){})與!function(){}()在頁面載入順序比較

大家都知道 $(function(){}); 是 $(document).ready(function(){}) 的簡寫,它是在頁面DOM載入完畢之後自動執行。 !function(){}(); 是一個匿名函式,而且類似這樣函式的寫法還有好多種,比

SqlMapConfig.xml --- 在spring配置檔案自動載入的mybatis檔案

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/d