精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Google Chrome中的高性能網(wǎng)絡(luò)

開發(fā) 前端
Google Chrome的歷史和指導(dǎo)原則 【譯注】這部分不再詳細(xì)翻譯,只列出核心意思。

Google Chrome的歷史和指導(dǎo)原則 【譯注】這部分不再詳細(xì)翻譯,只列出核心意思。

驅(qū)動(dòng)Chrome繼續(xù)前進(jìn)的核心原則包括:

  • 速度: 做最快的(fastest)的瀏覽器。
  • 安全(Security):為用戶提供最為安全的(most secure)的上網(wǎng)環(huán)境。
  • 穩(wěn)定: 提供一個(gè)健壯且穩(wěn)定的(resilient and stable)的Web應(yīng)用平臺(tái)。
  • 簡單: 以簡練的用戶體驗(yàn)(simple user experience)封裝精益求精的技術(shù)(sophisticated technology)。

本文關(guān)將注于第一點(diǎn)——速度。

關(guān)于性能的方方面面

一個(gè)現(xiàn)代瀏覽器就是一個(gè)和操作系統(tǒng)一樣的平臺(tái)。在Chrome之前的瀏覽器都是單進(jìn)程的應(yīng)用,所有頁面共享相同的地址空間和資源。引入多進(jìn)程架構(gòu)這是Chrome最為著名的改進(jìn)【譯注:省略一些反復(fù)談?wù)摰募?xì)節(jié)】。

120131107095439

一個(gè)進(jìn)程內(nèi),Web應(yīng)用主要需要執(zhí)行三個(gè)任務(wù):獲取資源,頁面 排版及渲染,和運(yùn)行JavaScript。渲染和腳本都是在運(yùn)行中交替以單線程的方式運(yùn)行的,其原因是為了保持DOM的一致性,而JavaScript本 身也是一個(gè)單線程的語言。所以優(yōu)化渲染和腳本運(yùn)行無論對(duì)于頁面開發(fā)者還是瀏覽器開發(fā)者都是極為重要的。

Chrome的渲染引擎是WebKit, JavaScript Engine則使用深入優(yōu)論的V8 (“V8″ JavaScript runtime)。但是,如果網(wǎng)絡(luò)不暢,無論優(yōu)化V8的JavaScript執(zhí)行,還是優(yōu)化WebKit的解析和渲染,作用其實(shí)很有限。巧婦難為無米之 炊,數(shù)據(jù)沒來就得等著!

相對(duì)于用戶體驗(yàn),作用最為明顯的就是如何優(yōu)化網(wǎng)絡(luò)資源的加載順 序、優(yōu)先級(jí)及每一個(gè)資源的延遲時(shí)間(latency)。也許你察覺不到,Chrome網(wǎng)絡(luò)模塊每天都在進(jìn)步,逐步降低每個(gè)資源的加載成本:向DNS lookups學(xué)習(xí),記住頁面拓?fù)浣Y(jié)構(gòu)(topology of the web), 預(yù)先連接可能的目標(biāo)網(wǎng)址,等等,還有很多。從外面來看就是一個(gè)簡單的資源加載的機(jī)制,但在內(nèi)部卻是一個(gè)精彩的世界。

關(guān)于Web應(yīng)用

開始正題前,還是先來了解一下現(xiàn)在網(wǎng)頁或者Web應(yīng)用在網(wǎng)絡(luò)上的需求。

HTTP Archive 項(xiàng)目一直在追蹤網(wǎng)頁構(gòu)建。除了頁面內(nèi)容外,它還會(huì)分析流行頁面使用的資源數(shù)量,類型,頭信息以及不同目標(biāo)地址的元數(shù)據(jù)(metadata)。下面是2013年1月的統(tǒng)計(jì)資料,由300,000目標(biāo)頁面得出的平均數(shù)據(jù):

220131107095457

1280 KB 包含88個(gè)資源(Images,JavaScript,CSS …)

連接15個(gè)以上的不同主機(jī)(distinct hosts)。

這些數(shù)字在過去幾年中一直持續(xù)增長( steadily increasing ),沒有停下的跡象。這說明我們正不斷地建構(gòu)一個(gè)更加龐大的、野心勃勃的網(wǎng)絡(luò)應(yīng)用。還要注意,平均來看每個(gè)資源不過12KB, 表明絕大多數(shù)的網(wǎng)絡(luò)傳輸都是短促(short and bursty)的。這和TCP針對(duì)大數(shù)據(jù)、流式(streaming)下載的方向不一致,正因?yàn)槿绱耍肓艘恍┎l(fā)癥。下面就用一個(gè)例子來抽絲剝繭, 一窺究竟……

一個(gè)Resource Request的一生 W3C的Navigation Timing specification定義了一組API,可以觀察到瀏覽器的每一個(gè)請(qǐng)求(request)的時(shí)序和性能數(shù)據(jù)。下面了解一些細(xì)節(jié):

320131107095509

給定一個(gè)網(wǎng)頁資源地址后,瀏覽器就會(huì)檢查本地緩存和應(yīng)用緩存。如果之前獲取過并且有相應(yīng)的緩存信息(appropriate cache headers)(如Expires, Cache-Control, etc.), 就會(huì)用緩存數(shù)據(jù)填充這個(gè)請(qǐng)求,畢竟最快的請(qǐng)求就是沒有請(qǐng)求(the fastest request is a request not made)。否則,我們重新驗(yàn)證資源,如果已經(jīng)失效(expired),或者根本就沒見過,一個(gè)耗費(fèi)網(wǎng)絡(luò)的請(qǐng)求就無法避免地發(fā)送了。

給定了一個(gè)主機(jī)名和資源路徑后,Chrome先是檢查現(xiàn)有已建立的連接(existing open connections)是否可以復(fù)用, 即sockets指定了以(scheme、host和port)定義的連接池(pool)。但如果配置了一個(gè)代理,或者指定了 proxy auto-config (PAC)腳本,Chrome就會(huì)檢查與proxy的連接。PAC腳本基于URL提供不同的代理,或者為此指定了特定 的規(guī)則。與每一個(gè)代理間都可以有自己的socket pool。最后,上述情況都不存在,這個(gè)請(qǐng)求就會(huì)從DNS查詢(DNS lookup)開始了,以便獲得它的IP地址。

幸運(yùn)的話,這個(gè)主機(jī)名已經(jīng)被緩存過。否則,必須先發(fā)起一個(gè) DNS Query。這個(gè)過程所需的時(shí)間和ISP,頁面的知名度,主機(jī)名在中間緩存(intermediate caches)的可能性,以及authoritative servers的響應(yīng)時(shí)間這些因素有關(guān)。也就是說這里變量很多,不過一般還不致于到幾百毫秒那么夸張。

420131107095522

拿到解析出的IP后,Chrome就會(huì)在目標(biāo)地址間打開一個(gè)新TCP連接,我們就要執(zhí)行一個(gè)3度握手(“three-way handshake”): SYN > SYN-ACK > ACK。這個(gè)操作每個(gè)新的TCP連接都必須完成,沒有捷徑。根據(jù)遠(yuǎn)近,路由路徑的選擇,這個(gè)過程可能要耗時(shí)幾百毫秒,甚至幾秒。而到現(xiàn)在,我們連一個(gè)有效 的字節(jié)都還沒收到。

當(dāng)TCP握手完成了,如果我們連接的是一個(gè)HTTPS地址,還有一個(gè)SSL握手過程,同時(shí)又要增加最多兩輪的延遲等待。如果SSL會(huì)話被緩存了,就只需一次。

最后,Chrome終于要發(fā)送HTTP請(qǐng)求了 (如上面圖示中的requestStart)。 服務(wù)器收到請(qǐng)求后,就會(huì)傳送響應(yīng)數(shù)據(jù)(response data)回到客戶端。這里包含最少的往返延遲和服務(wù)的處理時(shí)間。然后一個(gè)請(qǐng)求就完成了。但是,如果是一個(gè)HTTP重定向(redirect)的話?我們 又要從頭開始這個(gè)過程。如果你的頁面里有些冗余的重定向,最好三思一下!

