媒體查詢與http請求

來源:互聯網
上載者:User

Jason Grigsby發表了篇文章,《CSS Media Query for Mobile is Fool’s Gold》對媒體查詢(media query)吐槽,大意是在行動裝置上使用媒體查詢會造成很多資源的浪費——瀏覽器請求到很多用不到的圖片等資源,然後寫了一些測試案例測試一些可用方法。然後Tim Kadlec寫了篇《Media Query & Asset Downloading Results》,用js自動化的測試了Jason Grigsby的用例。

本文主要整理自Tim的這篇文章。我們來看看到底會不會浪費資源,並尋找下最優的方案。

直接看結果吧~~

測試一:img標籤

運行測試

本測試嘗試通過對img標籤的父級元素使用display:none來隱藏圖片。HTML和CSS代碼如下:

123
<div id="test1"><img src="images/test1.png" alt="" /></div>
123
@media all and (max-width: 600px) {#test1 { display:none; }}

測試結果

如果有一種應該100%避免的隱藏圖片的方法,那就是display:none。它基本上是沒有用的。貌似Opera Mobile和Opera mini不會下載圖片,而其它瀏覽器都會下載。Opera可以比較好的控制資源的下載,對於使用者看不到的內容,它不會預先下載。

瀏覽器 請求圖片
Android 2.1+ 請求
Blackberry (6.0+) 請求
Chrome (4.1)+ 請求
Chrome Mobile 請求
Fennec (10.0+) 請求
Firefox (3.6+) 請求
IE 請求
iOS (4.26+) 請求
Kindle (3.0) 請求
Opera (11.6+) 請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
RockMelt 請求
Safari (4+) 請求

結論

很簡單:不要這樣用。

測試二:背景圖片display:none

運行測試

在本例中,div被設定了background-image。如果螢幕寬度小於600px,div就被設定為display:none。HTML和CSS代碼如下:

1
<div id="test2"></div>
12345678
#test2 {background-image:url('images/test2.png');width:200px;height:75px;}@media all and (max-width: 600px) {#test2 {display:none;}}

測試結果

結果和測試一一樣:除了Opera mini和Opera Mobile和Firefox,所有瀏覽器都會下載圖片。

瀏覽器 請求圖片
Android 2.1+ 請求
Blackberry (6.0+) 請求
Chrome (4.1)+ 請求
Chrome Mobile 請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 請求
iOS (4.26+) 請求
Kindle (3.0) 請求
Opera (11.6+) 請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
RockMelt 請求
Safari (4+) 請求
Silk 請求

結論

同樣:不要這樣做。不過,像後面其它的測試,有其它的方法可以隱藏背景圖片同時避免多餘請求。

測試三:背景圖片的父級元素被設定為display:none

運行測試

本測試中,對一個div標籤設定背景圖片,然後對其父元素(也是個div)在瀏覽器寬度小於600px時設定display:none。HTML和CSS代碼如下:

123
<div id="test3"><div></div></div>
12345678910
#test3 div {background-image:url('images/test3.png');width:200px;height:75px;}@media all and (max-width: 600px) {#test3 {display:none;}}

測試結果

表面上,這個測試貌似和測試二沒太明顯的區別,但是結論是這個方法是比較靠譜的。。。

瀏覽器 請求圖片
Android 2.1+ 不請求
Blackberry (6.0+) 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 不請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari (4+) 不請求

結論

這個方法不錯。除了不太成熟的Fennec,其它瀏覽器都不請求不必要顯示的圖片。

測試四:背景圖片層疊

運行測試

本測試中,一個div被設定了背景圖片。如果瀏覽器寬度小於600px,該div會被給到另一個背景圖片。該測試用來檢測是否兩個圖片都會被請求,還是只請求需要的。HTML和CSS代碼如下:

1
<div id="test4"></div>
12345678910
#test4 {background-image:url('images/test4-desktop.png');width:200px;height:75px;}@media all and (max-width: 600px) {#test4 {background-image:url('images/test4-mobile.png');}}

測試結果

比設定display:none好一些,這種方法的結果有點兒亂:

瀏覽器 同時請求
Android 2.1-3.0? 請求
Android 4.0 不請求
Blackberry 6.0 請求
Blackberry 7.0 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari 4.0 請求
Safari 5.0+ 不請求

結論

我會避免使用這種方法。儘管環境在改善,但是在Android市場中佔主導地位的Android 2.x版本依然會像Fennec和Kindle一樣同時下載兩個圖片。三者中,尤其因為Android(的片段化),我會推薦尋找別的方案。

測試五:大背景圖片被設定min-width

運行測試

本測試中,一個div元素在瀏覽器寬度大於601px時被設定一個背景圖片,然後在瀏覽器寬度小於600px時被設定為另一個背景圖片。HTML和CSS代碼如下:

1
<div id="test5"></div>
1234567891011121314
@media all and (min-width: 601px) {#test5 {background-image:url('images/test5-desktop.png');width:200px;height:75px;}}@media all and (max-width: 600px) {#test5 {background-image:url('images/test5-mobile.png');width:200px;height:75px;}}

測試結果

這種方案好一點兒:

瀏覽器 同時請求
Android 2.1+ 不請求
Blackberry (6.0+) 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 不請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari (4+) 不請求

結論

這次更多的瀏覽器一起玩了。但是,Fennec一如既往得不能自已。Android 2.x比較怪異。它會同時請求兩個圖片——但只有在螢幕寬度大於600px匹配到min-width時才這樣。這種行為貌似在Android 3.0版本中被改進了。這是件詭異的事情,我很好奇它為什麼會這樣。 其實,有個好訊息。Jason Grigsby 說他的對本例的測試結果和我的不太一樣。所以我又在一些Android 2.x機器上跑了一下這個測試。結論是,我最初的測試結果不太正確,Android 2.x表現很好,我最初測試的那個平台有問題。這不僅僅對於開發人員來說是個好訊息,對我本人來說更是恢複了對人類的信心。。。。。。。

但是這依然不夠,你將需要對IE8以下瀏覽器提供替代方案,那些版本的瀏覽器不支援media query,所以沒有圖片會被顯示。當然,這個問題可以用條件注釋來簡單的相容一下。

測試六:背景圖片display:none(max-device-width)

運行測試

本測試和測試二類似,但是使用了max-device-width來替代max-width。HTML和CSS代碼如下:

1
<div id="test6"></div>
12345678910
#test6 {background-image:url('images/test6.png');width:200px;height:75px;}@media all and (max-device-width: 600px) {#test6 {display:none;}}

結論

好吧,不用浪費時間了,這個測試結果和測試二的基本一致。

測試七:層疊覆蓋高解析度

運行測試

最後一個測試,是為了new ipad提供的,它使用了retina螢幕,這樣它就要使用更高解析度的圖片了。

本例中,一個div被給到一個背景圖片。然後,通過使用min-device-pixel-ratio屬性,如果比例大於1.5,一個新的背景圖片將會被用到。

HTML和CSS代碼如下:

1
<div id="test7"></div>
123456789101112131415
#test7 {background-image:url('images/test7-lowres.png');width:200px;height:75px;}@media only screen and (-webkit-min-device-pixel-ratio: 1.5),only screen and (-moz-min-device-pixel-ratio: 1.5),only screen and (-o-min-device-pixel-ratio: 3/2),only screen and (min-device-pixel-ratio: 1.5) {#test7 {background-image:url('images/test7-highres.png');width:200px;height:75px;}}

測試結果

瀏覽器 同時請求
Android 2.1-3.0? 請求
Android 4.0 不請求
Blackberry 6.0 不請求
Blackberry 7.0 不請求
Chrome (16+) 不請求
Chrome Mobile 不請求
Fennec (10.0+) 不請求
Firefox (3.6+) 不請求
IE 9+ 不請求
iOS (4.26+) 不請求
Kindle (3.0) 不請求
Opera (11.6+) 不請求
Opera Mini (6.5+) 不請求
Opera Mobile (11.5) 不請求
Safari 4.0+ 不請求

結論

為了安全,這個方案可以多測試一些。看起來這種方法在絕大多數情況下是可用的。但是不幸的是,貌似Android 2.x會同時下載兩個圖片如果裝置像素比大於或等於1.5時(或者你在media query中設定的別的任何值)。所以,在本例中,如果你使用了一個高解析度的Android 2.x的裝置,會比較苦逼。。。

好訊息是,到目前位置,我還沒聽說有那一款Android 2.x的裝置的螢幕比例超過1.5.所以如果你的項目面向使用retina螢幕的ios裝置,你可以將min-device-pixel-ratio設定到2或者更高,這樣會比較安全一點兒。。。

推薦
  • 如果你要隱藏一張內容圖片,display:none是無效的,所以我推薦使用javascript方案或者伺服器端實現;
  • 如果你要隱藏一張背景圖片,最好的方法是隱藏其父級元素。如果你不方便這樣做,那就用一個層疊樣式覆蓋掉它吧(就像上面的第五個方案),然後將設定background-image:none;
  • 如果你要切換多張圖片,就把他們全部用media query定義吧。
關於響應式設計的思考

媒體查詢現在最大的用處就是響應式設計了,神飛翻譯這篇文章也是因為最近在思考響應式設計的效率問題。通過這些測試結果,我們在實現響應式設計的網站時,最好先處理行動裝置,然後再向高解析度裝置升級。然後使用圖片等外部資源的選取器,一定要寫到媒體查詢中去。

反饋

如果你覺得這些測試結果有任何錯誤的地方,歡迎在評論中提出,然後這些測試案例Tim都在GitHub上開源了,感興趣的話可以fork下。。。



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.