[譯] 利用並行流漸進加載圖片

漸進式圖片渲染和 HTTP/2 多路複用技術已經問世一段時間,可是如今咱們將二者以新的方式結合從而發揮出更大的力量。利用 Cloudflare 的漸進式流,圖片加載能夠縮短一半時間,而瀏覽器能夠更快開始渲染頁面javascript

創建 HTTP/1.1 鏈接的服務器對向客戶端發送資源的順序沒有決定權;響應做爲沒法分割的總體,準確的按照瀏覽器端請求的順序來發送。HTTP/2 在這方面的改進在於增長了多路複用和優先,使服務器能夠決定選擇發送什麼數據和發送的時間。咱們利用這些新的 HTTP/2 功能,經過優先發送圖片數據中最重要的片斷,來提高漸進式圖片的感知加載速度。前端

這個功能與全部的主流瀏覽器兼容,而且不須要頁面標記作任何更改,很容易使用。參加 Beta 註冊,讓你的網站也能使用這一功能吧!java

什麼是漸進式圖片渲染?

普通的圖片加載嚴格按照從上到下的順序。若是瀏覽器只收到了圖片文件的一半,那麼它只會顯示圖片的上半部分。漸進式圖片的內容的排列不是按從上到下的順序,而是按細節級別從低到高的排序。即便瀏覽器只收到一部分數據,它也能夠顯示整張圖片,只是清晰度有損失。隨着更多數據接收成功,圖片會變的更清晰。android

這一功能對 JPEG 格式頗有用,由於顯示圖片預覽只需 10-15% 的數據,而當 50% 的數據加載以後,圖片看起來幾乎和整個文件都到達時同樣清晰了。漸進式 JPEG 圖片的數據和普通圖片一致,只是以一種更易用的方式排序,因此漸進式渲染並不增長文件的大小。這是能夠實現的,由於 JPEG 並不以像素形式存儲圖片。它用頻率係數來表明圖像,就像是一系列預約義的樣式,以任意順序混合都能能夠從新構建原圖想。JPEG 的內部構造十分有趣,你能夠從個人 permormance.now() 會議演講 瞭解更多。ios

最終結果是,圖像用了一半的時間就看起來幾乎與加載完畢沒區別了,並且不花錢。頁面視覺效果完整,並且能夠更快投入使用。剩下的圖像數據會很快到達,並在瀏覽者注意到任何缺省以前將圖像升級成清晰度完整的質量。git

HTTP/2 漸進式流

可是這有個問題。網站會有多於一張圖片(有時甚至是幾百張圖片)。當服務器以原始的方式一張一張傳輸圖片時,漸進式渲染幫不上什麼忙,由於總的來說圖片還是按順序加載:github

收到一半圖片的全部數據(但沒收到剩下一半圖片的任何數據)看起來不如收到全部圖片的一半數據。web

並且還有另一個問題:當瀏覽器未知圖像大小的時候,它用佔位符佈局,再在每張圖加載的時候重佈局。這會讓頁面在加載過程當中跳動,這樣作很唐突,讓用戶感到分神、厭煩。後端

咱們的漸進式流新功能對這種狀況大幅改進:咱們能夠一次性並行發送全部圖片。這樣瀏覽器能夠儘快的獲得全部圖片的尺寸信息,進而能夠無需等待大量數據就繪製全部圖片的預覽,並且大圖片也不會延遲樣式、腳本和其餘重要資源的加載。瀏覽器

並行流漸進式加載圖片的概念和 HTTP/2 自己同樣古老,可是它須要網絡服務器底層部件的特殊處理,因此目前爲止這一技術還沒被大規模應用。

當咱們改進 HTTP/2 優先級時,咱們意識到它也能夠被用來改進這一功能。圖片文件做爲總體時既不是高優先級也不是低優先級。每一個文件優先級不一樣,動態調整優先級給予咱們所需的行爲:

  • 含有圖片大小的圖片頭優先級極高,由於瀏覽器須要儘早知道大小來佈局頁面。圖片頭很小,並且早於其餘數據發送它沒有壞處。

Known image sizes make layout stable

  • 展現圖片預覽所需的最小量圖像數據具備中等優先級(咱們得爲儘早完成未加載圖片預留空間,可是也要爲腳本,字體和其餘資源留下足夠帶寬)。

Half of the data looks good enough

  • 剩下的圖像數據是低優先級的。瀏覽器能夠在可有可無的時候接受它來提升圖片質量,由於網頁已經徹底可用了。

  • 要了解在每一階段發送的準確數據量,你須要理解圖像文件的結構,可是讓網絡服務器來解析圖像響應,而且把基於格式的行爲在協議層級上硬編碼,看起來就會很怪異。而把這個問題看成優先級的動態改變來處理,咱們就能夠優雅的將底層網絡編碼與圖像格式信息分割開來。咱們能夠用 Worker 或者是線下的圖像處理工具來分析圖片,並指導服務器相應的改變 HTTP/2 優先級。

圖片並行流的好處在於它不增長任何開銷。咱們仍然發送一樣的數據,相同量的數據,咱們只是以一種更聰明的方式來發送它。這個技巧利用了現存網絡標準,因此在全部瀏覽器上都兼容。

