轉:瀏覽器加載頁面的過程與頁面性能優化

  本文是轉帖,原文:http://www.baiduux.com/blog/2011/02/15/browser-loading/
javascript

發佈日期:2011年2月15日php

本文將探討瀏覽器渲染的loading過程,主要有2個目的:css

  • 瞭解瀏覽器在loading過程當中的實現細節,具體都作了什麼
  • 研究如何根據瀏覽器的實現原理進行優化,提高頁面響應速度

因爲loading和parsing是相互交織、錯綜複雜的,這裏面有大量的知識點,爲了不過於發散本文將不會對每一個細節都深刻研究,而是將重點 放在開發中容易控制的部分(Web前端和Web Server),同時因爲瀏覽器種類繁多且不一樣版本間差距很大,本文將側重一些較新的瀏覽器特性html

現有知識

提高頁面性能方面已經有不少前人的優秀經驗了,如Best Practices for Speeding Up Your Web SiteWeb Performance Best Practices前端

本文主要專一其中加載部分的優化,總結起來主要有如下幾點:html5

  • 帶寬
    • 使用CDN
    • 壓縮js、css,圖片優化
  • HTTP優化
    • 減小轉向
    • 減小請求數
    • 緩存
    • 儘早Flush
    • 使用gzip
    • 減小cookie
    • 使用GET
  • DNS優化
    • 減小域名解析時間
    • 增多域名提升併發
  • JavaScript
    • 放頁面底部
    • defer/async
  • CSS
    • 放頁面頭部
    • 避免@import
  • 其它
    • 預加載

接下來就從瀏覽器各個部分的實現來梳理性能優化方法java

 

network

首先是網絡層部分,這方面的實現大部分是經過調用操做系統或gui框架提供的apinginx

DNS

爲了應對DNS查詢的延遲問題,一些新的瀏覽器會緩存或預解析DNS,如當Chrome訪問google頁面的搜索結果時,它會取出連接中的域名進行預解析git

固然,Chrome並非每次都將頁面中的全部連接的域名都拿來預解析,爲了既提高用戶體驗又不會對DNS形成太大負擔,Chrome作了不少細節的優化,如經過學習用戶以前的行爲來進行判斷github

Chrome在啓動時還會預先解析用戶常去的網站,具體能夠參考DNS Prefetching,當前Chrome中的DNS緩存狀況能夠經過net-internals頁面來察看

爲了幫助瀏覽器更好地進行DNS的預解析,能夠在html中加上如下這句標籤來提示瀏覽器

<link rel="dns-prefetch" href="//HOSTNAME.com">

除此以外還可使用HTTP header中的X-DNS-Prefetch-Control來控制瀏覽器是否進行預解析,它有on和off兩個值,更詳細的信息請參考Controlling DNS prefetching



DNS優化的原理和方法 


 

Yahoo和Google都有本身的建設高性能網站最佳實踐, 我不作贅述, 須要瞭解的自行查閱資料:

上面的最佳實踐條例其實也就是咱們常在YSlowPageSpeed這兩個Firefox的add-ons中看到的網站檢測結果的參考標準.

而整個WPO實際上是對瀏覽器(browser)的加載(load)和解析(parse)過程當中的一些消耗行爲進行優化, 而load和parse在整個瀏覽器工做過程當中又互相糾結互相做用.

在這篇文字中討論的更可能是FE們可以伸手處理或者經過達成共識的方法來進行快速推進Tech們協助的一些事情.

OK, 咱們慢慢把瀏覽器的工做過程掰細了看吧.

首先, 咱們先整一個瀏覽器如何找到一個網站的簡易工做原理 – DNS查詢:

首先當用戶在瀏覽器的地址欄中敲入了網站的網址 ( 好比: alibaba.com ) ,這時瀏覽器會首先經過訪問的域名來定位到IP (DNS) 從而找到去哪裏獲取資源, 這時, 瀏覽器會依次進行以下查找:

1. 瀏覽器緩存 :

瀏覽器首先會在本身的緩存中查找有沒有對應的域名 – IP匹配, 若是好運的話, 這裏就能夠直接嘗試去訪問資源了, 若是運氣平平則往下走吧.

2. 系統緩存 :

瀏覽器緩存中沒有命中, 瀏覽器會告訴操做系統:」嘿, 我在我本身口袋裏沒找到, 可能丟了, 我得去你那看看」, 而後, 一個系統進程(?)調取系統中的DNS緩存進行查詢, 重複上一條的運氣判斷…

