摘要:為了更加高效的網(wǎng)絡(luò)層,它需要不僅僅只是扮演套接字管理員的角色。用套接字池來組織套接字,以源來分組套接字,每個套接字池強制限制其連接數(shù)和安全約束。協(xié)商是一個為計算機(jī)網(wǎng)絡(luò)提供通信安全的加密協(xié)議。
原文請查閱這里,略有改動,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。
本系列持續(xù)更新中,Github 地址請查閱這里。
這是 JavaScript 工作原理的第十二章。
正如在之前關(guān)于渲染引擎的文章中所講的那樣,我們相信好的和偉大的 JavaScript 開發(fā)者之間的差別在于后者不僅僅只是理解了語言的具體細(xì)節(jié)還了解其內(nèi)部構(gòu)造和運行環(huán)境。
網(wǎng)絡(luò)簡史49 年前,ARPAnet 誕生了。它是早期的報文分組交換網(wǎng)絡(luò)及第一個實現(xiàn) TCP/IP 協(xié)議套件的網(wǎng)絡(luò)。該網(wǎng)絡(luò)連通了加利福亞大堂和斯坦福研究所。20 年后,Tim Berners-Lee 分發(fā)了一個后來為人所熟知的萬維網(wǎng)的 『Mesh』草案。在 49 年的時間里,網(wǎng)絡(luò)走過了一段漫長的旅程,從僅僅只是是兩臺電腦間交換數(shù)據(jù)報文到至少 7500 萬臺服務(wù)器,38 億人使用互聯(lián)網(wǎng)以及 13 億個網(wǎng)站。
本文將試著分析現(xiàn)代瀏覽器使用哪些技術(shù)來自動提升應(yīng)用性能(有些你甚至不了解),然后著重介紹瀏覽器網(wǎng)絡(luò)層。最后,提供一些讓瀏覽器提升網(wǎng)絡(luò)應(yīng)用程序性能的技巧。
概述現(xiàn)代瀏覽器專門為快速,高效和安全數(shù)據(jù)傳輸?shù)木W(wǎng)絡(luò)應(yīng)用/網(wǎng)站而設(shè)計開發(fā)的。擁有數(shù)以百計的組件運行于各個不同的層級,從進(jìn)程管理和安全沙箱到 GPU 管線,音頻和視頻及其它更多等等,網(wǎng)絡(luò)瀏覽器更類似于一個操作系統(tǒng)而不僅僅只是一個軟件。
瀏覽器的整體性能是由一些大型的組件所決定的,這些組件包括:解析,布局,樣式計算,JavaScript 和 WebAssembly?執(zhí)行,渲染,當(dāng)然還有網(wǎng)絡(luò)堆棧。
一般情況下,工程師們會把網(wǎng)絡(luò)堆棧看成是一個性能瓶頸。經(jīng)常會發(fā)生這樣的情況因為從網(wǎng)絡(luò)抓取所有的資源會堵塞渲染剩下的步驟。為了更加高效的網(wǎng)絡(luò)層,它需要不僅僅只是扮演套接字管理員的角色。在我們看來獲取資源是一個非常簡單的機(jī)制,但是實際上它集成自身的優(yōu)化準(zhǔn)則,接口和服務(wù)的一整套平臺。
網(wǎng)頁開發(fā)者不需要擔(dān)心多帶帶的 TCP 或者 UDP 數(shù)據(jù)包,請求格式化,緩存以及其它正在發(fā)生的一切。瀏覽器會處理這些復(fù)雜的玩意,這樣就可以專注開發(fā)自己的程序。但是,知道其內(nèi)部的原理可以幫助開發(fā)者開發(fā)出更加高效和安全的程序。
本質(zhì)上,當(dāng)用戶開始和瀏覽器發(fā)生交互所產(chǎn)生的情況如下:
用戶在瀏覽器地址欄中輸入 URL 地址。
在網(wǎng)絡(luò)上查找指定 URL 的資源,瀏覽器開始檢查本地和應(yīng)用程序緩存并試著使用本地副本來響應(yīng)資源的請求。
當(dāng)緩存不可用,瀏覽器使用 URL 中的域名然后根據(jù)域名從 DNS 處獲取服務(wù)器的 IP 地址。如果有域名緩存,將不需要進(jìn)行 DNS 查詢。
瀏覽器創(chuàng)建一個 HTTP 報文表明其請求遠(yuǎn)程服務(wù)器的某個網(wǎng)頁。
報文被傳輸?shù)?TCP 層,該層會在 HTTP 報文頭部添加其自身的信息。該信息是保持創(chuàng)建的會話的必要信息。
然后在 IP 層處理報文,該層的主要職責(zé)即找出從用戶發(fā)送報文到遠(yuǎn)程服務(wù)器的路徑。在 HTTP 報文頭部添加該路徑信息。
傳輸報文到遠(yuǎn)程服務(wù)器。
一旦接收到報文,以類似的方式返回響應(yīng)數(shù)據(jù)。
W3C Navigation Timing specification 提供了瀏覽器接口及瀏覽器中每個請求背后的可視化計時和性能數(shù)據(jù)。讓我們?yōu)g覽下這些組件,因為每個組件在獲取最佳用戶體驗方面扮演了重要的角色。
整個網(wǎng)絡(luò)請求過程是相當(dāng)復(fù)雜的并且有許多的層次結(jié)構(gòu),每一層都有可能成為性能瓶頸。這就是為什么瀏覽器使用各種技術(shù)努力提升其性能,以便把整個網(wǎng)絡(luò)通信的性能損耗降至最低。
套接字管理看些新技術(shù)吧:
源-由應(yīng)用程序協(xié)議,域名和端口號的三個部分組成(比如 https, www.example.com, 443)
套接字池-屬于同源的一組套接字(所有的主流瀏覽器都限制套接字池最多只能有 6 個套接字)
JavaScript 和 WebAssembly 禁止開發(fā)者操作多帶帶的網(wǎng)絡(luò)套接字的生命周期,這樣是相當(dāng)?shù)拿髦堑摹_@樣不僅僅可以讓你頭發(fā)少掉點而且可以讓瀏覽器自動優(yōu)化大量的性能,這些性能包括套接字重用,請求優(yōu)化和延遲綁定,協(xié)議協(xié)商,強制連接限制及其它的優(yōu)化措施。
實際上,現(xiàn)代瀏覽器更一步地將請求管理周期從套接字管理中剝離了出來。用套接字池來組織套接字,以源來分組套接字,每個套接字池強制限制其連接數(shù)和安全約束。排隊,優(yōu)先化等待的請求,然后和套接字池中的單個套接字綁定。如果不是服務(wù)器主動關(guān)閉這些連接,多個請求可以自動重用相同的套接字。
由于創(chuàng)建一個新的 TCP 連接會帶來額外的性能開銷,重用連接會為其自帶來極大的性能提升。默認(rèn)情況下,當(dāng)發(fā)起請求的時候,瀏覽器使用所謂的 『keepalive』機(jī)制以節(jié)省創(chuàng)建到服務(wù)器的新連接所耗費的時間。創(chuàng)建一個新的 TCP 連接的平均時間為:
本地請求-23 毫秒
Transcontinental 請求-120 毫秒
Intercontinental 請求-225 毫秒
這樣的架構(gòu)衍生出了一些其它的優(yōu)化方法。請求可以依據(jù)優(yōu)先級來以不同的順序執(zhí)行。瀏覽器可以優(yōu)化所有套接字間的帶寬分配或者它可以創(chuàng)建套接字以等待預(yù)期的請求。
如上所述,這些都是瀏覽器所控制而不用開發(fā)者進(jìn)行干預(yù)。但這并不意味著我們無所事事了。選擇正確的數(shù)據(jù)傳輸所用的網(wǎng)絡(luò)通信模式,類型和頻率,正確的協(xié)議類型以及正確的服務(wù)器堆棧隧道/優(yōu)化對于提升整個程序的性能有著至關(guān)重要的作用。
一些瀏覽器甚至更進(jìn)一步。例如,當(dāng)你使用 Chrome 的時候,當(dāng)用戶使用的時候它會進(jìn)行自我學(xué)習(xí)從而變得更加快速。它基于訪問過的網(wǎng)頁和典型的瀏覽器模式來進(jìn)行學(xué)習(xí),這樣就可以預(yù)期可能的用戶行為且在用戶進(jìn)行任意操作之前進(jìn)行操作。最簡單的例子即當(dāng)用戶懸停在某個鏈接上的時候預(yù)渲染頁面。如果你想學(xué)習(xí)更多關(guān)于 Chrome 優(yōu)化技術(shù)的文章,可以查看 High-Performance Browser Networking 這本書的 https://www.igvita.com/posa/h... 章節(jié)。
網(wǎng)絡(luò)安全和沙箱允許瀏覽器操作多帶帶的套接字有另一個非常重要的目的即:瀏覽器就可以針對不被信任的程序資源強制實施一套一致的安全和政策約束措施。例如,瀏覽器禁止通過 API 直接訪問原始網(wǎng)絡(luò)套接字,因為這樣會導(dǎo)致任意可疑的程序隨意連接任意主機(jī)。瀏覽器也強制連接數(shù)限制以保護(hù)服務(wù)器免受由于客戶端訪問而耗盡其資源。
瀏覽器格式化所有流出的請求以強制格式正確和一致的協(xié)議語義來保護(hù)服務(wù)器。同樣地,瀏覽器會自動解碼響應(yīng)內(nèi)容以保護(hù)用戶免受可疑服務(wù)器的攻擊。
TSL 協(xié)商Transport Layer Security (TLS) 是一個為計算機(jī)網(wǎng)絡(luò)提供通信安全的加密協(xié)議。它廣泛應(yīng)用于大量應(yīng)用程序,其中之一即瀏覽網(wǎng)頁。網(wǎng)站可以使用 TLS 來保證服務(wù)器和網(wǎng)頁瀏覽器之間的所有通信安全。
整個 TLS 握手過程包含以下幾個步驟:
客戶端向服務(wù)器發(fā)送 『Client hello』 信息,附帶著客戶端隨機(jī)值和支持的密碼組合。
服務(wù)器返回給客戶端 『Server hello』信息,附帶著服務(wù)器隨機(jī)值。
服務(wù)器返回給客戶端認(rèn)證證書及或許要求客戶端返回一個類似的證書。服務(wù)器返回『Server hello done』信息。
如果服務(wù)器要求客戶端發(fā)送一個證書,客戶端進(jìn)行發(fā)送。
客戶端創(chuàng)建一個隨機(jī)的 Pre-Master 密鑰然后使用服務(wù)器證書中的公鑰來進(jìn)行加密,向服務(wù)器發(fā)送加密過的 Pre-Master 密鑰。
服務(wù)器收到 Pre-Master 密鑰。服務(wù)器和客戶端各自生成基于 Pre-Master 密鑰的主密鑰和會話密鑰。
客戶端給服務(wù)器發(fā)送一個 『Change cipher spec』的通知,表明客戶端將會開始使用新的會話密鑰來哈希和加密消息。客戶端也發(fā)送了一個 『Client finished』的消息。
服務(wù)器接收到『Change cipher spec』的通知然后使用會話鑰匙來切換其記錄層安全狀態(tài)為對稱加密狀態(tài)。服務(wù)器返回客戶端一個 『Server finished』消息。
客戶端和服務(wù)器現(xiàn)在可以通過建立的安全通道來交換程序數(shù)據(jù)。所有客戶端和服務(wù)器之間發(fā)送的信息都會使用會話密鑰進(jìn)行加密。
每當(dāng)發(fā)生任何驗證失敗的時候,用戶會收到警告。比如服務(wù)器使用自簽名的證書。
同源策略當(dāng)兩個頁面的協(xié)議,端口(如果有指定)以及主機(jī)名都是一樣的則稱為同源。
以下為一些可能包含跨域的資源示例:
里面的 JavaScript 代碼。語法錯誤的錯誤信息僅適用于同源腳本。
的 CSS。由于 CSS 的松散語法規(guī)則,跨域 CSS 要求正確的 Content-Type 頭。各個瀏覽器的限制不同。
圖片
和 媒體文件
,??和? 插件
@font-face 字體。一些瀏覽器允許跨域字體,其它則要求同源字體。
和
以上的列表還遠(yuǎn)遠(yuǎn)不夠;該列表旨在強調(diào)工作中的『最小特權(quán)』原則。瀏覽器只為應(yīng)用程序代碼暴露出其所必需的接口和資源:應(yīng)用提供數(shù)據(jù)和 URL 地址,然后瀏覽器格式化請求及處理每條連接的整個生命周期。
需要注意的是并沒有一個簡單的 『同源策略』概念。
相反,有一系列相關(guān)的機(jī)制來強制限制瀏覽器的 DOM 訪問,cookie 和 會話狀態(tài)管理,網(wǎng)絡(luò)連接和其它組件。
資源和客戶端狀態(tài)緩存最好和最快的請求即不創(chuàng)建請求。在分派一個請求前,瀏覽器自動檢查其資源緩存,進(jìn)行必要的驗證檢查然后當(dāng)指匹配指定的條件時返回一份本地資源拷貝。如果緩存中沒有可用的本地資源,則發(fā)起網(wǎng)絡(luò)請求然后把響應(yīng)內(nèi)容自動放置于緩存中以備之后的訪問(如果這是被允許的)。
瀏覽器自動為每個資源求值緩存指令。
當(dāng)條件允許時,瀏覽器自動重新恢復(fù)過期資源
瀏覽器自動處理緩存和資源回收的大小
管理一個高效和優(yōu)化的資源緩存是非常困難的。謝天謝地,瀏覽器為我們處理了整個復(fù)雜的玩意,而我們所需要做的即保證服務(wù)器返回恰當(dāng)?shù)木彺嬷噶睿幌肓私飧嗫梢钥?客戶端資源緩存 文章。你為網(wǎng)頁上的所有資源添加 Cache-Control,ETag,和 Last-Modified 的響應(yīng)頭信息。
最后,一個經(jīng)常被忽略但至關(guān)重要的瀏覽器功能即其提供了驗證,會話和 cookie 管理。瀏覽器為每個源維護(hù)多帶帶的『cookie jars』,通過提供必要的程序和服務(wù)器接口來讀寫新的 cookie,會話和認(rèn)證數(shù)據(jù),以及自動掛載和處理適當(dāng)?shù)?HTTP 頭來為我們自動處理整個過程。
例子:一個簡單但明了的用來展示瀏覽器的延遲會話狀態(tài)管理的方便性的例子即:多個選項卡或者瀏覽器窗口可以共享一個認(rèn)證會話,反之亦然;一個選項卡中的登出操作可以使所有其它打開窗口的會話失效。
應(yīng)用程序接口和協(xié)議了解了網(wǎng)絡(luò)服務(wù)之后,最終要講到應(yīng)用程序接口和協(xié)議。眾所周知,更底層的結(jié)構(gòu)提供了一組廣泛的重要服務(wù):套接字和連接管理,請求和響應(yīng)處理,各種安全策略,緩存及其它更多的強制措施。每當(dāng)初始化一個 HTTP 請求或者 XMLHttpRequest,一個持久的服務(wù)推事件或者 WebSocket 會話抑或打開一個 WebRTC 連接,我們就是在和部分或者所有這些底層服務(wù)進(jìn)行交互。
沒有單一的最佳協(xié)議或者接口。每個復(fù)雜的程序都會基于不同的要求混合使用不同的傳輸協(xié)議:和瀏覽器緩存的交互,協(xié)議開銷,消息延遲,可靠性,數(shù)據(jù)傳輸類型以及其它。一些協(xié)議擁有低數(shù)據(jù)傳輸延遲的特性(比如服務(wù)器推事件,WebSocket),但是可能不符合其它重要的場合,比如利用瀏覽器緩存或者支持任意情況下的二進(jìn)制數(shù)據(jù)傳輸?shù)哪芰Α?/p> 一些可以用來提升程序性能和安全的小技巧
一直在請求中使用 『Connection: Keep-Alive』頭信息。瀏覽器默認(rèn)在請求頭中添加 『Connection: Keep-Alive』。保證服務(wù)器也使用同樣的機(jī)制。
使用合適的 Cache-Control,Etag 和 Last-Modified 頭信息以便節(jié)省瀏覽器的下載時間。
花些時間調(diào)整和優(yōu)化服務(wù)器。這是奧秘所在!注意這一過程是否針對每個程序和所傳輸?shù)臄?shù)據(jù)。
一直使用 TLS!特別是如果程序中包含有任意類型的認(rèn)證。
研究瀏覽器所提供的安全策略并且在程序中強制實施。
擴(kuò)展關(guān)于字體文件的跨域問題可以查看這里和這里。
本系列持續(xù)更新中,Github 地址請查閱這里。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/116756.html
摘要:為了更加高效的網(wǎng)絡(luò)層,它需要不僅僅只是扮演套接字管理員的角色。用套接字池來組織套接字,以源來分組套接字,每個套接字池強制限制其連接數(shù)和安全約束。協(xié)商是一個為計算機(jī)網(wǎng)絡(luò)提供通信安全的加密協(xié)議。 原文請查閱這里,略有改動,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十二章...
摘要:為了更加高效的網(wǎng)絡(luò)層,它需要不僅僅只是扮演套接字管理員的角色。用套接字池來組織套接字,以源來分組套接字,每個套接字池強制限制其連接數(shù)和安全約束。協(xié)商是一個為計算機(jī)網(wǎng)絡(luò)提供通信安全的加密協(xié)議。 原文請查閱這里,略有改動,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第十二章...
摘要:使用新的易用的類定義,歸根結(jié)底也是要創(chuàng)建構(gòu)造函數(shù)和修改原型。首先,它把構(gòu)造函數(shù)當(dāng)成單獨的函數(shù)且包含類屬性集。該節(jié)點還儲存了指向父類的指針引用,該父類也并儲存了構(gòu)造函數(shù),屬性集和及父類引用,依次類推。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第...
摘要:使用新的易用的類定義,歸根結(jié)底也是要創(chuàng)建構(gòu)造函數(shù)和修改原型。首先,它把構(gòu)造函數(shù)當(dāng)成單獨的函數(shù)且包含類屬性集。該節(jié)點還儲存了指向父類的指針引用,該父類也并儲存了構(gòu)造函數(shù),屬性集和及父類引用,依次類推。 原文請查閱這里,略有刪減,本文采用知識共享署名 4.0 國際許可協(xié)議共享,BY Troland。 本系列持續(xù)更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第...
閱讀 1748·2023-04-25 16:28
閱讀 684·2021-11-23 09:51
閱讀 1467·2019-08-30 15:54
閱讀 1149·2019-08-30 15:53
閱讀 2816·2019-08-30 15:53
閱讀 3412·2019-08-30 15:43
閱讀 3250·2019-08-30 11:18
閱讀 3261·2019-08-26 10:25