距上一次我寫這類的文章已經近一年了,但經過一種「魔幻」的圖像格式來解決世界飢餓問題 和/或 響應式圖片問題(無論哪一個先實現)的夢想一直在我腦海中。幾周前,我開始思考是否存在一種圖像格式可以解決art direction和分辨率切換問題。css
就如何作到這一點我有不少想法,因而我建立了一個原型來證實它的可行性。該原型如今已經可用了,而且能夠進行修改更新。在本文中,我會闡釋該原型作了什麼,它不能作什麼,它是如何工做的, 還有它相對與標記解決方案(markup solutions)的優缺點。我也盡力用通俗的語言闡釋響應式圖片格式的概念,讓它更具體和淺顯易懂。git
不,我不會這麼作!發自心裏的!我最好的朋友中有些就是使用標記解決方案的。github
我加入響應式圖片社區已經有段時間了, 在那裏作原型、促進和展現標記解決方案。如今的標記解決方案(picture
標籤 和srcset
屬性)很是好而且重要的響應式圖像用法案例都採用了它。 對我來講, 我傾向於投票支持在全部瀏覽器上開始推廣picture
標籤和srcset
屬性 (即它的分辨率切換版本)。web
不過採用基於標記的解決方案存在一些缺陷。下面就是談到響應式圖片的標記解決方案時我常聽到的對它的批評。算法
標記解決方案須要經過詳細的定義,由於他們必須列舉全部資源。當涉及到art direction時, 他們還必須列出全部的斷點,這又增長了冗餘。segmentfault
標記解決方案在展現面向方向的頁面時候須要在標記內保存斷點。它混合了表現和內容,意味着佈局改變了標記也要跟着改變。瀏覽器
關於如何解決它的討論已經進行了不少次。特別是媒體查詢的出現,不過它不是必須的,特別是當它能夠被定義和實現的時候。緩存
這一般由開發人員提出。考慮性能的問題,基於標記的解決方案是基於視口大小, 而不是圖片的大小。 當瀏覽器開始抓取圖像的時候,佈局中圖像的大小是未知的,因此不能依靠它來肯定要抓取的資源。服務器
這意味着開發者可能須要在服務端存放一些視口表和圖像大小表,或者記在腦子裏,使得在特定的視口和佈局下顯示尺寸理想的圖片。ide
大多數狀況下,額外增長的步驟能夠解決這個問題, 不過當一個單一組件以不一樣的大小尺寸被用於多個頁面時,它也會變得複雜起來。
好,這一點是我聽到最多的。
從性能角度來看, 全部爲不一樣屏幕尺寸和分辨率提供單一資源的解決方案都須要從新下載整個圖像或者更換到高分辨率版本。由於大多數的圖像數據極可能已經在瀏覽器內存中存儲,從新下載一次太傷用戶的心了(中國用戶表示流量燒不起啊~)。
上面講到的東西讓我感慨(再一次),若是咱們已經有了一個基於文件格式的解決方案,那麼這個世界該多麼的美好啊。
基於文件格式的解決方案有以下好處:
負載放在了圖像編碼器端。標記依然和如今的保持一致:一個標籤攜帶一個資源。
經過這種響應性圖片解決方案將網站自動轉化會更容易些,由於自動化層只關心圖像自己,而不是頁面標記和佈局。
改變圖像佈局(例如視口大小的改變)只會下載當前圖像夫人不一樣版本或是它的高分辨率的版本, 而不會從新下載已加載過的圖像。
Web開發者再也不須要維護一個圖像的多個版本,儘管他們可能由於內容排版緣由須要保留該圖片的一個非響應式版本。
我嘗試經過一種基於文件格式的簡單解決方案來緩解web開發人員的繁重工做,避免沒用的圖片被下載 (即便在狀況改變的時候),同時保證預加載能正常工做。
漸進式JPEG可以實現分辨率切換,但它的要求十分嚴格。 它嚴格限制了圖像的最低質量,在我看來,它太流線化(data-heavy)了。另外,分辨率的範圍是受限的,也沒有對更好的編碼提供足夠的控制權。因此說,漸進式JPEGF根本不能解決art direction問題。
咱們討論的是響應式圖像容器, 內部包含的層能夠是WebP或JPEG-XR或其餘將來的格式 。它使用調整大小和裁剪操做覆蓋了分辨率切換和art direction用例。
編碼器(例如瀏覽器)會只下載它須要的層來顯示合適的圖像。每一個層的質量都比它以前層高, 若是須要顯示合適的尺寸或者更高的分辨率就把相應的數據傳給編碼器。
很明顯它支持分辨率切換,若是要支持art direction也能夠經過在當前層定位上一層來給予它合適的尺寸。
咱們來看一下案例。
下面是一張討論art direction例子時經常使用的圖片:
它最小的時候看起來應該是這樣:
這只是原圖通過裁剪的一個版本,沒什麼特別的。
下面,在它(圖片裁剪版本)上面的一層:
你會發現灰色塊區域外正常顯示, 實際上灰色塊區域是上一層(圖片裁剪版本)的等價層,而且包含了層與層之間的區別。
下面是第三個圖片,最後(最上面)一層:
蘋果手機的一個高品質圖片
下面是它的第一層,顯著壓縮版本:
第二層展現中等大小圖片版本和上一層(即第一層)圖片「拉伸」版本的不一樣部分:
第三層展現了原始圖像和通過「拉伸」的上一層的不一樣部分:
若是你想知道更多細節,能夠訪問repository。
我看過的圖像旋轉和重定位的例子都須要art direction, 一般是根據視口的尺寸,在圖片的周圍添加一個標識。
這種狀況下使用CSS可能更好。CSS transforms能夠處理旋轉, 而CSS定位和Media-Specific背景圖片結合,也能解決其餘的問題。
這就是讓人感受棘手的地方。由於必須建立一個特殊的抓取機制獲取這種特殊的圖像類型。我不能打包票說我已經解決了這個問題,不過我很是瞭解它的工做原理。
我推薦依賴HTTP ranges的機制,相似與<video>
元素的獲取。
具體來講:
1.相對全部圖像,體積相對較小,大小固定的;(例如8KB)
2.由做者指定的。(例如一個先進的屬性的值);
3.一些探測
4.基於清單(稍後咱們會講到);
瀏覽器在檢測到的同時能夠抓取到這個初始範圍,就像如今瀏覽器抓取資源同樣,甚至能夠比如今更快,由於範圍已經預加載的狀況下,資源(例如css和js)的請求數就下降了。
一旦瀏覽器下載到圖像的初始範圍,它包含文件的外邊框 。也就是說瀏覽器一旦計算完頁面的佈局,它會知道那些字節範圍是須要的,用來正確顯示圖片。
瀏覽器會自動判斷當前顯示的圖層是否合適,在後續層更合適的狀況下,它會主動獲取後續層(即更高分辨率),甚至在它知道合適的尺寸以前就已經獲取了。
一旦瀏覽器頁面佈局渲染完畢,它會抓取全部須要的圖像層。
上面的機制會致使HTTP請求數量的增長,在HTTP/1.1下面還會致使些許的延遲。
這個機制能夠經過定義清單文件來優化,清單文件描述了圖像資源的字節範圍。添加清單的想法由Cyril Concolato 在去年的W3C技術全體/顧問委員會會議中提出 ,這頗有意義,借鑑了視頻流的經驗。它避免了瀏覽器娶到一個不肯定的初始範圍(至少在它下載了一次清單文件後)。
添加一個清單能夠避免在佈局完成後的額外的請求,而且這有助於阻止請求(使用探測器),甚至在佈局完成以前。
建立清單文件能夠很容易的由開發工具或服務端完成,因此開發者們就不須要手動處理這些細節了。
理論上,咱們能夠解決這個問題。經過抓取整個圖像,而後一旦瀏覽器得到全部須要的數據就馬上重置鏈接,但這極可能會引入嚴重的性能問題。
在瀏覽器會話期間重置TCP鏈接有如下問題:
一點也不。這裏的原型展現了經過這樣的一個容器如何實現大多數的響應式圖片案例。
讓這個解決方案成爲業界共識,在可交互方面對它進行詳細的設計和實現會是一個長期的過程。在HTTP/1.1網站下的性能影響和解碼速度方便仍須要更多的探索。
我相信它會成爲將來簡化響應式圖片的一種方式,但我不以爲咱們應該乾等着那個理想的方案出現。
若是你一開始就跳到了這,不要緊。這篇文章的確很長。
綜上所述,我展現了(連帶一個模型)一種響應式圖像格式的工做原理和它可以解決的大多數響應式圖片案例。 在經過添加一些比特標記來使它成爲一個可行性方案方面,我也闡述了許多細節。
我認爲這將成爲一個長期的解決方案,由於在它變得實用以前,一些關鍵問題須要解決。在我看來,主要的問題在於解碼性能,緊隨其後的則是HTTP/1.1的下載性能影響。
繼續探索這個方向是值得的,可是如今咱們不要坐以待斃。響應式圖片在瀏覽器、現實生活中的解決方案在(兩年前的)今天就應該出現了,而不是二年後的今天。
原文 Responsive Image Container: A Way Forward For Responsive Images? 做者 Yoav Weiss