3. 路由器緩存 :

走到這, 運氣還真不太好啊, 操做系統也沒轍了, 那怎麼辦呢, 向路由去要要看吧… 重複運氣判斷…

4. ISP DNS緩存 :

好吧, 真不知道說運氣好仍是運氣很差了, 不廢話, 去ISP (網絡提供商) 的DNS緩存服務器中尋找了, 通常狀況下, 在ISP端的緩存中都能找到相應的緩存記錄了, 不應這麼背了, 或者… 您的ISP有夠菜…

5. 遞歸搜索

最無奈的狀況發生了, 在前面都沒有辦法命中的DNS緩存的狀況下, ISP的DNS服務器開始從root域名服務器開始進行遞歸, 順序是從.com頂級域名服務器到alibaba的域名服務器, 再沒找到…好吧, 您認爲您要去的網站真的公開存在麼…?

要強調的是, 不僅是對網站第一次的域名訪問須要作這樣一次查詢工做, 在對頁面中的資源引用的域名解析時同樣會有這樣的一系列工做. 最明顯的就是啓用全新域名來作靜態資源存儲服務時, 基本上上述的1 – 5個步驟都得走上幾遍. 才能讓新域名在各DNS緩存服務器上留下記錄.

在這個話題上, 關於DNS的相似系統級的解決方案不是FE可以控制得了的, 咱們q能夠在涉及到DNS時有些小Tips來從中作些事情.

好吧, 第一項.DNS相關的優化:

常規實踐 : DNS解析的複雜性決定了不當的使用多域名獲取資源會形成沒必要要的性能開銷. 在WPO中, 不少優化工做是很藝術的, 在DNS和HTTP這兩方面優化是就能夠看到這個神奇的藝術性:

DNS的優化, 固然是儘量少的形成DNS查詢開銷, 而在HTTP優化的策略中有一項優化措施是避免單域名下鏈接數的缺陷來進行資源多通道下載, 實施的細節會在<HTTP優化的原理和方法> 中詳細介紹, 在這裏只是簡單的提一下, 靜態資源多域名服務能夠繞過瀏覽器單域名載入資源時並行鏈接數的限制, DNS優化須要咱們儘量少的域名解析, HTTP優化時須要咱們適當的使用多域名服務, 那怎麼樣讓兩個優化實踐都可以比較好的實施呢? [todo]

優雅降級 : 在某些現代瀏覽器 ( Google Chrome, Firefox 3.5+ ) 中, 已經可以支持DNS的預取了, 怎麼個預取呢? 就是在瀏覽器加載網頁時, 對網頁中的<link>或者<a>的href屬性中的域名進行後臺的預解析(上文中的 1- 5步), 而且將解析結果緩存在瀏覽器端, 當用戶在真正點擊連接時, 省去在當下的DNS解析消耗, 把這個消耗過程轉嫁到用戶沒法感知的瀏覽過程當中去.

第一, 現代瀏覽器已經支持且默認打開了DNS Prefetch的功能. 固然也能夠經過瀏覽器的配置來管理該功能:

用Firefox3.5+能夠這樣: 瀏覽器默認就打開了HTTP協議下的DNS預取功能, 默認關閉HTTPS協議下的DNS預取功能, 可經過 about:config 的network.dns.disablePrefetchnetwork.dns.disablePrefetchFromHTTPS<兩個選項來控制兩種協議下的預取功能.

Chrome管理DNS Prefetch方法暫時缺乏.

第二, 能夠經過用meta信息來告知瀏覽器, 我這頁面要作DNS預取:

 

<meta http-equiv="x-dns-prefetch-control" content="on" />

第三,能夠使用link標籤來強制對DNS作預取:

 

 

<link rel="dns-prefetch" href="http://www.alibaba.com/" />

[todo DEMO]

擴展閱讀:

另, 小康(lazyKang)同窗發現一個神奇的現象:

在一次無緩存訪問中,  在一個並行下載通道內, 就算是同域名的狀況, 也會形成DNS並行解析的消耗…

DNS預解析一次, 應該就能避免這樣的問題, 空了作個DEMO試試看.

 



CDN

本文不打算詳細討論這個話題,感興趣的讀者能夠閱讀Content delivery network

