覽器的工作機制,一句話概括起來就是:web瀏覽器與web服務器之間通過HTTP協議進行通信的過程。所以,C/S之間握手的協議就是HTTP協議。瀏覽器接收完畢開始渲染之前大致過程如下:
從瀏覽器地址欄的請求鏈接開始,瀏覽器通過DNS解析查到域名映射的IP地址,成功之后瀏覽器端向此IP地址取得連接,成功連接之后,瀏覽器端將請 求頭信息 通過HTTP協議向此IP地址所在服務器發起請求,服務器接受到請求之后等待處理,最后向瀏覽器端發回響應,此時在HTTP協議下,瀏覽器從服務器接收到 text/html類型的代碼,瀏覽器開始顯示此html,并獲取其中內嵌資源地址,然后瀏覽器再發起請求來獲取這些資源,并在瀏覽器的html中顯示。
離我們最近并能直接顯示一個完整通信過程的工具就是Firebug了,看下圖:
其中黃色的tips浮層告訴了我們”colorBox.html”從發起請求到關閉連接整個過程中每個環節的時長(域名解析 -> 建立連接 -> 發起請求 -> 等待響應 -> 接收數據),點擊該請求,可以獲得HTTP的headers信息,包含響應頭信息與請求頭信息,如:
//響應頭信息 HTTP/1.1 304
Server: Apache/2.2.4 (Win32) PHP/5.2.1 Connection: Keep-Alive Keep-Alive: timeout=5, max=100 Etag: "1e483-1324-a86f5621"
//請求頭信息 GET /Docs/eva/api/colorBox.html HTTP/1.1 Host: ued.com User-Agent: Mozilla/5.0
Firefox/3.6.13 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-cn,zh;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Referer: http://ued.com/Docs/ If-Modified-Since: Thu, 17 Feb 2011 10:14:07 GMT If-None-Match: "1e483-1324-a86f5621" Cache-Control: max-age=0
另外,ajax異步請求同樣遵循HTTP協議,原理大同小異。
瀏覽器加載顯示html頁面內容的順序
我們經常看到瀏覽器在加載某個頁面時,部分內容先顯示出來,又有些內容后顯示。那么瀏覽器加載顯示html究竟是按什么順序進行的呢?
其實瀏覽器加載顯示html的順序是按下面的順序進行的:
1、IE下載的順序是從上到下,渲染的順序也是從上到下,下載和渲染是同時進行的。
2、在渲染到頁面的某一部分時,其上面的所有部分都已經下載完成(并不是說所有相關聯的元素都已經下載完)。
3、如果遇到語義解釋性的標簽嵌入文件(JS腳本,CSS 劍 敲創聳盜E的下載過程會啟用單獨連接進行下載。
4、并且在下載后進行解析,解析過程中,停止頁面所有往下元素的下載。
5、樣式表在下載完成后,將和以前下載的所有樣式表一起進行解析,解析完成后,將對此前所有元素(含以前已經渲染的)重新進行渲染。
6、JS、CSS中如有重定義,后定義函數將覆蓋前定義函數。
Firefox處理下載和渲染順序大體相同,只是在細微之處有些差別,例如:iframe的渲染
如果你的網頁比較大,希望部分內容先顯示出來,粘住瀏覽者,那么你可以按照上面的規則合理的布局你的網頁,達到預期的目的。
JS的加載
不能并行下載和解析(阻塞下載)
當 引用了JS的時候,瀏覽器發送1個jsrequest就會一直等待該request的返回。因為瀏覽器需要1個穩定的DOM樹結構,而JS中很有可能有代 碼直接改變了DOM樹結構,比如使用 document.write 或 appendChild,甚至是直接使用的location.href進行跳轉,瀏覽器為了防止出現JS修改DOM樹,需要重新構建DOM樹的情況,所以 就會阻塞其他的下載和呈現.
為了更清楚的顯示頁面元素的加載順序,動手寫了一個程序,程序對頁面中的每個元素都延遲10秒。
程序的位置在見附件。
首先查看TestHtmlOrder.aspx這個頁面,使用HttpWatcher來檢測頁面元素的加載。
從下面的圖中可以看到加載順序。
IE首先加載了主頁面TestHtmlOrder.aspx,
下載了主頁面后,頁面首先顯示的是“紅色劍靈”、“藍色劍靈”幾個字,但此時顯示的是只是黑色字體,沒有樣式,因為樣式還沒有下載下來。
接下來頁面中的標簽是JS標簽,屬于嵌入文件,因此IE需要將其下載下來。這有兩個文件,雖然IE同時能夠和WebServer建立兩個鏈接,但是此時并沒有使用兩個連接,而是使用一個連接,在下載完成后,接下來才下載另外一個文件。
究其原因,是因為JS包含了語法定義,在第二個文件里面的函數可能用到了第一個文件里面的變量和函數,IE沒有辦法判斷,或者需要很耗時的判斷,才 能判斷文件下載的先后順序。而在解釋方面,IE對JS文件是下載一個,解釋一個(可以執行文件TestJsOrder2.aspx)。如果先下載的是第二 個文件,此時就會發生解釋錯誤。因此需要開發者自己在放置JS文件位置時,按先后順序放好,IE依次下載進行解釋。后面的函數覆蓋前面的函數定義
在下載完成后,我們看到helloWorld,helloworld2,開始順序執行。而此時字體的樣式表和圖片仍然沒有下載下來。
在helloWorld,helloWorld2執行過程時,此時頁面停留在函數執行的中斷點(alert部分)。此時IE并沒有去下載CSS的文件。由此說明JS函數的執行會阻塞IE的下載。
接下來我們看到CSS文件的下載也是使用了一個連接,也是串行下載。其串行下載的原因和JS串行下載原因是一樣的。
在兩個CSS文件下載過程中,我們看到“紅色劍靈”,“藍色劍靈”依次變為紅色和藍色,兩者顏色的轉換時間相差在10秒,說明樣式文件和JS文件一樣是下載完一個解析一個的。
現在轉到TestCssOrder.aspx看一下,可以看到 開始時“紅色劍靈”,“紅色強壯劍靈”,顯示為紅色,過了10秒“藍色劍靈”顯示為藍色,再過10秒,“紅色強壯劍靈”字體變粗了,同時“紅色強壯劍靈 2”開始出現。在剛開始“紅色劍靈”,“紅色強壯劍靈”顯示紅色時,第三個樣式還沒有下載下來,此時IE使用已經下載到樣式對上面的元素渲染了一遍,此時 雖然“紅色劍靈”,“紅色強壯劍靈”樣式定義不同,但是顯示效果一樣。第三個文件下載后,此時IE又重新對“紅色強壯劍靈”渲染了一遍,此時其變為加粗, 以上所有的文件加載并且渲染完成后,開始渲染下面的標簽“紅色強壯劍靈2”
有一點需要證明:在IE使用樣式對標簽進行渲染時,是不是停止了其他頁面元素的下載?原來我想通過加長渲染時間(利用濾鏡,將標簽元素數目增大)來檢測,不過沒有驗證成功。只是從JS函數的執行推斷CSS的渲染也是如此。
接下來看到的是圖片文件下載,此時看到的是兩個圖片同時開始下載,而且是下載完成后,立即在頁面上開始顯示,直到所有的圖片下載完成。
注:一個測試文件在網絡傳輸上所花費時間的辦法。
首先需要明白檢測中w ait值的意義:wait=服務器所花時間 + 網絡時間
服務器所花時間我們可以用Thread.Sleep(10000);來讓其休息10s,
比如這個:
由此大概可以計算出 10.002-10=0.002秒,這就是大概在網絡上所花的時間。
端面試瀏覽器是如何渲染頁面的,可以從以下幾個步驟進行分析:
1.用戶輸入一個URL的時候,瀏覽器會發送一個請求,請求URL對應的資源。
2.瀏覽器的HTML解析器會將這個文件解析,并且構建成一棵DOM樹。
3.自上而下,遇到任何樣式(link、style)與腳本(script)都會阻塞(外部樣式不阻塞后續外部腳本的加 載)。
1.在構建DOM樹的時候,遇到JS和CSS元素,HTML解析器就換將控制權轉讓給JS解析器或者是CSS解析器。
優先級:瀏覽器默認設置<用戶設置<外部樣式<內聯樣式<HTML中的style樣式;
1.JS解析器或者是CSS解析器解析完這個元素時候,HTML又繼續解析下個元素,直到整棵DOM樹構建完成
2.DOM樹構建完之后,瀏覽器把DOM樹中的一些不可視元素去掉,然后與CSSOM合成一棵render樹。
3.將 CSS 與 DOM 合并,構建渲染樹(Render Tree)
1.接著瀏覽器根據這棵render樹,計算出各個節點(元素)在屏幕的位置。這個過程叫做layout,輸出的是一棵layout樹。
2.布局和繪制,重繪(repaint)和重排(reflow)
3.最后瀏覽器根據這棵layout樹,將頁面渲染到屏幕上去。
在渲染過程中,瀏覽器會根據HTTP響應中的編碼方式(通過是UTF8),解析字節數據,得到一些字符,然后根據這些字符來渲染頁面。
#挑戰30天在頭條寫日記#
主有點搞錯了,現在的服務端渲染跟以前的服務端渲染是完全不一樣的.
首先介紹一下以前的傳統模式:服務端渲染,代表是PHP這類,那時候前端只是寫網頁的,偶爾寫點ajax,但是不多,大部分靠服務器查找數據然后渲染出來頁面發送給瀏覽器展示,每次跳轉都要從新執行一遍這個邏輯.因此挺消耗服務端的資源的.
后來H5出來后才有所改觀,單頁應用也逐漸興起,Nodejs使前端可以脫離瀏覽器,進軍服務器寫后端代碼.
非常多的人按捺不住內心的激動,終于不被人稱為"切圖仔"了,而且前端人群非常的多,此時我寫這個回答的時候,NPM上的包就已經有654,218個了!
移動端開始興起,網站的加載速度也開始變得重要,各個網站也開始考慮用戶的感受,如果能降低用戶的流量成本,就能使用戶更快的進入頁面,停留的時間也就更久,更能為公司帶來經濟效益,因此這變得越來越重要.
如果還是以前的傳統方式,每次跳轉都要重新加載頁面下載數據,那么用戶肯定受不了等待從而離開,損失是非常嚴重的,因此這時候的人瞄準了H5,使用H5構建的單頁應用開始越來越多,只需要加載一次網頁,后面就不需要再次下載,而且還可以做緩存,減少用戶的流量費用.
但是前端很快發現了一個嚴重的問題,爬蟲是不認js的,也就是說你無法給自己的網站做SEO.
SEO 搜索引擎優化是一種利用搜索引擎的搜索規則來提高目前網站在有關搜索引擎內的自然排名的方式.當百度或者其他搜索引擎的爬蟲來到你的網站的時候,它發現這里面什么東西都沒有,就只有一些css和js資源連接,但是它并不執行你的js,因此是無法獲取到你的網站信息的,它就無法記錄你的網站信息,用戶使用搜索引擎的時候也就無法查詢到關于你網站的數據信息,這是很嚴重的問題,你的網站流量會斷崖式下跌.
因此針對這個問題,前端想到了一個預處理方案:服務器端渲染(SSR).
前端使用Nodejs搭建服務器,然后在用戶訪問的時候預先執行一些頁面中js的邏輯,渲染成HTML,將它們直接發送到瀏覽器,很多流行的開源前端框架已經集成了這類方式,比如Vue.js,React.js,Angular.js等等.
與傳統 SPA(Single-Page Application - 單頁應用程序)相比,服務器端渲染(SSR)的優勢主要在于:
1.更好的 SEO,由于搜索引擎爬蟲抓取工具可以直接查看完全渲染的頁面。如果 SEO 對你的站點至關重要,而你的頁面又是異步獲取內容,則你可能需要服務器端渲染(SSR)解決此問題。
2.更快的內容到達時間,特別是對于緩慢的網絡情況或運行緩慢的設備.無需等待所有的 JavaScript 都完成下載并執行,才顯示服務器渲染的標記,所以你的用戶將會更快速地看到完整渲染的頁面.通常可以產生更好的用戶體驗,并且對于那些時間就是金錢的應用程序而言,服務器端渲染(SSR)至關重要。
使用服務器端渲染(SSR)時還需要有一些權衡之處:
1.涉及構建設置和部署的更多要求.與可以部署在任何靜態文件服務器上的完全靜態單頁面應用程序(SPA)不同,服務器渲染應用程序,需要處于 Node.js server 運行環境.
2.在 Node.js 中渲染完整的應用程序,顯然會比僅僅提供靜態文件的 server 更加大量占用 CPU 資源,因此如果你預料在高流量環境下使用,請準備相應的服務器負載,并明智地采用緩存策略.
在對你的應用程序使用服務器端渲染(SSR)之前,你應該問第一個問題是否真的需要它.這主要取決于內容到達時間對應用程序的重要程度.例如,如果你正在寫一個活動頁,那么初始加載時的額外幾百毫秒并不重要,這種情況下去使用服務器端渲染(SSR)肯定是一個小題大作之舉.然而,內容到達時間(time-to-content)要求是絕對關鍵的指標,在這種情況下,服務器端渲染(SSR)可以幫助你實現最佳的初始加載性能.
*請認真填寫需求信息,我們會在24小時內與您取得聯系。