你得出所有的延遲時(shí)間了嗎? 我們假設(shè)一個(gè)典型的寬帶環(huán)境:沒有本地緩存,相對(duì)較快的DNS lookup(50ms), TCP握手,SSL協(xié)商,以及一個(gè)較快服務(wù)器響應(yīng)時(shí)間(100ms)和一次延遲(80ms,在美國國內(nèi)的平均值): 50ms for DNS 80ms for TCP handshake (one RTT)

  • 160ms for SSL handshake (two RTT’s)
  • 40ms (發(fā)送請(qǐng)求到服務(wù)器)
  • 100ms (服務(wù)器處理)
  • 40ms (服務(wù)器回傳響應(yīng)數(shù)據(jù))

一個(gè)請(qǐng)求花了470毫秒, 其中80%的時(shí)間被網(wǎng)絡(luò)延遲占去了。看到了吧,我們真得有很多事情要做!事實(shí)上,470毫秒已經(jīng)很樂觀了:

如果服務(wù)器沒有達(dá)到到初始TCP的擁塞窗口(congestion window),即4-15KB,就會(huì)引入更多的往返延遲。 SSL延遲也可能變得更糟。如果需要獲取一個(gè)沒有的認(rèn)證(certificate)或者執(zhí)行 online certificate status check (OCSP), 都會(huì)讓我們需要一個(gè)新的TCP連接,又增加了數(shù)百至上千毫秒的延遲。

#p#

怎樣才算”夠快”?

前面可以看到服務(wù)器響應(yīng)時(shí)間僅是總延遲時(shí)間的20%,其它都被DNS,握手等操作占用了。過去用戶體驗(yàn)研究( user experience research )表明用戶對(duì)延遲時(shí)間的不同反應(yīng):

延遲及用戶反應(yīng) 0 – 100ms 迅速 100 – 300ms 有點(diǎn)慢 300 – 1000ms 機(jī)器還在運(yùn)行 1s+ 想想別的事…… 10s+ 我一會(huì)再來看看吧…

上表同樣適用于頁面的性能表現(xiàn): 渲染頁面,至少要在250ms內(nèi)給個(gè)回應(yīng)來吸引住用戶。這就是簡單地針對(duì)速度。從Google, Amazon, Microsoft,以及其它數(shù)千個(gè)站點(diǎn)來看,額外的延遲直接影響頁面表現(xiàn):流暢的頁面會(huì)吸引更多的瀏覽、以及更強(qiáng)的用戶吸引力(engagement) 和頁面轉(zhuǎn)換率(conversion rates).

現(xiàn)在我們知道了理想的延遲時(shí)間是250ms,而前面的示例告訴我們,DNS Lookup, TCP和SSL握手,以及request的準(zhǔn)備時(shí)間花去了370ms, 即便不考慮服務(wù)器處理時(shí)間,我們也超出了50%。

對(duì)于絕大多數(shù)的用戶和網(wǎng)頁開發(fā)者來說,DNS, TCP,以及SSL延遲都是透明,很少有人會(huì)想到它。這也就是為什么Chrome的網(wǎng)絡(luò)模塊那么的復(fù)雜。

我們已經(jīng)識(shí)別出了問題,下面讓我們深入一下實(shí)現(xiàn)的細(xì)節(jié)…

深入Chrome的網(wǎng)絡(luò)模塊 多進(jìn)程架構(gòu)

Chrome的多進(jìn)程架構(gòu)為瀏覽器的網(wǎng)絡(luò)請(qǐng)求處理帶來了重要意義,它目前支持四種不同的執(zhí)行模式( four different execution models ).

默認(rèn)情況下,桌面的Chrome瀏覽器使用process- per-site模式, 將不同的網(wǎng)站頁面隔離起來, 相同網(wǎng)站的頁面組織在一起。舉個(gè)簡單的例子: 每個(gè)tab獨(dú)立一個(gè)進(jìn)程。從網(wǎng)絡(luò)性能的角度上說,并沒什么本質(zhì)上的不同,只是process-per- tabl模式更易于理解。

520131107095531

每一個(gè)tab有一個(gè)渲染進(jìn)程(render process),其中包括了用于解析頁面(interpreting)和排版(layout out)的WebKit的排版引擎(layout engine), 即上圖中的HTML Render。還有V8引擎和兩者之間的DOM Bindings,如果你對(duì)這部分很好奇,可以看這里( great introduction to the plumbing )。

每一個(gè)這樣的渲染進(jìn)程被運(yùn)行在一個(gè)沙箱環(huán)境中,只會(huì)對(duì)用戶的電 腦環(huán)境做極有限的訪問–包括網(wǎng)絡(luò)。而使用這些資源,每一個(gè)渲染進(jìn)程必須和瀏覽內(nèi)核進(jìn)程(browser[kernel] process)溝通,以管理每個(gè)渲染進(jìn)程的安全性和訪問策略(access policies)。

進(jìn)程間通訊(IPC)和多進(jìn)程資源加載

渲染進(jìn)程和內(nèi)核進(jìn)程之間的通訊是通過IPC完成的。在Linux和 Mac OS上,使用了一個(gè)提供異步命名管道通訊方式的socketpair()。每一個(gè)渲染進(jìn)程的消息會(huì)被序列化地到一個(gè)專用的I/O線程中,然后再由它發(fā)到內(nèi) 核進(jìn)程。在接收端,內(nèi)核進(jìn)程提供一個(gè)過濾接口(filter interface)用于解析資源相關(guān)的IPC請(qǐng)求( ResourceMessageFilter ), 這部分就是網(wǎng)絡(luò)模塊負(fù)責(zé)的。

620131107095544

這樣做其中一個(gè)好處是所有的資源請(qǐng)求都由I/O進(jìn)程處理,無論是UI產(chǎn)生的活動(dòng),或者網(wǎng)絡(luò)事件觸發(fā)的交互。在內(nèi)核進(jìn)程(browser /kernel process)的I/O線程解析資源請(qǐng)求消息,將轉(zhuǎn)發(fā)到一個(gè)ResourceDispatcherHost的單例(singleton)對(duì)象中處理。

這個(gè)單例接口允許瀏覽器控制每個(gè)渲染進(jìn)程對(duì)網(wǎng)絡(luò)的訪問,也能達(dá)到有效和一致的資源共享:

Socket pool 和 connection limits: 瀏覽器可以限定每一個(gè)profile打開256個(gè)sockets, 每個(gè)proxy打開32個(gè)sockets, 而每一組{scheme, host, port}可以打開6個(gè)。注意同時(shí)針對(duì)一組{host,port}最多允計(jì)打開6個(gè)HTTP和6個(gè)HTTPS連接。 Socket reuse: 在Socket Pool中提供持久可用的TCP connections,以供復(fù)用。這樣可以為新的連接避免額外建立DNS、TCP和SSL(如果需要的話)所花費(fèi)的時(shí)間。

Socket late-binding(延遲綁定): 網(wǎng) 絡(luò)請(qǐng)求總是當(dāng)Scoket準(zhǔn)備好發(fā)送數(shù)據(jù)時(shí)才與一個(gè)TCP連接關(guān)連起來,所以首先有機(jī)會(huì)做到對(duì)請(qǐng)求有效分級(jí)(prioritization),比如,在 socket連接過程中可能會(huì)到達(dá)到一個(gè)更高優(yōu)先級(jí)的請(qǐng)求。同時(shí)也可以有更好的吞吐率(throughput),比如,在連接打開過程中,去復(fù)用一個(gè)剛好 可用的socket, 就可以使用到一個(gè)完全可用的TCP連接。其實(shí)傳統(tǒng)的TCP pre-connect(預(yù)連接)及其它大量的優(yōu)化方法也是這個(gè)效果。

Consistent session state (一致的會(huì)話狀態(tài)): 授權(quán)、cookies及緩存數(shù)據(jù)會(huì)在所有渲染進(jìn)程間共享。

