Yahoo的前端最佳化實踐中有一條是先把html裡的部分先輸出(Flush the Buffer Early),這樣做瀏覽器得到head後能先下載head裡的css/js檔案,而不用等到整個html下載完了才去下載head裡的css/js,從而提高網頁開啟的速度。
http1.1裡增加了一個Transfer-Encoding: chunked前序,這個前序的作用可以把報文分成多塊輸出。
報文的格式如下:
Java代碼
Chunked-Body = *chunk
"0" CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
hex-no-zero =
chunk-size = hex-no-zero *HEX
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
footer = *entity-header
Chunked-Body = *chunk
"0" CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
hex-no-zero =
chunk-size = hex-no-zero *HEX
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
footer = *entity-header
CRLE:斷行符號換行(\r\n)
例如:
Java代碼
... #很多前序
Transfer-Encoding: chunked #前序2個CRLE後開始報文
1 #chunk的大小,十六進位,然後加個CRLE
a #chunk資料,然後加個CRLE
4 #chunk的大小,十六進位,然後加個CRLE
test #chunk資料,可以不斷迴圈分塊輸出,然後加個CRLE
0 #chunk結束,0 + 2個CRLE
... #很多前序
Transfer-Encoding: chunked #前序2個CRLE後開始報文
1 #chunk的大小,十六進位,然後加個CRLE
a #chunk資料,然後加個CRLE
4 #chunk的大小,十六進位,然後加個CRLE
test #chunk資料,可以不斷迴圈分塊輸出,然後加個CRLE
0 #chunk結束,0 + 2個CRLE
在php裡使用ob_flush後,將自動加上Transfer-Encoding: chunked前序實現分塊輸出,但是在使用過程中經常達不到效果。不得不考慮一些問題
一、php的緩衝區
如果你的php是以apache模組運行,那請使用flush函數來通知php輸出。如果是以fastcgi模式運行則使用ob_flush通知php。這時gzip將失效,Chunked方式不支援每塊都獨立壓縮。只能全部輸出壓縮後,將壓縮包分塊輸出。為了保證相容性,先調用ob_flush,再調用flush。
二、瀏覽器的緩衝區
當遇到Transfer-Encoding: chunked前序後,瀏覽器做什麼反應,這個還是要看瀏覽器的實現了。在我的實驗中,firefox不管chunk資料大小都會做即時顯示,而ie8和chrome則需要一定長度後才顯示。所以,需要先輸出一定的大小後某些瀏覽器才有效果。
三、反向 Proxy伺服器
你使用的反向 Proxy伺服器支援http1.1協議嗎?它是怎麼處理後端是chunked方式的?proxy緩衝沒滿之前遇到chunked會按照後端來輸出嗎?
nginx的proxy功能只支援http1.0,並且它只有proxy buffer滿了才會輸出。
四、FastCGI緩衝
如果以FastCGI模式運行,可能Web Server有自己的fastcgi緩衝,等待緩衝滿了才輸出(nginx就這樣)。flush函數只能通知php的output緩衝輸出
Chunked transfer encoding
Hypertext Transfer Protocol -- HTTP/1.1 Chunked transfer encoding
深入理解ob_flush和flush的區別
http://www.bkjia.com/PHPjc/478424.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/478424.htmlTechArticleYahoo的前端最佳化實踐中有一條是先把html裡的head部分先輸出(Flush the Buffer Early),這樣做瀏覽器得到head後能先下載head裡的css/js檔案,而不用等...