在性能方面與此相關的一個問題是用戶可能使用自定義的DNS,如OpenDNS或Google的8.8.8.8,須要注意對這種狀況進行處理

link prefetch

因爲Web頁面加載是同步模型,這意味着瀏覽器在執行js操做時須要將後續html的加載和解析暫停,由於js中有可能會調用 document.write來改變dom節點,不少瀏覽器除了html以外還會將css的加載暫停,由於js可能會獲取dom節點的樣式信息,這個暫停 會致使頁面展示速度變慢,爲了應對這個問題,Mozilla等瀏覽器會在執行js的同時簡單解析後面的html,提取出連接地址提早下載,注意這裏僅是先 下載內容,並不會開始解析和執行

這一行爲還能夠經過在頁面中加入如下標籤來提示瀏覽器

<link rel="prefetch" href="http://">

但這種寫法目前並無成爲正式的標準,也只有Mozilla真正實現了該功能,能夠看看Link prefetching FAQ

WebKit也在嘗試該功能,具體實現是在HTMLLinkElement的process成員函數中,它會調用ResourceHandle::prepareForURL()函數,目前從實現看它是僅僅用作DNS預解析的,和Mozilla對這個屬性的處理不一致

對於不在當前頁面中的連接,若是須要預下載後續內容能夠用js來實現,請參考這篇文章Preload CSS/JavaScript without execution

預下載後續內容還能作不少細緻的優化,如在Velocity China
2010
中,來自騰訊的黃希彤介紹了騰訊產品中使用的交叉預下載方案,利用空閒時間段的流量來預加載,這樣即提高了用戶訪問後續頁面的速度,又不會影響到高峯期的流量,值得借鑑

預渲染

預渲染比預下載更進一步,不只僅下載頁面,並且還會預先將它渲染出來,目前在Chrome(9.0.597.0)中有實現,不過須要在about:flags中將’Web Page Prerendering’開啓

不得不說Chrome的性能優化作得很細緻,各方面都考慮到了,也難怪Chrome的速度很快

http

在網絡層之上咱們主要關注的是HTTP協議,這裏將主要討論1.1版本,若是須要了解1.0和1.1的區別請參考Key Differences between HTTP/1.0 and HTTP/1.1

header

首先來看http中的header部分

header大小

header的大小通常會有500 多字節,cookie內容較多的狀況下甚至能夠達到1k以上,而目前通常寬帶都是上傳速度慢過下載速度,因此若是小文件多時,甚至會出現頁面性能瓶頸出在 用戶上傳速度上的狀況,因此縮小header體積是頗有必要的,尤爲是對不須要cookie的靜態文件上,最好將這些靜態文件放到另外一個域名上

將靜態文件放到另外一個域名上會出現的現象是,一旦靜態文件的域名出現問題就會對頁面加載形成嚴重影響,尤爲是放到頂部的js,若是它的加載受阻會致使頁面展示長時間空白,因此對於流量大且內容簡單的首頁,最好使用內嵌的js和css

header的擴展屬性

header中有些擴展屬性能夠用來保護站點,瞭解它們是有益處的

  • X-Frame-Options
    • 這個屬性能夠避免網站被使用frame、iframe的方式嵌入,解決使用js判斷會被var location;破解的問題,IE八、Firefox3.六、Chrome4以上的版本都支持
  • X-XSS-Protection
    • 這是IE8引入的擴展header,在默認狀況下IE8會自動攔截明顯的XSS攻擊,如query中寫script標籤並在返回的內容中包含這項標籤,若是須要禁止能夠將它的值設爲0,由於這個XSS過濾有可能致使問題,如IE8 XSS Filter Bug
  • X-Requested-With
    • 用來標識Ajax請求,大部分js框架都會加入這個header
  • X-Content-Type-Options
    • 若是是html內容的文件,即便用Content-Type: text/plain;的header,IE仍然會識別成html來顯示,爲了不它所帶來的安全隱患,在IE8中能夠經過在header中設置X- Content-Type-Options: nosniff來關閉它的自動識別功能

使用get請求來提升性能

首先性能因素不該該是考慮使用get仍是post的主要緣由,首先關注的應該是否符合HTTP中標準中的約定,get應該用作數據的獲取而不是提交

之因此用get性能更好的緣由是有測試代表,即便數據很小,大部分瀏覽器(除了Firefox)在使用post時也會發送兩個TCP的packet,因此性能上會有損失

