2010 年初的時候,Facebook 的前端性能研究小組開始了他們的優化項目,通過了六個月的努力,成功的將我的空間主頁面加載耗時由原來的5 秒減小爲如今的2.5 秒。這是一個很是了不得的成就,也給用戶來帶來了很好的體驗。在優化項目中,工程師提出了一種新的頁面加載技術,稱之爲Bigpipe。目前淘寶和 Facebook 面臨的問題很是類似:海量數據和頁面過大,若是能夠在詳情頁、列表頁中使用bigpipe,或者在webx中集成bigpipe,將會帶來明顯的頁面加載 速度提高。php
《高性能網站建設指南》一書中指出,只有 10%~20%的最終用戶響應時間是花費在從Web 服務器獲取HTML 文檔並傳送到瀏覽器中的。若是但願可以有效地減小頁面的響應時間,就必須關注剩餘的80%~90%的最終用戶體驗。作個比較,若是對後臺業務邏輯進行優 化,效率提升了50%,但最終的頁面響應時間只減小了5%~10%,由於它所佔的比重較少。若是對前端進行性能優化,效率提高50%,則會使最終頁面響應 時間減小40%~45%。這是多麼可觀的數字!另外,前端的性能優化通常比業務邏輯的優化更加容易。因此,前端優化投入小,見效快,性價比極高,須要投入 更多的關注。css
2.2 BigPipe與AJAXhtml
Web2.0的重要特徵是網頁顯示大量動態內容,即 web2.0注重網頁與用戶的交互。其核心技術是AJAX,現在全部主流網站都或多或少使用AJAX。與AJAX相似,BigPipe 實現了分塊兒的概念,使頁面可以分步輸出,即每次輸出一部分網頁內容。接下來討論BigPipe 與AJAX 的區別。前端
簡單的說,BigPipe 比AJAX 有三個好處:java
AJAX 的核心是XMLHttpRequest,客戶端須要異步的向服務器端發送請求,而後將傳送過來的內容動態添加到網頁上。如此實現存在一些缺陷,即發送往返 請求須要耗費時間,而BigPipe 技術使瀏覽器並不須要發送XMLHttpRequest 請求,這樣就節省時間損耗。web
使用AJAX時,瀏覽器和服務器的工做順序執行。服務器必須等待瀏覽器的請求,這樣就會形成服務器的空閒。瀏覽器工做時,服務器在等待,而服務器工做時, 瀏覽器在等待,這也是一種性能的浪費。使用BigPipe,瀏覽器和服務器能夠並行同時工做,服務器不須要等待瀏覽器的請求,而是一直處於加載頁面內容的 工做階段,這就會使效率獲得更大的提升。瀏覽器
減小瀏覽器發送到請求。對一個5億用戶的網站來講,減小了使用AJAX額外帶來的請求,會減小服務器的負載,一樣會帶來很大的性能提高。性能優化
基於以上三點,Facebook 在進行頁面優化時採用了BigPipe 技術。目前淘寶主搜索結果頁中,須要加載類目,相關搜索,寶貝列表,廣告等內容,前端這裏使用php 的curl 的批處理來併發的訪問引擎獲取相應的數據,並進行分步輸出。這種模式仍是與bigpipe有些不一樣,這點後面會講到。通常來說,在頁面比較大,並且比較復 雜,樣式表和腳本比較多的狀況下,使用BigPipe 來優化輸出頁面是比較合適的。另外很是重要的一點,BigPipe 並不改變瀏覽器的結構與網絡協議,僅使用JS就能夠實現,用戶不須要作任何的設置,就會看到明顯的訪問時間縮短。服務器
3 目前的問題 接下來討論現有的瓶頸。面對網頁愈來愈大的狀況,尤爲是大量的css 文件和js 文件須要加載,傳統的頁面加載模型很難知足這樣的需求,直接結果就是頁面加載速度變慢,這毫不是咱們但願看到的。目前的技術實現中,用戶提出頁面訪問請求後,頁面的完整加載流程以下:網絡
用戶訪問網頁,瀏覽器發送一個HTTP 請求到網絡服務器
服務器解析這個請求,而後從存儲層去數據,接着生成一個html 文件內容,並在一個HTTP Response 中把它傳送給客戶端
HTTP response 在網絡中傳輸
瀏覽器解析這個Response ,建立一個DOM 樹,而後下載所需的CSS 和JS文件
下載完CSS 文件後,瀏覽器解析他們而且應用在相應的內容上
下載完JS 後,瀏覽器解析和執行他們
圖1.
完整流程見圖1.圖中左側表示服務器,右側表示瀏覽 器。瀏覽器先發送請求,而後服務器進行查找數據,生成頁面,返回html 代碼,最後瀏覽器進行渲染頁面。這種模式有很是明顯的缺陷:流程中的操做有着嚴格的順序,若是前面的一個操做沒有執行結束,後面的操做就不能執行,即操做 之間是不能重疊。這樣就形成性能的瓶頸:服務器生成一個頁面的內容時,瀏覽器是空閒的,顯示空白內容;而當瀏覽器加載渲染頁面內容時,服務器又是空閒的, 時間與性能的浪費由此產生。
圖2.
考慮圖2 中現有的服務模型,橫軸表示花費的時間。黃色表示在服務器的生成頁面內容的時間,白色表示網絡傳輸時間,藍色表示在瀏覽器渲染頁面的時間。能夠看出,現有 的模式形成很大的時間浪費。 考慮圖3 中的狀況,圖中綠色表示服務器從春儲層取查數據花費的時間,在海量數據下,當執行一條很費時的查詢語句時(以下圖右側),服務器就就阻塞在那 裏沒有其餘操做,而瀏覽器更是得不到任何反饋。這會形成很是不友好的用戶體驗,用戶不知道什麼緣由使他們等待很長時間。
圖3.
4 BigPipe思想與原理 面對上述問題,咱們看下BigPipe的解決辦法。 BigPipe提出分塊的概念,即根據頁面內容位置的不一樣,將整個頁面分紅不一樣的塊兒– 稱爲pagelet。該技術的設計者Changhao Jiang 是研究電子電路的博士,可能從微機上獲得了啓發,將衆多pagelet加載的不一樣階段像流水線同樣在瀏覽器和服務器上執行,這樣就作到了瀏覽器和服務器的 並行化,從而達到重疊服務器端運行時間和瀏覽器端運行時間的目的。使用BigPipe 不只能夠節省時間,使加載的時間縮短,並且能夠同過pagelet的分步輸出,使一部分的頁面內容更快的輸出,從而得到更好的用戶體驗。BigPipe 中,用戶提出頁面訪問請求後,頁面的完整加載流程以下:
Request parsing:服務器解析和檢查http request
Datafetching:服務器從存儲層獲取數據
Markup generation:服務器生成html 標記
Network transport : 網絡傳輸response
CSS downloading:瀏覽器下載CSS
DOM tree construction and CSS styling:瀏覽器生成DOM 樹,而且使用CSS
JavaScript downloading: 瀏覽器下載頁面引用的JS 文件
JavaScript execution: 瀏覽器執行頁面JS代碼
這個8 個流程幾乎與上文中提到現有的模式沒有區別,但這整個流程只是一個pagelet 的完整流程,而多個pagelet 的不一樣操做階段就能夠像流水線同樣進行執行了。
圖4
圖4 中,能夠看出BigPipe 對原有的模式進行的改進。瀏覽器發送訪問請求,而後瀏覽器分步返回不一樣的pagelet的內容,具體實現將在後面介紹.考慮圖5中的改進,BigPipe 打破了原有的順序執行,將頁面分紅不一樣的pagelet ,如此一來,全部的pagelet 的執行時間累加起來仍是原有的時間。可是, 經過疊加不一樣pagelet 的不一樣階段的執行時間,使總的運行時間大大減小,這就是Bigpipe減小頁面加載時間的祕密。
FaceBook的頁面被分紅了不少不一樣的pagelets,如圖:
圖5
8 結論
通過上面的討論,咱們能夠發現,使用BigPipe 技術優化頁面能夠有四個好處:
1. 減小頁面的加載時間
2. 使頁面分步輸出,改善用戶體驗
3. 使頁面結構化,提升可讀性,更加便於維護
4. 每一個pagelet 都是相互獨立的,若是有一個pagelet 的內容不能加載,並不會影響其餘的pagelet 的內容顯示。
同時,BigPipe 是一項比較新的理念, 在去年六月份才由Facebook 的工程師提出,應該說有很大的發展空間。BigPipe 的原理很是簡單,並不會引入不少額外的負擔,適用範圍很廣,容易上手。幾乎全部的網頁均可以採用BigPipe 的理念去進行優化,尤爲對因而有着海量數據和網頁比較大的網站,將會以低成本帶來高回報。通常來說,網站越大,腳本和樣式表越多,瀏覽器版本越舊,網絡環 境越差,優化的結果越可觀。
9 引用與參考資料
1.做者的博客:http://www.facebook.com/note.php?note_id=389414033919
2.bigpipe技術的ppt:http://twork.taobao.net/books/237
3.bigpipe的java實現:http://codemonkeyism.com/facebook-bigpipe-java/
4.一篇介紹bigpipe的文章:http://www.54chen.com/architecture/rose-pipe-http-54chen.html
5.另外一篇挺有用的文章:http://www.cnblogs.com/BearsTaR/archive/2010/06/18/facebook_html_chunk.html
6.人人網相似bigpipe的技術–rosepipe:http://www.54chen.com/architecture/rose-open-source-portal-framework.html
7.《高性能網站建設指南》by Steve Souder, Copyright 2007 Steve Sounder, 978-0-596- 52930-7