瀑布圖

如下是從 WebPageTest 獲得的瀑布圖,展現了普通 HTTP/2 響應和漸進式流的比較。兩種狀況中的文件一致,傳輸的數據量一致,總的頁面加載時間也一致(在測量偏差內)。圖中,藍色片斷表示數據正在傳輸,綠色表示請求等待。

第一張圖展現了圖片依次加載的典型服務器行爲。圖看起來整齊,可是實際的頁面加載體驗並很差——最後一張圖直到將近最後纔開始加載。

第二張圖展現的是圖片並行加載。圖上藍色的垂直線表示的是早期的圖片頭髮送,以及以後漸進式渲染的幾個階段。你能夠看出全部圖片的數據的有用部分都到達的更早。你可能還會注意到有一張圖片是一次性發送的,而不是像其餘圖片同樣分批完成的。那是由於在 TCP/IP 鏈接創建之初咱們還不知道鏈接的真實速度,咱們只好犧牲一些優先處理的機會來最大化鏈接速度。

與其餘方法相比的指標

有一些其它的技術也用來更快的提供圖片預覽,好比低質量圖片佔位(LQIP),可是它們是有一些缺點的。他們爲佔位符增長了沒必要要的數據,並且一般會干擾瀏覽器的預加載掃描,而且延遲完整圖片的加載,由於將預覽更替到完整圖片依賴於 JavaScript。

  • 咱們的方法不增長請求,也不增長更多數據。頁面總加載時間不會延遲。
  • 咱們的方法不須要 JavaScript。它利用了瀏覽器原生的功能。
  • 咱們的方法不須要改變頁面標記,因此全站部署是安全並簡單的。

用戶體驗的改進能夠在例如 SpeedIndex,以及視覺上的完成時間等性能指標上表現出來。請注意,普通的圖片下載的過程看起來是線性的,可是漸進流使它能夠很快的進行到基本完成:

最大限度地利用漸進式渲染

避免讓 JavaScript 損壞效果。隱藏圖片直至 onload 事件才顯示(利用淡入等)的腳本會使漸進式渲染無效。漸進式渲染用傳統的 <img> 元素效果最好。

只有 JPEG 能夠嗎?

咱們的應用是不依賴於格式的,可是漸進流只對某些文件類型有用。好比說,對腳本或樣式應用它是不可行的:這些資源只有未渲染或所有渲染兩個狀態。

優先發送圖片頭(包括圖片大小)對全部格式都適用。

漸進式渲染的益處對 JPEG(全部瀏覽器都支持)和 JPEG 2000(Safari 支持)是得天獨厚的。GIF 和 PNG 有交錯模式,可是這些模式和糟糕的壓縮相伴生。WebP 根本不支持漸進式渲染。這就形成了這樣一種兩難:WebP 一般比同等質量的 JPEG 小 20% 到 30%,可是漸進式 JPEG 看起來 加載得快 50%。有些下一代圖像格式對漸進式渲染的支持優於 JPEG,比 WebP 壓縮更優,可是瀏覽器還不支持這些格式。同時大家能夠經過修改 Cloudflare 面板的 Polish 設置,在節省帶寬的 WebP 和可感知性能更好的漸進式 JPEG 之間選擇。

試驗用的自定義頭

咱們也支持自定義 HTTP 頭來進行試驗,來優化網站的其餘資源的流播。好比,你可讓咱們的服務器優先發送動畫 GIF 的第一幀,而剩餘的幀延後。或者你能夠在 HTML 文檔 <body> 加載前優先加載 <head> 標籤裏提到的資源。

自定義頭只能在 Worker 中設置。句法是用逗號隔開的包括優先級和併發選項的文件位置清單。優先級和併發選項與前一篇博客提到的整文件 cf-priority 頭同樣。

cf-priority-change: <offset in bytes>:<priority>/<concurrency>, ...
複製代碼

好比,對於漸進式 JPEG 咱們用這個(Worker 中的 JavaScript 片斷):

let headers = new Headers(response.headers);
headers.set("cf-priority", "30/0");
headers.set("cf-priority-change", "512:20/1, 15000:10/n");
return new Response(response.body, {headers});
複製代碼

它會告訴服務器,當一開始發送最早的 512 字節時用 30 做爲優先級。而後切換到優先級 20 以及必定程度的併發(/1),最後當發送文件的 15000 字節以後,切換到低優先級高併發(/n)把文件的剩餘部分發送完。

咱們試着分割 HTTP/2 幀來匹配標頭中的指定偏移量,從而儘快改變發送的優先級。可是,優先級並不保證不一樣流上的數據會被嚴格按照指示覆用,由於服務器只是在多路流同時須要發送數據時才應用優先級排序。若是某些請求從上游瀏覽器或緩存到達的更早,服務器可能會當即發送它們,而不是等待其餘請求。

試一試!

你能夠用咱們的 Polish 工具來把你的圖片轉化成漸進式 JPEG。加入 beta 來優雅地使用並行流。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索