鏈接數

在HTTP/1.1協議下,單個域名的最大鏈接數在IE6中是2個,而在其它瀏覽器中通常4-8個,而總體最大連接數在30左右

而在HTTP/1.0協議下,IE六、7單個域名的最大連接數能夠達到4個,在Even Faster Web Sites一書中的11章還推薦了對靜態文件服務使用HTTP/1.0協議來提升IE六、7瀏覽器的速度

瀏覽器連接數的詳細信息能夠在Browserscope上查到

使用多個域名能夠提升併發,但前提是每一個域名速度都是一樣很快的,不然就會出現某個域名很慢會成爲性能瓶頸的問題

cache

主流瀏覽器都遵循http規範中的Caching in HTTP來實現的

從HTTP cache的角度來看,瀏覽器的請求分爲2種類型:conditional requests 和 unconditional requests

unconditional請求是當本地沒有緩存或強制刷新時發的請求,web server返回200的heder,並將內容發送給瀏覽器

而conditional則是當本地有緩存時的請求,它有兩種:

  1. 使用了Expires或Cache-Control,若是本地版本沒有過時,瀏覽器不會發出請求
  2. 若是過時了且使用了ETag 或Last-Modified,瀏覽器會發起conditional請求,附上If-Modified-Since或If-None-Match的 header,web server根據它來判斷文件是否過時,若是沒有過時就返回304的header(不返回內容),瀏覽器見到304後會直接使用本地緩存中的文件

如下是IE發送conditional requests的條件,從MSDN上抄來

  • The cached item is no longer fresh according to Cache-Control or Expires
  • The cached item was delivered with a VARY header
  • The containing page was navigated to via META REFRESH
  • JavaScript in the page called reload on the location object, passing TRUE
  • The request was for a cross-host HTTPS resource on browser startup
  • The user refreshed the page

簡單的來講,點擊刷新按鈕或按下F5時會發出conditional請求,而按下ctrl的同時點擊刷新按鈕或按下F5時會發出unconditional請求

須要進一步學習請閱讀:

前進後退的處理

瀏覽器會盡量地優化前進後退,使得在前進後退時不須要從新渲染頁面,就好像將當前頁面先「暫停」了,後退時再從新運行這個「暫停」的頁面

不過並非全部頁面都能「暫停」的,如當頁面中有函數監聽unload事件時,因此若是頁面中的連接是原窗口打開的,對於unload事件的監聽會影響頁面在前進後時的性能

在新版的WebKit裏,在事件的對象中新增了一個persisted屬性,能夠用它來區分首次載入和經過後退鍵載入這兩種不一樣的狀況,而在Firefox中可使用pageshow和pagehide這兩個事件

unload事件在瀏覽器的實現中有不少不肯定性因素,因此不該該用它來記錄重要的事情,而是應該經過按期更新cookie或按期保存副本(如用戶備份編輯文章到草稿中)等方式來解決問題

具體細節能夠參考WebKit上的這2篇文章:

cookie

瀏覽器中對cookie的支持通常是網絡層庫來實現的,瀏覽器不須要關心,如IE使用的是WinINET

須要注意IE對cookie的支持是基於pre-RFC Netscape draft spec for cookies的,和標準有些不一樣,在設定cookie時會出現轉義不全致使的問題,如在ie和webkit中會忽略「=」,不過大部分web開發程序(如php語言)都會處理好,自行編寫http交互時則須要注意

p3p問題

在IE中默認狀況下iframe中的頁面若是域名和當前頁面不一樣,iframe中的頁面是不會收到cookie的,這時須要經過設置p3p來解決,具體能夠察看微軟官方的文檔,加上以下header便可

P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"

這對於用iframe嵌入到其它網站中的第三方應用很重要

編碼識別

頁面的編碼能夠在http header或meta標籤中指明,對於沒有指明編碼的頁面,瀏覽器會根據是否設置了auto detect來進行編碼識別(如在chrome中的View-Encoding菜單)

關於編碼識別,Mozilla開源了其中的Mozilla Charset Detectors模塊,感興趣的能夠對其進行學習

建議在http
header中指定編碼,若是是在meta中指定,瀏覽器在獲得html頁面後會首先讀取一部份內容,進行簡單的meta標籤解析來得到頁面編碼,如WebKit代碼中的HTMLMetaCharsetParser.cpp,能夠看出它的實現是查找charset屬性的值,除了WebKit之外的其它瀏覽器也是相似的作法,這就是爲什麼HTML5中直接使用以下的寫法瀏覽器都支持