Global resource and network optimizations (全局資源和網(wǎng)絡(luò)優(yōu)化): 瀏覽器能夠在所有渲染進(jìn)程和未處理的請(qǐng)求間做更優(yōu)的決策。比如給當(dāng)前tab對(duì)應(yīng)的請(qǐng)求以更好的優(yōu)先級(jí)。

Predictive optimizations (預(yù)測(cè)優(yōu)化): 通過監(jiān)控網(wǎng)絡(luò)活動(dòng),Chrome會(huì)建立并持續(xù)改善預(yù)測(cè)模型來提升性能。

… 項(xiàng)目還在增加中.

單就一個(gè)渲染進(jìn)程而言, 透過IPC發(fā)送資源請(qǐng)求很容易,只要告訴瀏覽器內(nèi)核進(jìn)程一個(gè)唯一ID, 后面就交給內(nèi)核進(jìn)程處理了。

跨平臺(tái)的資源加載

跨平臺(tái)也是Chrome網(wǎng)絡(luò)模塊的一個(gè)主要考量,包括Linux, Windows, OS X, Chrome OS, Android, 和iOS。 為此,網(wǎng)絡(luò)模塊盡量實(shí)現(xiàn)成了單進(jìn)程模式(只分出了獨(dú)立的cache和proxy進(jìn)程)的跨平臺(tái)函數(shù)庫, 這樣就可以在平臺(tái)間共用基礎(chǔ)組件(infrastructure)并分享相同的性能優(yōu)化,更有機(jī)會(huì)做到同時(shí)為所有平臺(tái)進(jìn)行優(yōu)化。

相關(guān)的代碼可以在這里找到the “src/net” subdirectory)。本文不會(huì)詳細(xì)展開每個(gè)組件,不過了解一下代碼結(jié)構(gòu)可以幫助我們理解它的能力結(jié)構(gòu)。 比如:

net/android 綁定到Android 運(yùn)行時(shí)(runtime) [譯注(Horky):運(yùn)行時(shí)真是一個(gè)很爛的術(shù)語,翻和沒翻一樣。] net/base 公共的網(wǎng)絡(luò)工具函數(shù)。比如,主機(jī)解析, cookies, 網(wǎng)絡(luò)轉(zhuǎn)換偵測(cè)(network change detection),以及SSL認(rèn)證管理 net/cookies 實(shí)現(xiàn)了Cookie的存儲(chǔ)、管理及獲取 net/disk_cache 磁盤和內(nèi)存緩存的實(shí)現(xiàn) net/dns 實(shí)現(xiàn)了一個(gè)異步的DNS解析器(DNS resolver) net/http 實(shí)現(xiàn)了HTTP協(xié)議 net/proxy 代理(SOCKS 和 HTTP)配置、解析(resolution) 、腳本抓取(script fetching), … net/socket TCP sockets,SSL streams和socket pools的跨平臺(tái)實(shí)現(xiàn) net/spdy 實(shí)現(xiàn)了SPDY協(xié)議 net/url_request URLRequest, URLRequestContext和URLRequestJob的實(shí)現(xiàn) net/websockets 實(shí)現(xiàn)了WebSockets協(xié)議 上面每一項(xiàng)都值得好好讀讀,代碼組織的很好,你還會(huì)發(fā)現(xiàn)大量的單元測(cè)試。

#p#

Mobile平臺(tái)上的架構(gòu)和性能

移動(dòng)瀏覽器正在大發(fā)展,Chrome團(tuán)隊(duì)也視優(yōu)化移動(dòng)端的體驗(yàn)為最高優(yōu)先級(jí)。先要說明的是移動(dòng)版的Chrome的并不是其桌面版本的直接移植,因?yàn)槟菢痈静粫?huì)帶來好的用戶體驗(yàn)。移動(dòng)端的先天特性就決定了它是一個(gè)資源嚴(yán)重受限的環(huán)境,在運(yùn)行參數(shù)有一些基本的不同:

桌面用戶使用鼠標(biāo)操作,可以有重疊的窗口,大的屏幕,也不用擔(dān)心電池。網(wǎng)絡(luò)也非常穩(wěn)定,有大量的存儲(chǔ)空間和內(nèi)存。 移動(dòng)端的用戶則是觸摸和手勢(shì)操作,屏幕小,電池電量有限,通過只能用龜速且昂貴的網(wǎng)絡(luò),存儲(chǔ)空間和內(nèi)存也是相當(dāng)受限。

再者,不但沒有典型的樣板移動(dòng)設(shè)備,反而是有一大批各色硬件的設(shè)備。Chrome要做的,只能是設(shè)法兼容這些設(shè)備。好在Chrome有不同的運(yùn)行模式(execution models),面對(duì)這些問題,游刃有余!

在Android版本上,Chrome同樣運(yùn)用了桌面版本的多進(jìn)程架構(gòu)- 一個(gè)瀏覽器內(nèi)核進(jìn)程,以及一個(gè)或多個(gè)渲染進(jìn)程。但因?yàn)閮?nèi)存的限制,移動(dòng)版的Chrome無法為每一個(gè)tabl運(yùn)行一個(gè)特定的渲染進(jìn)程,而是根據(jù)內(nèi)存情況等 條件決定一個(gè)最佳的渲染進(jìn)程個(gè)數(shù),然后就會(huì)在多個(gè)tab間共享這些渲染進(jìn)程。

如果內(nèi)存實(shí)在不足,或其它原因?qū)е翪hrome無法運(yùn)行多進(jìn)程,它就會(huì)切到單進(jìn)程、多線程的模式。比如在iOS設(shè)備上,因?yàn)槠渖诚錂C(jī)制的限制,Chrome只能運(yùn)行在這種模式下。

關(guān)于網(wǎng)絡(luò)性能,首先Chrome在Android和iOS使用的是 各其它平臺(tái)相同的網(wǎng)絡(luò)模塊。這可以做到跨平臺(tái)的網(wǎng)絡(luò)優(yōu)化,這也是Chrome明顯領(lǐng)先的優(yōu)勢(shì)之一。所不同的是需要經(jīng)常根據(jù)網(wǎng)絡(luò)情況和設(shè)備能力進(jìn)行些調(diào)整, 包括推測(cè)優(yōu)化(speculative optimization)的優(yōu)先級(jí)、socket的超時(shí)設(shè)置和管理邏輯、緩存大小等。

比如,為了延長電池壽命,移動(dòng)端的Chrome會(huì)傾向于延遲關(guān)閉空 閑的sockets (lazy closing of idle sockets), 通常是為了減少信號(hào)(radio)的使用而在打開新的socket時(shí)關(guān)閉舊的。另外因?yàn)轭A(yù)渲染(pre-rendering,稍后會(huì)介紹)會(huì)使用一定的網(wǎng) 絡(luò)和處理資源,它通常只在WiFi才會(huì)使用。

關(guān)于移動(dòng)瀏覽體驗(yàn)會(huì)獨(dú)立一章,也許就在POSA系列的下一期。

Chrome Predictor的預(yù)測(cè)功能優(yōu)化

Chrome會(huì)隨著使用變得更快。 它這個(gè)特性是通過一個(gè)單例對(duì)象Predictor來實(shí)現(xiàn)的。這個(gè)對(duì)象在瀏覽器內(nèi)核進(jìn)程(Browser Kernel Process)中實(shí)例化,它唯一的職責(zé)就是觀察和學(xué)習(xí)當(dāng)前網(wǎng)絡(luò)活動(dòng)方式,提前預(yù)估用戶下一步的操作。下面是一個(gè)示例:

用戶將鼠標(biāo)停留在一個(gè)鏈接上,就預(yù)示著一個(gè)用戶的偏好以及下一步的瀏覽行為。這時(shí)Chrome就可以提前進(jìn)行DNS Lookup及TCP握手。用戶的點(diǎn)擊操作平均需要將近200ms,在這個(gè)時(shí)間就可能處理完DNS和TCP相關(guān)的操作, 也就是省去幾百毫秒的延遲時(shí)間。 當(dāng)在地址欄(Omnibox/URL bar) 觸發(fā)高可能性選項(xiàng)時(shí),就同樣會(huì)觸發(fā)一個(gè)DNS lookup和TCP預(yù)連接(pre-connect),甚至在一個(gè)不可見的頁簽中進(jìn)行預(yù)渲染(pre-render)!

