本博客所有內容采用 Creative Commons Licenses 許可使用. 引用本內容時,請保留 朱濤, 出處 ,並且 非商業 .
完成了若干個基於WEB的項目, 也了解了從前端的js,css,html到後端python/php等, 二者如何交互, 最終浏覽器如何執行, 這些在心裡也已經很明確了. 不過一個問題一直萦繞在心中,那就是:
一個html有若干個外部資源(js,css,flash,image等),這些請求是何時下載的,又是何時執行的?
不清楚,不明白, 所以也就不知道我寫的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> <link rel="stylesheets" type="text/css" href="/static/abc.css"></link> <script> $(document).ready(function(){ $("#img").attr("src", "/static/kkk.png"); }); </script> </head> <body> <div> <img id="img" src="/static/abc.jpg" style="width:400px;height:300px;"/> <script src="/static/kkk.js" type="text/javascript"></script> </body> </html>
它有如下幾種資源:
總共是6個http request.
在分析之前,我們來看看firefox對這個html請求的結果, 如下圖:
我們再看看chrome(linux)對這個html的請求結果,如下圖(圖比較小,可以在新標簽中打開):
我們先分析下,然後再去說明這2種請求結果的不同.
首先說明下面這些描述主要是基於自己google, 咨詢朋友和在 SO 和 IRC 上獲得, 我並沒有閱讀相關的spec(當然我很想閱讀,如果知道相關spec的朋友請留言謝謝), 不能保證其正確性和准確性,風險自擔 :D.
基於相關的調研, 我的理解為, 對於一個URI請求, 浏覽器會按照下面的請求和執行順序進行:
一個請求可以同時有多少個connection(線程), 取決於不同的浏覽器, http1.1 標准中規定的是對於同一個server/proxy(也就是hostname) 不超過2個connection, 但是在實際的浏覽器實現中, 具體如下:
Firefox 2: 2 Firefox 3: 6 Opera 9.26: 4 Opera 9.5 beta: 4 Safari 3.0.4 Mac/Windows: 4 IE 7: 2 IE 8: 6
所以請根據這個實際情況來思考上面的下載順序.
然後我們看執行順序(js的執行, css的應用等):
在實際的浏覽器中, 一般遇到<script>標簽會自動block住其它線程的下載, 如firefox, 這也是為什麼 在web開發中常常推薦將<script>標簽置於</body>之前的原因.
但是並非所有的浏覽器都block, 如chrome並不會block住其它的connection. 所以具體的load還需要參考具體的浏覽器實現.
建議, 將<script></script>標簽置於</body>之前, 這樣可以在大多數情況下都得到較好的性能.
我們回過頭來看下上面2個圖中的請求響應圖.
有如下特征:
有如下特征:
你可能會奇怪如果js可以並行下載,那麼可能位於DOM下面的代碼會先執行, 首先可以肯定的是 即使下面的js先完成下載,也不會影響到整體的從上到下的執行順序,浏覽器會維護這種順序的關系, chrome的這種方式也是未來浏覽器的一種趨勢, 而這也是為什麼chrome能夠更快的原因之一.
在提出這個問題後,我便多方入手, 向朋友咨詢, 向 SO 提出問題, 甚至去Firefox的 IRC 進行了提問,
回答的朋友還都是很耐心的, 不過, 他們大多向我問了一個問題 做WEB開發, 你為什麼要了解這些細節.
對於這樣的問題,我還是比較納悶的, 我一直認為 一個好的程序員,不僅需要知道how, 還要知道what, 甚至why,
知道how,只說明你是一個合格的碼工,只會簡單地使用別人提供的東西來開發.
知道what, 說明你開始去關注背後是如何實現的, 隨著時間推進, 這時候你會逐漸成為一個有經驗的程序員.
知道why, 說明你開始向hacker的路邁進了, 開始逐步走向了技術牛人的路線了,長此以往你會有很大的成長的. 參考 How To Become A Hacker.
讓我們去享受細節,本質的快樂吧,而不是只停留在我會的層面那麼表面的快樂.
浏覽器是各大廠商搶占的市場,無論是自主(Firefox, chrome, IE, Opera, Safari)或者基於一定的內核(遨游, 搜狗, TT, 360等), 但是可以肯定的是浏覽器會更加強大, 遵守規范, 更快的響應等, 而我們WEB程序員的日子也會好過很多.
本文部分細節還是比較含糊, 後面可能還會在寫一篇文章來進行更徹底,清晰的說明.
歡迎討論.
這次是不惜血本了, 之前積累了快400的 SO reputation score, 一下壓出去了150個來尋找最滿意的答案.
具體大家可以參考:
Load and execution sequence of a web page?
帖子中有較詳細的回答,可以作為參考.