<meta charset="utf-8">

須要注意不設定編碼會致使不可預測的問題,應儘量作到明確指定

chunked

瀏覽器在加載html時,只要網絡層返回一部分數據後就會開始解析,並下載其中的js、圖片,而不須要等到全部html都下載完成纔開始,這就意味着若是能夠分段將數據發送給瀏覽器,就能提升頁面的性能,這就是chunked的做用,具體協議細節請參考Chunked Transfer Coding

在具體實現上,php中能夠經過flush函數來實現,不過其中有很多須要注意的問題,如php的配置、web server、某些IE版本的問題等,具體請參考php文檔及評論

注意這種方式只適用於html頁面,對於xml類型的頁面,因爲xml的嚴格語法要求,瀏覽器只能等到xml所有下載完成後纔會開始解析,這就意味着同等狀況下,xml類型的頁面展示速度必然比html慢,因此不推薦使用xml

即便不使用這種http傳輸方式,瀏覽器中html加載也是邊下載邊解析的,而不需等待全部html內容都下載完纔開始,因此實際上chunked 主要節省的是等待服務器響應的時間,由於這樣能夠作到服務器計算完一部分頁面內容後就馬上返回,而不是等到全部頁面都計算都完成才返回,將操做並行

另外Facebook所使用的BigPipe其實是在應用層將頁面分爲了多個部分,從而作到了服務端和瀏覽器計算的並行

keepalive

keepalive使得在完成一個請求後能夠不關閉socket鏈接,後續能夠重複使用該鏈接發送請求,在HTTP/1.0和HTTP/1.1中都有支持,在HTTP/1.1中默認是打開的

keepalive在瀏覽器中都會有超時時間,避免長期和服務器保持鏈接,如IE是60秒

另外須要注意的是若是使用阻塞IO(如apache),開啓keepalive保持鏈接會很消耗資源,能夠考慮使用nginx、lighttpd等其它web server,具體請參考相關文檔,這裏就不展開描述

pipelining

pipelining是HTTP/1.1協議中的一個技術,能讓多個HTTP請求同時經過一個socket傳輸,注意它和keepalive的區 別,keepalive能在一個socket中傳輸多個HTTP,但這些HTTP請求都是串行的,而pipelining則是並行的

惋惜目前絕大部分瀏覽器在默認狀況下都不支持,已知目前只有opera是默認支持的,加上不少網絡代理對其支持很差致使容易出現各類問題,因此並無普遍應用

SPDY

SPDY是google提出的對HTTP協議的改進,主要是目的是提升加載速度,主要有幾點:

  • Mutiplexed streams
    • 能夠在一個TCP中傳輸各類數據,減小連接的耗時
  • Request prioritization
    • 請求分級,便於發送方定義哪些請求是重要的
  • HTTP header compression
    • header壓縮,減小數據量

frame

從實現上看,frame類(包括iframe和frameset)的標籤是最耗時的,並且會致使多一個請求,因此最好減小frame數量

resticted

若是要嵌入不信任的網站,可使用這個屬性值來禁止頁面中js、ActiveX的執行,能夠參考msdn的文檔

<iframe security="restricted" src=""></iframe>

javascript

加載

對於html的script標籤,若是是外鏈的狀況,如:

<script src="a.js"></script>

瀏覽器對它的處理主要有2部分:下載和執行

下載在有些瀏覽器中是並行的,有些瀏覽器中是串行的,如IE八、Firefox三、Chrome2都是串行下載的

執行在全部瀏覽器中默認都是阻塞的,當js在執行時不會進行html解析等其它操做,因此頁面頂部的js不宜過大,由於那樣將致使頁面長時間空白,對於這些外鏈js,有2個屬性能夠減小它們對頁面加載的影響,分別是:

  • async
    • 標識js是否異步執行,當有這個屬性時則不阻塞當前頁面的加載,並在js下載完後馬上執行
    • 不能保證多個script標籤的執行順序
  • defer
    • 標示js是否延遲執行,當有這個屬性時js的執行會推遲到頁面解析完成以後
    • 能夠保證多個script標籤的執行順序

下圖來自Asynchronous and deferred JavaScript execution explained,清晰地解釋了普通狀況和這2種狀況下的區別