我們每個(gè)人都一串天天會(huì)訪問的網(wǎng)站, Chrome會(huì)研究在這些頁面上的子資源, 并且嘗試進(jìn)行預(yù)解析(pre-resolve), 甚至可能會(huì)進(jìn)行預(yù)加載(pre-fetch)以優(yōu)化瀏覽體驗(yàn)。

除了上面三項(xiàng),還有很多..

Chrome會(huì)在你使用過程中學(xué)習(xí)Web的拓?fù)浣Y(jié)構(gòu),而不單單是你的瀏覽模式。理想的話,它將為你省去數(shù)百毫秒的延遲, 更接近于即時(shí)頁面加載的狀態(tài). 正是為了這個(gè)目標(biāo),Chrome投入了以下的核心優(yōu)化技術(shù):

DNS預(yù)解析(pre-resolve) 提前解析主機(jī)地址,以減少DNS延遲 TCP預(yù)連接(pre-connect) 提前連接到目標(biāo)服務(wù)器,以減少TCP握手延遲 資源預(yù)加載(prefetching) 提前加載頁面的核心資源,以加載頁面顯示 頁面預(yù)渲染(prerendering)
提前獲取整個(gè)頁面和相關(guān)子資源,這樣可以做到及時(shí)顯示

每一個(gè)決策都包含著一個(gè)或多個(gè)的優(yōu)化, 用來克服大量的限制因素. 不過畢竟都只是預(yù)測(cè)性的優(yōu)化策略,如果效果不理想,就會(huì)引入多余的處理和網(wǎng)絡(luò)傳輸。甚至可能會(huì)帶來一些加載時(shí)間上的負(fù)體驗(yàn)。

Chrome如何處理這些問題呢? Predictor會(huì)盡量收集各種信息,諸如用戶操作,歷史瀏覽數(shù)據(jù),以及來自渲染引擎(render)和網(wǎng)絡(luò)模塊自身的信息。

和Chrome中負(fù)責(zé)網(wǎng)絡(luò)事務(wù)調(diào)度的ResourceDispatcherHost不同,Predictor對(duì)象會(huì)針對(duì)用戶和網(wǎng)絡(luò)事務(wù)創(chuàng)建一組過濾器(filter):

IPC channel filter用來監(jiān)控來自render進(jìn)程的事務(wù)。 每個(gè)請(qǐng)求上都會(huì)加一個(gè)ConnectInterceptor 對(duì)象,這樣就可以跟蹤網(wǎng)絡(luò)傳輸?shù)哪J揭约懊恳粋€(gè)請(qǐng)求的度量數(shù)據(jù)。

渲染進(jìn)程(render process)會(huì)在一系列的事件下發(fā)送消息到瀏覽器進(jìn)程(browser process), 這些事件被定義在一個(gè)枚舉(ResolutionMotivation)中以便于使用 (url_info.h):

enum ResolutionMotivation { MOUSE_OVER_MOTIVATED, // 鼠標(biāo)懸停. OMNIBOX_MOTIVATED, // Omni-box建議進(jìn)行解析. STARTUP_LIST_MOTIVATED, // 這是在前10個(gè)啟動(dòng)項(xiàng)中的資源. EARLY_LOAD_MOTIVATED, // 有時(shí)需要使用prefetched來提前建立連接.

// 下面定義了預(yù)加載評(píng)估的方式,會(huì)由一個(gè)navigation變量指定. // referring_url_也需要同時(shí)指定. STATIC_REFERAL_MOTIVATED, // 外部數(shù)據(jù)庫(External Database)建議進(jìn)行解析。 LEARNED_REFERAL_MOTIVATED, // 前一次瀏覽(prior navigation建議進(jìn)行解析. SELF_REFERAL_MOTIVATED, // 猜測(cè)下一個(gè)連接是不是需要進(jìn)行解析.

// <略> … }; 通過這些給定的事 件,Predictor的目標(biāo)就可以評(píng)估它成功的可能性, 然后再適時(shí)觸發(fā)操作。每一項(xiàng)事件都有其成功的機(jī)率、優(yōu)先級(jí)以及時(shí)間戳,這些可以在內(nèi)部維護(hù)一個(gè)用優(yōu)先級(jí)管理的隊(duì)列,也是優(yōu)化的一個(gè)手段。最終,對(duì)于這個(gè)隊(duì) 列中發(fā)出的每一個(gè)請(qǐng)求的成功率,都可以被Predictor追蹤到。基于這些數(shù)據(jù),Predictor就可以進(jìn)一步優(yōu)化它的決策。

Chrome網(wǎng)絡(luò)架構(gòu)小結(jié)

Chrome使用多進(jìn)程架構(gòu),將渲染進(jìn)程同瀏覽器進(jìn)程隔離開來。 Chrome維護(hù)著一個(gè)資源分發(fā)器的實(shí)例(a single instance of the resource dispatcher), 它運(yùn)行在瀏覽器內(nèi)核進(jìn)程,并在各個(gè)渲染進(jìn)程間共享。

網(wǎng)絡(luò)層是跨平臺(tái)的,大部分情況下以單進(jìn)程庫存在。

網(wǎng)絡(luò)層使用非阻塞式(no-blocking)操作來管理所有網(wǎng)絡(luò)任務(wù)。

共享的網(wǎng)絡(luò)層支持有效的資源排序、復(fù)用、并為瀏覽器提供在多進(jìn)程間進(jìn)行全局優(yōu)化的能力。

每一個(gè)渲染進(jìn)程通過IPC和資源分發(fā)器(resource dispatcher)通訊。

資源分發(fā)器(Resource dispatcher)通過自定義的IPC Filter解析資源請(qǐng)求。

Predictor在解析資源請(qǐng)求和響應(yīng)網(wǎng)絡(luò)事務(wù)中學(xué)習(xí),并對(duì)后續(xù)的網(wǎng)絡(luò)請(qǐng)求進(jìn)行優(yōu)化。

Predictor會(huì)根據(jù)學(xué)習(xí)到的網(wǎng)絡(luò)事務(wù)模式預(yù)測(cè)性的進(jìn)行DNS解析, TCP握手,甚至是資源請(qǐng)求,為用戶實(shí)際操作時(shí)節(jié)省數(shù)百毫秒的時(shí)間。

了解晦澀的內(nèi)部細(xì)節(jié)后,讓我們來看一下用戶可以感受到的優(yōu)化。一切從全新的Chrome開始。

#p#

優(yōu)化冷啟動(dòng)(Cold-Boot)體驗(yàn)

第一次啟動(dòng)瀏覽器,它當(dāng)然不可能了解你的使用習(xí)慣和喜歡的頁面。但事實(shí)上,我們大多數(shù)會(huì)在瀏覽器的冷啟動(dòng)后做些類似的事情,比如到電子郵箱查看郵 件,加一些新聞頁面、社交頁面及內(nèi)部 頁面到我的最愛,諸如此類。這些頁面各有不同,但它們?nèi)匀痪哂幸恍┫嗨菩裕訮redictor仍然可以對(duì)這個(gè)過程提速。

Chrome記下了用戶在全新啟動(dòng)瀏覽器時(shí)最常用的10個(gè)域名。當(dāng)瀏覽器啟動(dòng)時(shí),Chrome會(huì)提前對(duì)這些域名進(jìn)行DNS預(yù)解析。你可以在Chrome中使用chrome://dns查看到這個(gè)列表。在打開頁面的最上面的表格中會(huì)列出啟動(dòng)時(shí)的備選域名列表。 720131107095555

通過Omnibox優(yōu)化與用戶的交互

引入Omnibox是Chrome的一項(xiàng)創(chuàng)新, 并不是簡單地處理目標(biāo)的URL。除了記錄之前訪問過的頁面URL,它還與搜索引擎的整合,并且支持在歷史記錄中進(jìn)行全文搜索(比如,直接輸入頁面名稱)。

當(dāng)用戶輸入時(shí),Omnibox自動(dòng)發(fā)起一個(gè)行為,要么查找瀏覽記錄中的URL, 要么進(jìn)行一次搜索。每一次發(fā)起的操作都會(huì)被加以評(píng)分,以統(tǒng)計(jì)它的性能。你可以在Chrome輸入chrome://predictors來觀察這些數(shù)據(jù)。 820131107095605

Chrome維護(hù)著一個(gè)歷史記錄,內(nèi)容包括用戶輸入的前置文字,采用的行為,以命中的資數(shù)。 在上面的列表,你可以看到,當(dāng)輸入g時(shí),有76%的機(jī)會(huì)嘗試打開Gmail. 如果再補(bǔ)充一個(gè)m (就是gm), 打開Gmail的可能性增加到99.8%。

那么網(wǎng)絡(luò)模塊會(huì)做什么呢?上 表中的黃色和綠色對(duì)于ResourceDispatcher非常重要。如果有一個(gè)一般可能性的頁面(黃色), Chrome就是發(fā)起DNS預(yù)解析。如果有一個(gè)高可能性的頁面(綠色),Chrome還會(huì)在DNS解析后發(fā)起TCP預(yù)連接。如果這兩項(xiàng)都完成了,用戶仍然 繼續(xù)錄入,Chrome就會(huì)在一個(gè)隱藏的頁簽進(jìn)行預(yù)渲染(pre-render)。

相對(duì)的,如果輸入的前置文字找不到合適的匹配項(xiàng)目,Chrome會(huì)向搜索引擎服務(wù)者發(fā)起DNS預(yù)解析和TCP預(yù)連,以獲取相似的搜索結(jié)果。

平均而言用戶從填寫查詢內(nèi)容到評(píng)估給出的建議需要花費(fèi)數(shù)百毫秒。 此時(shí)Chrome可以在后臺(tái)進(jìn)行預(yù)解析,預(yù)連接,甚至進(jìn)行預(yù)渲染。再當(dāng)用戶準(zhǔn)備按下回車鍵時(shí),大量的網(wǎng)絡(luò)延遲已經(jīng)被提前處理掉了。

優(yōu)化緩存性能

最快的請(qǐng)求就是沒有請(qǐng)求。 無論何時(shí)討論性能,都不能不談緩存。相信你已經(jīng)為頁面上所有資源的都提供了Expires, ETag, Last-Modified和Cache-Control這些響應(yīng)頭信息(response headers)。什么? 還沒有?那你還是先處理好再來看吧!

Chrome有兩種不同的內(nèi)部緩存的實(shí)現(xiàn):一種備份于本地磁盤(local disk),另一種則存儲(chǔ)于內(nèi)存(in-memory)中。內(nèi)存模式(in-memory)主要應(yīng)用于無痕瀏覽模式(Incognito browsing mode),并在關(guān)閉窗口清除掉。 兩種方式使用了相同的內(nèi)部接口(disk_cache::Backend, 和disk_cache::Entry),大大簡化了系統(tǒng)架構(gòu)。如果你想實(shí)現(xiàn)一個(gè)自己的緩存算法,可以很容易地實(shí)現(xiàn)進(jìn)去。

在內(nèi)部,磁盤緩存(disk cache)實(shí)現(xiàn)了它自己的一組數(shù)據(jù)結(jié)構(gòu), 它們被存儲(chǔ)在一個(gè)單獨(dú)的緩存目錄里。其中有索引文件(在瀏覽器啟動(dòng)時(shí)加載到內(nèi)存中),數(shù)據(jù)文件(存儲(chǔ)著實(shí)際數(shù)據(jù),以及HTTP頭以及其它信息)。比較有趣 的是,16KB以下的文件存儲(chǔ)于共同的數(shù)據(jù)塊文件中(data block-files,即小文件集中存儲(chǔ)于一個(gè)大文件中),其它較大的文件才會(huì)存儲(chǔ)到自己專屬的文件中。最后,磁盤緩存的淘汰策略是維護(hù)一個(gè)LRU,通 過比如訪問頻率和資源的使用時(shí)間(age)的度量進(jìn)行管理。

 920131107095617

在Chrome開個(gè)頁簽,輸入chrome://net-internals/#httpCache。 如果你要看到實(shí)際的HTTP數(shù)據(jù)和緩存的響應(yīng)處理,可以打開chrome://cache, 里面會(huì)列出所有緩存中可用的資源。打開每一項(xiàng),還可以看到詳細(xì)的數(shù)據(jù)頭等信息。

優(yōu)化DNS預(yù)連接

前面已經(jīng)多次提到了DNS預(yù)解析,在深入實(shí)現(xiàn)之前,先匯總一下DNS預(yù)解析的場景和理由:

運(yùn)行在渲染進(jìn)程中的WebKit文檔解析器(document parser), 會(huì)為當(dāng)前頁面上所有的鏈接提供一個(gè)主機(jī)名(hostname)列表,Chrome可以選擇是否提前解析。 當(dāng)用戶要打開頁面時(shí),渲染進(jìn)程先會(huì)觸發(fā)一個(gè)鼠標(biāo)懸停(hover)或按鍵(button down)事件。

Omnibox可能會(huì)針對(duì)一個(gè)高可能性的建議頁面發(fā)起解析請(qǐng)求。

Chrome Predictor會(huì)基于過往瀏覽記錄和資源請(qǐng)求數(shù)據(jù)發(fā)起主機(jī)解析請(qǐng)求。(下面會(huì)詳細(xì)解釋。)

頁面本身會(huì)顯式地要求Chrome對(duì)某些主機(jī)名稱進(jìn)行預(yù)解析。

上述各項(xiàng)對(duì)于Chrome都只是一個(gè)線索。 Chrome 并不保證預(yù)解析一定會(huì)被執(zhí)行,所有的線索會(huì)由Predictor進(jìn)行評(píng)估,以決定后續(xù)的操作。最壞的情況下,可能無法及時(shí)解析主機(jī)名,用戶就必須等待一個(gè) DNS解析時(shí)間,然后是TCP連接時(shí)間,最后是資源加載時(shí)間。Predictor會(huì)記下這個(gè)場景,在未來決策時(shí)相應(yīng)地加以參考。總之,一定是越用越快。

之前提過到Chrome可以 記住每個(gè)頁面的拓?fù)?topology),并可以基于這個(gè)信息進(jìn)行加速。還記得吧,平均每個(gè)頁面帶有88個(gè)資源,分別來自于30多個(gè)獨(dú)立的主機(jī)。每打開這 個(gè)頁面,Chrome會(huì)記下資源中比較常用的主機(jī)名,在后續(xù)的瀏覽過程中,Chrome就會(huì)發(fā)起針對(duì)某些主機(jī)或者全部主機(jī)的DNS解析,甚至是TCP預(yù)連接!

1020131107095626

#p#

使用chrome://dns 就可以觀察到上面的數(shù)據(jù)(Google+頁面), 其中有6個(gè)子資源對(duì)應(yīng)的主機(jī)名,并記錄了DNS預(yù)解析發(fā)生的次數(shù),TCP預(yù)連接發(fā)生的次數(shù),以及到每個(gè)主機(jī)的請(qǐng)求次數(shù)。這些數(shù)據(jù)就可以讓Chrome Predictor執(zhí)行相應(yīng)的優(yōu)化決策。

除了內(nèi)部事件通知外,頁面設(shè)計(jì)者可以在頁面中嵌入如下的語句請(qǐng)求瀏覽器進(jìn)行預(yù)解析:

之所以有這個(gè)需求,一個(gè)典型的例子是重定向(redirects). Chrome本身沒辦法判斷出這種模式,通過這種方式則可以讓瀏覽器提前進(jìn)行解析。