須要注意的是這兩個屬性目前對於內嵌的js是無效的

而對於dom中建立的script標籤在瀏覽器中則是異步的,以下所示:

var script = document.createElement('script');
script.src = 'a.js';
document.getElementsByTagName('head')[0].appendChild(script);

爲了解決js阻塞頁面的問題,能夠利用瀏覽器不認識的屬性來先下載js後再執行,如ControlJS就是這樣作的,它能提升頁面的相應速度,不過須要注意處理在js未加載完時的顯示效果

document.write

document.write是不推薦的api,對於標示有async或defer屬性的script標籤,使用它會致使不可預料的結果,除此以外還有如下場景是不該該使用它的:

  • 使用document.createElement建立的script
  • 事件觸發的函數中,如onclick
  • setTimeout/setInterval

簡單來講,document.write只適合用在外鏈的script標籤中,它最多見的場景是在廣告中,因爲廣告可能包含大量html,這時須要注意標籤的閉合,若是寫入的內容不少,爲了不受到頁面的影響,可使用相似Google AdSense的方式,經過建立iframe來放置廣告,這樣作還能減小廣告中的js執行對當前頁面性能的影響

另外,可使用ADsafe等方案來保證嵌入第三方廣告的安全,請參考如何安全地嵌入第三方js – FBML/caja/sandbox/ADsafe簡介

script標籤放底部

將script標籤放底部能夠提升頁面展示給用戶的速度,然而不少時候事情並沒那麼簡單,如頁面中的有些功能是依賴js的,因此更多的還須要根據實際需求進行調整

  • 嘗試用Doloto分析出哪些JS和初始展示是無關的,將那些沒必要要的js延遲加載
  • 手工進行分離,如能夠先顯示出按鈕,但狀態是不可點,等JS加載完成後再改爲可點的

傳輸

js壓縮可使用YUI CompressorClosure Compiler

gwt中的js壓縮還針對gzip進行了優化,進一步減少傳輸的體積,具體請閱讀On Reducing the Size of Compressed Javascript

css

比起js放底部,css放頁面頂部就比較容易作到

@import

使用@import在IE下會因爲css加載延後而致使頁面展示比使用link標籤慢,不過目前幾乎沒有人使用@import,因此問題不大,具體細節請參考don’t use @import

selector的優化

瀏覽器在構建DOM樹的過程當中會同時構建Render樹,咱們能夠簡單的認爲瀏覽器在遇到每個DOM節點時,都會遍歷全部selector來判斷這個節點會被哪些selector影響到

不過實際上瀏覽器通常是從右至左來判斷selector是否命中的,對於ID、Class、Tag、Universal和Page的規則是經過 hashmap的方式來查找的,它們並不會遍歷全部selector,因此selector越精確越好,google page-speed中的一篇文檔Use efficient CSS selectors詳細說明了如何優化selector的寫法

另外一個比較好的方法是從架構層面進行優化,將頁面不一樣部分的模塊和樣式綁定,經過不一樣組合的方式來生成頁面,避免後續頁面頂部的css只增不減,愈來愈複雜和混亂的問題,能夠參考Facebook的靜態文件管理

工具

如下整理一些性能優化相關的工具及方法

Browserscope

以前提到的http://www.browserscope.org收集了各類瀏覽器參數的對比,如最大連接數等信息,方便參考

Navigation Timing

Navigation Timing是還在草案中的獲取頁面性能數據api,能方便頁面進行性能優化的分析

傳統的頁面分析方法是經過javascript的時間來計算,沒法獲取頁面在網絡及渲染上所花的時間,使用Navigation Timing就能很好地解決這個問題,具體它能取到哪些數據能夠經過下圖瞭解(來自w3c)

目前這個api較新,目前只在一些比較新的瀏覽器上有支持,如Chrome、IE9,但也佔用必定的市場份額了,能夠如今就用起來

boomerang

yahoo開源的一個頁面性能檢測工具,它的原理是經過監聽頁面的onbeforeunload事件,而後設置一個cookie,並在另外一個頁面中 設置onload事件,若是cookie中有設置且和頁面的refer保持一致,則經過這兩個事件的事件來衡量當前頁面的加載時間

另外就是經過靜態圖片來衡量帶寬和網絡延遲,具體能夠看boomerang

檢測工具

reference

相關文章
相關標籤/搜索