具體的實(shí)現(xiàn)也是因版本而有所差異,總體而言,Chrome中的DNS處理有兩個(gè)主要的實(shí)現(xiàn):1.基于歷史數(shù)據(jù)(historically), 通過調(diào)用平臺(tái)無關(guān)的getaddrinfo()系統(tǒng)函數(shù)實(shí)現(xiàn)。2.代理操作系統(tǒng)的DNS處理方法,這種方法正在被Chrome自行實(shí)現(xiàn)的一套異步DNS解 析機(jī)制(asynchronous DNS resolver)所取代。

依賴于系統(tǒng)的實(shí)現(xiàn),代碼少而 且簡單,但是getaddrInfo()是一個(gè)阻塞式的系統(tǒng)調(diào)用,無法有效地并行多個(gè)查詢操作。經(jīng)驗(yàn)數(shù)據(jù)還顯示,并行請(qǐng)求過多甚至?xí)雎酚善鞯呢?fù)額。 Chrome為此設(shè)計(jì)了一個(gè)復(fù)雜的機(jī)制。對(duì)于其中帶有worker-pool的預(yù)解析, Chrome只是簡單的發(fā)送getaddrinfo() 調(diào)用, 同時(shí)阻塞worker thread直到收到響應(yīng)數(shù)據(jù)。因?yàn)橄到y(tǒng)有DNS緩存的原因,針對(duì)解析過的主機(jī),解析操作會(huì)立即返回。 這個(gè)過程簡單,有效。

但還不夠! getaddrinfo()隱藏了太多有用的信息,比如Time-to-live(TTL)時(shí)間戳, DNS緩存的狀態(tài)等。于是Chrome決定自己實(shí)現(xiàn)一套跨平臺(tái)的異步DNS解析器。

1120131107095639

這個(gè)新技術(shù)可以支持以下優(yōu)化:

  • 更好地控制重轉(zhuǎn)的時(shí)機(jī),有能力并行執(zhí)行多個(gè)查詢操作。 清晰地記錄TTLs。
  • 更好地處理IPv4和IPv6的兼容。

基于RTT和其它事件,針對(duì)不同服務(wù)器進(jìn)行錯(cuò)誤處理(failover)

Chrome仍然進(jìn)行著持續(xù)的優(yōu)化. 通過chrome://histograms/DNS可以觀察到DNS度量數(shù)據(jù):

1220131107095646

上面的柱狀圖展示了 DNS預(yù)解析延遲時(shí)間的分布:比如將近50%(最右側(cè))的查詢?cè)?0ms內(nèi)完成。這些數(shù)據(jù)基于最近的瀏覽操作(采樣9869次),用戶可以選擇是否報(bào)告這 些使用數(shù)據(jù),然后這些數(shù)據(jù)會(huì)以匿名的形式交由工程團(tuán)隊(duì)加以分析,這樣就可以了解到功能的性能,以及未來如何進(jìn)一步調(diào)整。周而復(fù)始,不斷優(yōu)化。

使用預(yù)連接優(yōu)化了TCP連接管理

已經(jīng)預(yù)解析到了主機(jī)名,也有了 由OmniBox和Chrome Predictor提供信號(hào),預(yù)示著用戶未來的操作。為什么再進(jìn)一步連接到目標(biāo)主機(jī),在用戶真正發(fā)起請(qǐng)求前完成TCP握手呢?這樣就可省掉了另一個(gè)往返的 延遲,輕易地就能為用戶節(jié)省到上百毫秒。其實(shí),這就是TCP預(yù)連接的工作。 通過訪問chrome://dns 就可以看到TCP預(yù)連接的使用情況。

1320131107095653

首先, Chrome檢查它的socket pool里有沒有目標(biāo)主機(jī)可以復(fù)用的socket, 這些sockets會(huì)在socket pool里保留一段時(shí)間,以節(jié)省TCP握手時(shí)間及啟動(dòng)延時(shí)(slow-start penalty)。如果沒有可用的socket, 就需要發(fā)起TCP握手,然后放到socket pool中。這樣當(dāng)用戶發(fā)起請(qǐng)求時(shí),就可以用這個(gè)socket立即發(fā)起HTTP請(qǐng)求。

打開 chrome://net-internals#sockets 就可以看到當(dāng)前的sockets的狀態(tài):

1420131107095702

你可以看到每一個(gè)socket的時(shí)間軸:連接和代理的時(shí)間,每個(gè)封包到達(dá)的時(shí)間,以及其它一些信息。你也可以把這些數(shù)據(jù)導(dǎo)出,以方便進(jìn)一步分析或者報(bào)告問題。有好的測(cè)試數(shù)據(jù)是優(yōu)化的基礎(chǔ), chrome://net-internals就是Chrome網(wǎng)絡(luò)的信息中心。

使用預(yù)加載優(yōu)化資源加載

Chrome支持在頁面的HTML標(biāo)簽中加入的兩個(gè)線索來優(yōu)化資源加載:

在rel中指定的 subresource(子資源)和prefetch(預(yù)加載)非常相似。不同的是,如果一個(gè)link指定rel(relation)為prefetch 后,就是告訴瀏覽器這個(gè)資源是稍后的頁面中要用到的。而指定為subresource則表示在本頁中就會(huì)用到,期望能在使用前加載。兩者不同的語義讓 resource loader有不同的行為。prefetch的優(yōu)先級(jí)較低,一般只會(huì)在頁面加載完成后才會(huì)開始。而subresource則會(huì)在解析出來時(shí)就被嘗試優(yōu)先執(zhí) 行。

還要注意,prefetch是HTML5的一部分,F(xiàn)irefox和Chrome都可以支持。但subresource還只能用在Chrome 中。

應(yīng)用Browser Prefreshing優(yōu)化資源加載

不過,并不是所有的Web開發(fā)者會(huì)愿意加入上面所述的subresource relation, 就算加了,也要等收到主文檔并解析出這些內(nèi)容才行,這段時(shí)間開銷依賴于服務(wù)器的響應(yīng)時(shí)間和客戶端與服務(wù)器間的延遲時(shí)間,甚至要耗去上千毫秒。

和前面的預(yù)解析,預(yù)連接一樣,這里還有一個(gè)prefreshing::

用戶初始化一個(gè)目標(biāo)頁面的請(qǐng)求。 Chrome查詢Predictor之前針對(duì)目標(biāo)頁面的子資源加載,初始化一組DNS預(yù)解析,TCP預(yù)連接及資源prefreshing。

如是在緩存中發(fā)現(xiàn)之前記錄的子資源,由從磁盤中加載到內(nèi)存中。如果沒有或者已經(jīng)過期了,就是發(fā)送網(wǎng)絡(luò)請(qǐng)求。

[[89150]]

直到在2013年初, prefreshing還是處于早期的討論階段。如果通過數(shù)據(jù)結(jié)果分析,這個(gè)功能最終上線了,我們就可以稍晚些時(shí)候使用到它了。

#p#

使用預(yù)渲染優(yōu)化頁面瀏覽

前面討論的每個(gè)優(yōu)化都用來幫助減少用戶發(fā)起請(qǐng)求到看到頁面內(nèi)容的延遲時(shí)間。多快才能帶來即時(shí)呈現(xiàn)的體驗(yàn)?zāi)兀炕谟脩趔w驗(yàn)數(shù)據(jù),這個(gè)時(shí)間是100毫秒,根本沒給網(wǎng)絡(luò)延遲留什么空間。而在100毫秒內(nèi),又怎樣渲染頁面呢?

大家可能都有這樣的體驗(yàn): 同時(shí)開多個(gè)頁簽時(shí)會(huì)明顯快于在一個(gè)頁簽中等待。瀏覽器為此提供了一個(gè)實(shí)現(xiàn)方式:

這就是Chrome的預(yù)渲染(prerendering in Chrome)! 相對(duì)于只下載一個(gè)資源的“prefetch”, “prerender”會(huì)讓Chrome在一個(gè)不可見的頁簽中渲染一個(gè)頁面,包含了它所有的子資源。當(dāng)用戶要瀏覽它時(shí),這個(gè)頁簽被切到前臺(tái),做到了即時(shí)的 體驗(yàn)。

可以瀏覽 prerender-test.appspot.com 來體驗(yàn)一下效果,再通過chrome://net-internals/#prerender查看下歷史記錄和預(yù)連接頁面的狀態(tài)。

1620131107095729

因?yàn)轭A(yù)渲染會(huì)同時(shí)消耗CPU和網(wǎng)絡(luò)資源,因些一定要在確信預(yù)渲染頁面會(huì)被使用到情況下才用。Google Search就在它的搜索結(jié)果里加入prerender, 因?yàn)榈谝粋€(gè)搜索結(jié)果很可能就是下一個(gè)頁面(也叫作Google Instant Pages)

你可以使用預(yù)渲染特性,但以下限制項(xiàng)一定要牢記:

.所有的進(jìn)程中最多只能有一個(gè)預(yù)渲染頁。 HTTPS和帶有HTTP認(rèn)證的頁面不可以預(yù)渲染。

.如果請(qǐng)求資源需要發(fā)起非冪等(non-idempotent,idempotent request的意義為發(fā)起多次,不會(huì)帶來服務(wù)的負(fù)面響應(yīng)的請(qǐng)求)的請(qǐng)求(只有GET請(qǐng)求)時(shí),預(yù)渲染也不可用。

  • .所有的資源的優(yōu)先級(jí)都很低。
  • .頁面渲染進(jìn)程的使用最低的CPU優(yōu)先級(jí)。
  • .如果需要超過100MB的內(nèi)存,將無法使用預(yù)渲染。
  • .不支持HTML5多媒體元素。

預(yù)渲染只能應(yīng)用于確信安全的頁面。另外JavaScript也最好在運(yùn)行時(shí)使用Page Visibility API 來判斷一下當(dāng)前頁是否可見(參考 you should be doing anyway) !

[[89151]]

最后,總之,Chrome正逐步優(yōu)化網(wǎng)絡(luò)延遲和用戶體驗(yàn),讓它隨著用戶的使用越來越快!

原文鏈接:http://tech.uc.cn/?p=2092

責(zé)任編輯:陳四芳 來源: UC技術(shù)博客
相關(guān)推薦

2021-05-08 15:20:35

Chrome瀏覽器通知

2023-11-01 11:59:13

2025-01-06 00:00:10

2012-05-08 13:36:55

2009-10-26 09:49:53

Google Chrome OS泄露版

2017-11-28 17:14:16

華為云

2009-06-04 09:20:45

2009-03-01 21:38:04

GoogleChrome 2.0.Beta

2009-03-23 09:01:37

GoogleChrome瀏覽器

2009-02-20 11:04:48

GoogleChrome2.0.164.0

2024-03-18 13:43:20

Linux架構(gòu)

2023-10-31 18:52:29

網(wǎng)絡(luò)框架XDP技術(shù)

2020-06-17 16:43:40

網(wǎng)絡(luò)IO框架

2009-08-12 17:48:56

存儲(chǔ)高性能計(jì)算曙光

2010-05-12 11:08:00

2024-04-28 10:17:30

gnetGo語言

2023-11-01 10:38:46

Linux高性能網(wǎng)絡(luò)編程

2022-03-18 12:39:57

UbuntuChrome

2018-10-08 15:22:36

IO模型

2011-04-12 10:52:43

布線系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲精品一线二线三线| 国产精品麻豆网站| 日本成人激情视频| 欧美一区二区三区观看| 综合视频一区| 欧美少妇性性性| 被灌满精子的波多野结衣| 黄色片在线播放| 国产精品18久久久久久vr| 日本精品久久久久久久| 亚洲av无码一区二区三区在线| 久久99精品国产自在现线| 欧美亚洲免费在线一区| 日韩极品视频在线观看| av电影在线观看一区二区三区| 国产成人av电影在线| 国产精品18久久久久久首页狼| 日本妇女毛茸茸| 在线观看欧美理论a影院| 日韩视频免费观看高清完整版在线观看 | 免费观看国产视频在线| 深夜福利视频一区| 国产精品一区在线| 国产精品video| 日本三级欧美三级| 91精品天堂福利在线观看| 精品五月天久久| 91亚洲一线产区二线产区| 国产91在线精品| 一本大道av一区二区在线播放| 青青在线视频免费观看| 3p视频在线观看| 国产午夜亚洲精品理论片色戒 | 最新热久久免费视频| 欧美日韩亚洲免费| 青青草免费在线| 成人黄色在线视频| 99超碰麻豆| 国产伦理吴梦梦伦理| 天堂一区二区在线| 国产91精品久久久| 久久狠狠高潮亚洲精品| 欧美日韩国产欧| 欧美成人国产va精品日本一级| 国产不卡在线观看视频| 欧美日韩123| 精品视频在线播放免| 日韩av手机在线播放| 天堂精品在线视频| 日韩欧美亚洲一区二区| 在线视频观看一区二区| 欧美一级免费| 欧美男男青年gay1069videost| 日韩中文字幕免费在线| 免费成人直播| 91久久久免费一区二区| av无码精品一区二区三区| 一区一区三区| 日本韩国欧美在线| 亚洲一区二区三区四区五区xx| 韩国美女久久| 在线观看日韩av先锋影音电影院| 日韩av在线综合| 我爱我色成人网| 在线观看国产精品网站| 一级在线免费视频| 日韩欧美激情| 正在播放一区二区| 无码人妻一区二区三区免费n鬼沢| 日日夜夜精品视频| 精品国产免费视频| 在线免费观看a级片| 日韩三区视频| 国产亚洲一级高清| 欧美性生给视频| 欧美影院一区| 国外视频精品毛片| 久久青青草视频| 日韩高清一级片| 成人午夜在线影院| 日韩在线观看视频网站| 久久久久久久一区| 在线观看国产一区| 国产啊啊啊视频在线观看| 欧美日韩精品中文字幕| 亚洲成人福利在线观看| 亚洲综合资源| 亚洲成人亚洲激情| 91网站免费入口| 66视频精品| 97色伦亚洲国产| 国产一级片一区二区| 国内精品国产三级国产a久久| http;//www.99re视频| 亚洲欧美日韩免费| 中文字幕在线不卡视频| 无码播放一区二区三区| 日韩黄色在线| 日韩成人中文字幕在线观看| 青青青视频在线播放| 欧美日韩调教| 国产精品久久视频| 懂色av成人一区二区三区| 久久精品一区二区三区不卡牛牛| 中文字幕在线中文字幕日亚韩一区| 182在线视频观看| 欧美色男人天堂| 人妻换人妻a片爽麻豆| 欧美日韩高清| 97视频在线观看成人| 一级特黄aaa大片| aaa国产一区| 日本黄xxxxxxxxx100| 大菠萝精品导航| 在线不卡一区二区| 国产美女永久免费无遮挡| 激情综合在线| 成人午夜一级二级三级| 黄色小视频在线观看| 亚洲综合在线视频| 在线播放av中文字幕| 亚洲人和日本人hd| 欧美激情按摩在线| 国产精品探花视频| 久久精品在这里| 男女激情无遮挡| 91亚洲精品视频在线观看| 色yeye香蕉凹凸一区二区av| 亚洲日本视频在线观看| 成人看片黄a免费看在线| eeuss中文| 成人免费一区| 亚洲天堂男人的天堂| 亚洲天堂日韩av| 国产91丝袜在线播放九色| gogogo免费高清日本写真| 日韩三区免费| 亚洲欧美综合v| 久久精品视频7| 99久久99久久久精品齐齐| 亚洲精品少妇一区二区| 91精品福利观看| 日韩中文字幕在线视频| 懂色av蜜臀av粉嫩av喷吹| 国产亚洲欧美日韩在线一区| 欧美a v在线播放| 精品网站aaa| 97精品视频在线播放| 免费看黄色一级视频| 亚洲午夜精品在线| 日本不卡一区二区三区视频| 成人午夜影院在线观看| 精品人妻一区二区三区日产乱码| 国产精品色眯眯| 浓精h攵女乱爱av| 日本一二区不卡| 国产精品中文字幕在线| h视频网站在线观看| 欧美色窝79yyyycom| 精品伦精品一区二区三区视频密桃| 玖玖玖国产精品| 日韩激情视频| 成人在线免费av| 日韩在线观看免费网站| 国产精品久久久久精| 亚洲天堂成人在线观看| 亚洲国产欧美日韩在线| 欧美三级不卡| 久久99精品国产99久久| 成人勉费视频| 深夜成人在线观看| 国产视频在线一区| 午夜欧美2019年伦理| 极品白嫩丰满美女无套| 久久久久欧美精品| 亚洲v欧美v另类v综合v日韩v| 全球中文成人在线| 欧美乱妇高清无乱码| 欧美一级淫片aaaaaa| 欧美日韩中文字幕综合视频| 久久久久久成人网| 国产一区二区调教| 久艹视频在线免费观看| 精品久久国产| 91黄在线观看| 日韩精品极品| 日韩中文字幕视频| 人妻偷人精品一区二区三区| 在线看一区二区| 欧美黑人猛猛猛| 久久蜜臀精品av| 男女视频在线观看网站| 国产日韩亚洲| 一区二区三区四区欧美| 国产精品一区二区三区美女| 国产精品黄色影片导航在线观看| 黄色网页在线免费观看| 日韩久久免费电影| 国产精选久久久| 欧美日韩亚洲精品内裤| 久草福利资源在线| 91天堂素人约啪| 亚洲第一成肉网| 久久久久99| 菠萝蜜视频在线观看入口| 欧美日韩一二三四| 国产伦精品一区二区三区照片| 成人免费在线观看视频| 97免费在线视频| 成人在线播放| 亚洲无限av看| 人妻一区二区三区免费| 欧美日本在线一区| 五月婷婷激情视频| 亚洲夂夂婷婷色拍ww47| 国产探花视频在线| 久久综合九色综合欧美亚洲| 少妇欧美激情一区二区三区| 日韩精品电影在线观看| 青青青青草视频| 中文字幕乱码亚洲无线精品一区| 欧美一区二区视频在线| 荡女精品导航| 91久久精品一区二区别| 日本成人在线网站| 国产精品扒开腿做爽爽爽视频 | 992tv在线成人免费观看| 乱人伦中文视频在线| 亚洲图片在区色| 欧美女子与性| 日韩电影中文字幕av| 韩国av永久免费| 精品三级在线看| aaa一区二区| 在线成人av网站| 中文字幕在线观看欧美| 91久久精品一区二区二区| 一级片中文字幕| 亚洲国产美女搞黄色| 欧美激情精品久久| 亚洲天堂免费在线观看视频| 高清国产在线观看| 国产欧美一区二区精品性色| 午夜理伦三级做爰电影| 久久先锋资源网| 3d动漫精品啪啪一区二区下载| 不卡一卡二卡三乱码免费网站| 激情av中文字幕| 成人免费av网站| 精品国产乱码久久久久夜深人妻| 国产伦精一区二区三区| 国产欧美精品一二三| 国产精品一二三区在线| 国产精品中文久久久久久| 国产一区二区h| 欧美69精品久久久久久不卡| 国产91高潮流白浆在线麻豆| 久久久久久久久久久久国产精品| 国产成人免费视频网站| 苍井空张开腿实干12次| 粉嫩一区二区三区性色av| 农村末发育av片一区二区| 成人永久免费视频| 自拍视频一区二区| 久久久久久久综合| 手机看片国产日韩| 亚洲激情图片qvod| 亚洲精品77777| 日韩欧美精品免费在线| 91丨九色丨海角社区| 欧美精品xxxxbbbb| 亚洲毛片在线播放| 日韩精品一区二区三区第95| 国产午夜在线观看| 日韩在线观看成人| 女囚岛在线观看| 欧美亚洲另类制服自拍| 国产国产一区| 91精品国产91久久久久青草| 国产精品调教| 污视频在线免费观看一区二区三区| 99国产精品免费视频观看| 欧美日韩dvd| 男女精品网站| 欧美精品久久久久久久久25p| 国产精品自拍一区| 国产一级二级在线观看| 欧美国产激情二区三区| 欧美三级 欧美一级| 欧美性xxxxx| 国产精品久久久久久久久久久久久久久久久久| 日韩一区和二区| 免费在线毛片| 欧美成人免费一级人片100| 午夜影院在线播放| 国产一区香蕉久久| 秋霞在线一区| 日本免费在线视频观看| 午夜在线精品偷拍| 手机精品视频在线| 国产欧美精品在线观看| 久草视频免费在线| 欧亚一区二区三区| 高h调教冰块play男男双性文| 中文字幕亚洲欧美一区二区三区| 日本色护士高潮视频在线观看| 欧洲精品在线视频| 日韩欧美一级| 亚洲国产精品一区二区第四页av| 欧美日韩亚洲三区| www.夜夜爽| 久久久久久久久99精品| 日韩av片在线播放| 欧美一区二区精品久久911| 国产中文字幕在线观看| 高清欧美电影在线| 激情综合婷婷| 亚洲国产精品www| 老妇喷水一区二区三区| 中文字幕在线国产| 亚洲精品大片www| 中文字幕视频二区| 亚洲色图日韩av| 国产传媒在线观看| 国产精品区一区二区三含羞草| 日韩在线欧美| 国产精品一区二区羞羞答答| 26uuu亚洲综合色| 国产成人无码一区二区三区在线 | 可以免费看毛片的网站| 久久久91精品国产| 欧美三级电影网址| 日韩在线电影一区| 丝袜亚洲另类丝袜在线| 国产熟女高潮一区二区三区 | 国产亚洲高清在线观看| 手机成人在线| 日日摸夜夜添夜夜添国产精品| 91玉足脚交白嫩脚丫| 亚洲韩国一区二区三区| 国产喷水吹潮视频www| 久久精品电影网站| 国产情侣一区二区三区| 天堂社区 天堂综合网 天堂资源最新版| 亚洲综合三区| 中文字幕5566| 一本久道中文字幕精品亚洲嫩| 五月婷婷在线观看视频| 欧美专区在线视频| 中文字幕亚洲影视| 激情综合网婷婷| 国产亚洲欧美色| 瑟瑟视频在线免费观看| 在线观看国产成人av片| 国产精品伦一区二区| 亚洲日本精品| 国产制服丝袜一区| 国产女人被狂躁到高潮小说| 日韩精品专区在线影院重磅| 任你弄在线视频免费观看| 国产精品免费一区二区三区在线观看| 国产在线不卡| 国产精品久久久久久亚洲色| 午夜精品成人在线视频| 青青免费在线视频| 国产精品亚洲视频在线观看| 99精品视频精品精品视频| 亚洲精品乱码久久久久久9色| 亚洲国产乱码最新视频| 视频二区在线| 国产精品日韩专区| 五月天久久久| 香蕉视频免费网站| 色婷婷久久一区二区三区麻豆| 国产免费av在线| 亚洲综合中文字幕在线观看| 黄色av日韩| 国产中年熟女高潮大集合| 欧美色图片你懂的| 丰乳肥臀在线| 日韩免费毛片| 国产一区二区精品久久99| 日韩少妇高潮抽搐| 正在播放国产一区| jizzjizzjizz欧美| 十八禁视频网站在线观看| 中文字幕中文字幕中文字幕亚洲无线 | caoporn国产精品免费视频| 成人综合国产精品| 日韩视频中文| 国产又粗又长又黄的视频| 欧美精品一区二区三区在线| 97成人资源| 久久国产精品免费观看| 99精品国产一区二区三区不卡| 久久久久久av无码免费看大片| 欧美激情18p| 日韩.com| 成人免费无码大片a毛片| 欧美精品黑人性xxxx|