最近一項研究表明,80%的網民對移動端的瀏覽體驗感到失望,同時當體驗提升時,他們會在智慧手機上花費更多的時間。
這不奇怪,因為64%的智慧手機使用者希望網站可以在4秒內載入完畢,但一半的網站花費了二倍以上的時間,達到了9秒。這篇文章會闡述一些可以使你的網站在移動端跑得更快的技術。
移動端使用者的下載速度
讓我們來研究下究竟是什麼影響了智慧手機上的網頁載入速度。
最明顯的原因是智慧機的網速。最佳情況下,移動端使用者使用3g與4g上網。在美國,57%的使用者使用3g上網,27%的使用者使用4g。在加拿大,4g使用者更少。而在英國,4g還是新鮮事物。Pcworld的研究表明,在美國,3g平均下載速度為2mbps,4g則為6.2mbps。ofcom的研究顯示,在英國3g的下載速度為2.1mbps。北美和歐洲以外的連線速度一般較慢。1mpbs可換算為122kb每秒,或者0.12mb每秒,因此以上的資料可以轉換如下:
- 244 KB/s 3G使用者平均網速值 (0.24 MB/s)
- 756 KB/s 4G使用者平均網速值(0.76 MB/s)
如果把上述值乘以移動使用者等待時間4秒,這意味著網站對於3g使用者來說最大為1mb,而4g使用者為3mb。
然而下載速度並不是瓶頸,網路延遲及智慧機的記憶體與cpu才是瓶頸。即使手機可以在4秒內下載完1mb,頁面也要花費更長的時間去載入,因為手機需要接收並解析程式碼與圖片。
在桌面端,下載檔案只佔顯示網站時間的20%,其餘時間花費在解析http請求,獲取樣式表,指令碼檔案及圖片上。由於移動端的cpu,記憶體與快取跟桌面端完全無法相提並論,這些在手機上會花費更長的時間。
怎樣減少載入時間
構建一個快速的網站,就是一個做出艱難決定與砍掉非核心體驗的過程。如果某一項需求價值不大,去掉之。這個原則適用於所有開發階段,尤其是規劃和編碼時。
- 減少依賴檔案 : 更少的檔案意味著更少的http請求與更快的載入時間
- 降低圖片大小: 適應與調整高解析度圖片,在額外的下載時間中佔居榜首,佔用了寶貴的記憶體與處理資源。
- 減輕客戶端負擔: 最佳實踐是重新思考你的javascript,並使之降低到最小尺寸
怎樣減少依賴檔案
如果你想為移動端使用者隱藏圖片,display:none
與visibility:hidden
是不能阻止檔案下載的。測試下面的程式碼:
1 2 3 4 5 6 7 |
<div style="display:none;"> <img src="logo-none.png" /> </div> <div style="visibility:hidden;"> <img src="logo-hidden.png" /> </div> |
你可以觀察下面的瀑布圖,圖片容器設定display: none
或visibility: hidden
後仍然會被下載。
替代方案是利用css載入背景圖片,之後利用media query媒體查詢來通過條件隱藏圖片。這個技術最初被Jason grigsby測試過,之後被tim kandlec進一步擴充。亞馬遜獨立的移動端頁面使用了此種技術,根據裝置來條件載入特定的圖片。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<meta name="viewport" content="width=device-width"> <style> @media (max-width:600px) { .image { display:none; } } @media (min-width:601px) { .image { background-image: url(image1.jpg); } } </style> <div class="image"></div> |
你可以看到圖片不載入的瀑布圖:
保持最小數量的外聯樣式表
如果你已經根據斷點來載入分開的樣式表,你需要仔細思考這樣的做法了。我們測試了以下的程式碼:
1 2 3 4 |
<link href="extra-small.css" rel="stylesheet" media="screen and (max-width: 390px)" /> <link href="small.css" rel="stylesheet" media="screen and (min-width: 391px) and (max-width: 500px)" /> <link href="medium.css" rel="stylesheet" media="screen and (min-width: 501px) and (max-width: 767px)" /> <link href="large.css" rel="stylesheet" media="screen and (min-width: 768px)" /> |
你可以看到這四個樣式表在豎屏下(portrait mode)都被載入了.
因此無論如何這些樣式表都會被夾在,你需要把這些檔案合併在一個檔案裡,減少http請求。另一種方法,你可以通過後端處理,通過判斷裝置來自動插入樣式表。 (這種方式在wordpress.com的響應式網站中使用過)。
另一種方案可以使用內部樣式。亞馬遜獨立的移動產品頁面有一個6 KB大小的外部樣式表,連同一些內部樣式。這隻需要通過一個額外的HTTP請求來下載所有的頁面樣式。亞馬遜的桌面版本並不是很高效,帶有9個外部樣式表,總共40 KB。
利用CSS3代替圖片
圓角,陰影,漸變填充等,這些樣式不需要使用圖片,可以減少http請求,加快載入時間。
Css3可以減少http請求,但增加了處理負荷。我們建立了一系列的html檔案,每個檔案包含一個基本的css3特性。參考下面的圖表,你可以發現css3帶來的處理時間很小,但不能不考慮。特別注意box-shadow
對處理時間的影響最大。
DATAURI來代替圖片與WEB字型檔案
Data uri方案可以不使用任何額外資源就可以向html及css中插入內容。這個技術可以在web頁面中插入任何內容,通常被用於插入圖片及web字型檔案。這個技術最大的好處是可以減少http請求。
Data uri使用很簡單,你可以按照下面的格式,使用base64編碼過的資料直接插入html與css中代替圖片檔案。
1 |
data:[MIME-type][;charset=encoding][;base64],[data] |
舉個例子,下面的小圖示就是用data uri建立的:
程式碼在這:
1 |
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAACI0lEQVQoz2P48/bFX1Tw58vn3/dv/rp56dfD238+vocIfl029UOC3dsgS4Y/nz4gq/794sm3VbO+zmr/MqX+S1/l597yb2vn/rpx6VN14od4+3cBRgx/vn9F1vB9/+bPPeVfJlZ/6S793JwDVPcxL/BjQeiHFNf3cbbvgw0Z4JZCwM/Lpz81Zn2qS/1Ul/apOv5jUfiHbP8PSc7vY23fh5m+C9JjALoVzQ8/zx7+0lH4IcvnQ4bXhwzPD8muINXhZu+C9N/56zB8mdr49/cfdH9/fPdj36bPLbkgpYH670KNQaoDdV47aTK8j7H+tmXpX6zg95+f545+7ix656PxzlP5jaf2c2M1hvcRZu8jzb4umfrn6xfs2v78+XFkx9sI2+fass8N1Rje+eu/dtR+YaD0Jj70296df3/+xKrr593bL91tnmnJMbwwVXtuoAbU+kxD5pmu4pvYkK9rVvz58B5Tz7dd257pKDAAlT43giEDFZA2NclXAe5fN60DOgZFx48fb6ICGRCqIchY/bmhKkibivinOdPRLPnQ1cwAUqGrCFQBVIes7ZmmzEtni9+vXiFr+DR9IsMzHfnXIV5vs5OeqUs/05B+rqcIdBhQ81M1yRfW+r+fPUHRMLWfAejir+tWATlf1ix/HR34wlL3ub7Scx2F56Yan6ZPQnPS+6oihlc+Tr/fv4OG+Levv+7d+X700PeDe3/dv4um+tfjhy9drQDa2DKqOJhVKgAAAABJRU5ErkJggg==" /> |
Wordpress.com的響應式網站使用這個技術插入了圖片及字型。波士頓環球報的響應式網站也使用了這個技術,他們的網站在智慧手機上,四秒內就載入完畢了。
使用這項技術,從此不用為外部圖片及字型檔案勞心費神。也需要測試與比較是否值得應用這項技術來代替傳統方式。
可縮放向量圖形(SVG)而不是圖片
就像data URIs,可縮放向量圖形(SVG)可以被嵌入到一個頁面來減少HTTP請求數。例如,下面的圖片是一個內聯SVG:
這是程式碼:
1 2 3 4 5 6 7 8 9 10 |
<svg version="1.1" id="drop" x="0px" y="0px" width="17.812px" height="28.664px" viewBox="296.641 381.688 17.812 28.664" enable-background="new 296.641 381.688 17.812 28.664" xml:space="preserve"> <path fill="#EE1C4E" d="M314.428,401.082c-0.443-5.489-5.146-9.522-7 .52-14.186c-0.816-1.597-1.352-5.208-1.352-5.208 s-0.555,3.792-1.388 ,5.425c-2.233,4.371-7.127,8.999-7.507,14.047c-0.36,4.794,4.101,9.191 ,8.896,9.191 C310.49,410.354,314.816,405.941,314.428,401.082z"/> </svg> |
SVG檔案可以通過一個向量圖形編輯器,如Adobe Illustrator建立。一旦建立,在文字編輯器中開啟檔案並把其程式碼拷貝出來(減去任何不必要的資料)。
上面的程式碼在HTML檔案中會生效,,但不會在樣式表中生效。若在一個樣式表中嵌入SVG檔案,需要先將它轉換為一個資料URI。如果這樣做,我們需要從編輯器中(一定要包括後設資料)拷貝出,用base64編碼,然後使用以下格式嵌入樣式表:
1 |
data:image/svg+xml[;base64],[data] |
這是程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0i MS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx 1c3RyYXRvciAxNS4xLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOi A2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL 0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8x LjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzE iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Im h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3a WR0aD0iMTcuODEycHgiIGhlaWdodD0iMjguNjY0cHgiIHZpZXdCb3g9IjI5Ni42NDEg MzgxLjY4OCAxNy44MTIgMjguNjY0Ig0KCSBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDI 5Ni42NDEgMzgxLjY4OCAxNy44MTIgMjguNjY0IiB4bWw6c3BhY2U9InByZXNlcnZlIj 4NCjxwYXRoIGZpbGw9IiNFRTFDNEUiIGQ9Ik0zMTQuNDI4LDQwMS4wODJjLTAuNDQzL TUuNDg5LTUuMTQ2LTkuNTIyLTcuNTItMTQuMTg2Yy0wLjgxNi0xLjU5Ny0xLjM1Mi01 LjIwOC0xLjM1Mi01LjIwOA0KCXMtMC41NTUsMy43OTItMS4zODgsNS40MjVjLTIuMjM zLDQuMzcxLTcuMTI3LDguOTk5LTcuNTA3LDE0LjA0N2MtMC4zNiw0Ljc5NCw0LjEwMS w5LjE5MSw4Ljg5Niw5LjE5MQ0KCUMzMTAuNDksNDEwLjM1NCwzMTQuODE2LDQwNS45N DEsMzE0LjQyOCw0MDEuMDgyeiIvPg0KPC9zdmc+DQo=); |
Sprites圖
Sprites(雪碧圖)技術可以把經常使用的圖片合成為一張圖片,從而減少http請求。比如當你將四張圖片合成到一個sprite中後,http請求從4減少到1.需要顯示的圖片利用background-position
屬性來控制。
字型圖示
字型圖示是利用字型檔案來包含符號和圖表(如Wingdings或Webdings 都是某種圖示字型),可以用來代替載入一個影象檔案。例如,下面的圖示不是一個影象,而是Wingdings字型中的“h”
字元:
Wingdings和Webdings有點過氣了,現在有其他更專業的Web字型可用的,可以通過font-face
載入。
單獨的Web字型,對於所有圖示來講,HTTP請求的數量可以減少到一個。如果Web字型使用資料URI(如上所述)嵌入頁面,HTTP請求可以減少到零。這正是WordPress.com使用的技術。這是他們樣式表中嵌入的web 字型:
WordPress.com訪問所有這些圖示,不會有任何額外的HTTP請求,因為圖示通過資料URI,以Web字型的方式嵌入到WordPress的樣式表中。
同時,字型圖示可以使用CSS3關鍵幀動畫(這很有用,比如“載入”圖示(小菊花))。 主要的缺點是,字型圖示做成的CSS sprites只能是某個純色。亞馬遜的css雪碧圖包括彩色圖示,因此它不能使用這種技術。
如IcoMoon之類的工具可以很方便的建立一個自定義Web字型。所需要的只是每個圖示的SVG檔案。
避免內聯iframe
每一個內聯框架(iframe)都會生成一個HTTP請求,這是在iframe內沒有另外依賴資源的情況下。這是我們做一個快速測試,比較一個iframe只含有文字。
包含一個iframe增加了將近0.2s的載入時間。為了保證web站點載入迅速,最好不要使用iframe。
移動先行
移動先行也適用於前端開發。
編碼時以移動使用者作為第一考慮,然後為平板電腦和桌面逐步增強,減少不必要的依賴。另外一種方式為桌面端優先,重型元件預設載入,然後為小螢幕隱藏這些元件(稱為“優雅降級”)。
下面例子為桌面端優先的編碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<style> .image { background-image: url(image1.jpg); } @media (max-width:390px) { .image { display: none; } } </style> <div class="image"></div> |
在上面的程式碼中,預設是顯示影象,然後在移動裝置上通過媒體查詢隱藏了圖片。
下面的例子為移動端優先的編碼:
1 2 3 4 5 6 7 8 9 |
<style> @media (min-width:391px) { .image { background-image: url(image1.jpg); } } </style> <div class="image"></div> |
預設情況下,圖片不顯示,之後使用媒體查詢對更大的螢幕進行漸進增強。
拆分到多個頁面(單獨的移動網站)
保持你的核心內容在頁面上,之後提供到次要內容的連結到次要內容。這將減少HTML的載入負擔,同時防止相關的資源被下載。
亞馬遜的移動產品頁面有通用的產品資訊,同時提供連結到“使用者評論”、“描述和細節”和“新&
使用提供。
這就減少了三張圖片的HTTP請求,且HTML的大小減少45 KB。
保持最少重定向(單獨的移動網站)
亞馬遜有一個重定向,來引導遊客到單獨的移動頁面,這帶來了0.4秒的延遲。與之相比,戴爾的網站有兩個重定向,帶來了1.2秒延遲。
如何縮小圖片尺寸
響應式圖片
響應式圖片的思路是讓訪客影象只下載那些最適合他們的裝置的圖片,對於智慧手機,使用低解析度影象,可以快速下載和渲染。
亞馬遜的獨立的移動產品頁面使用響應式影象技術,利用媒體查詢分配一個特定的背景影象到一個div。這是亞馬遜的程式碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
<!-- // This meta viewport is inserted for iPhones // --> <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0"> <!-- // This meta viewport is inserted for the Nexus S // --> <meta name="viewport" content="width=device-width"> <style> @media (max-width:390px) { #image-container { max-width: 109px; } .image { background-image: url(image1.jpg); } } @media (max-width:390px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image2.jpg); } } @media (max-width:390px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image3.jpg); } } @media (min-width:391px) and (max-width:500px) { #image-container { max-width: 121px; } .image { background-image: url(image4.jpg); } } @media (min-width:391px) and (max-width:500px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image5.jpg); } } @media (min-width:391px) and (max-width:500px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image6.jpg); } } @media (min-width: 501px) and (max-width: 767px) { #image-container { max-width: 182px; } .image { background-image: url(image5.jpg); } } @media (min-width: 501px) and (max-width: 767px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image7.jpg); } } @media (min-width: 501px) and (max-width: 767px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image8.jpg); } } @media (min-width:768px) { #image-container { max-width: 303px; } .image { background-image: url(image8.jpg); } } @media (min-width:768px) and (-webkit-min-device-pixel-ratio:1.5) { .image { background-image: url(image8.jpg); } } @media (min-width:768px) and (-webkit-min-device-pixel-ratio:2) { .image { background-image: url(image8.jpg); } } </style> <div id="image-container"> <div class="image"> <img src="image1.jpg" /> </div> </div> |
儘管亞馬遜在內部樣式中有八個產品圖片,在豎屏模式下的iPhone 4或Nexus S只有兩個被下載。
《波士頓環球報》的響應式網站,採用了利用不同的data-fullsrc
來載入圖片的響應式影象技術。這是一個html標記,和一個伺服器端JavaScript重定向規則的組合:
1 |
<img alt="" src="mobile-size.r.jpg" data-fullsrc="desktop-size.jpg" /> |
src
是手機上使用的影象,確保網站預設為尺寸較小的版本(移動先行),而data-fullsrc
是全尺寸的影象。JavaScript用來檢測裝置的螢幕大小,之後寫入cookie
。對於大螢幕,JavaScript利用data-fullsrc
上的高解析度影象替換較小的圖片。伺服器也使用Apache重寫規則,來在影象檔案的名稱中檢查.r.
(mobile用的圖片帶有.r.
),同時顯示一個備用GIF,而不會使用較小的移動影象(從而防止手機大小的影象被下載到桌面)。
微軟的響應式網站使用的斯科特·傑爾的Picturefill技術:
1 2 3 4 5 6 7 8 |
<div data-picture data-alt="Alternate text here"> <div data-src="image1.png"></div> <div data-src="image2.png" data-media="(min-device-pixel-ratio: 2.0)"></div> <div data-src="image3.png" data-media="(max-width: 539px)"></div> <div data-src="image4.png" data-media="(max-width: 539px) and (min-device-pixel-ratio: 2.0)"></div> <noscript><img src="image1.png" alt="Alternate text here" /></noscript> </div> |
注意:上面的程式碼片段中, data-picture= " "
應該是 data-picture
,沒有= ” “。(=字元是smashing magazine的所見即所得編輯器自動插入的)。利用這種技術,JavaScript掃描頁面的程式碼,發現包含data-picture
屬性的div
。然後根據data-media
屬性插入一個新的img
標籤。
這些響應式影象技術的主要好處有:
- 小螢幕下載低解析度的影象,而大螢幕下載高解析度影象;
- 只下載所需的圖片,而不需要的圖片不在後臺載入。
有各種各樣的其他技術實現響應式影象。你可以檢視這些資源,瞭解更多的細節:
如何減少客戶端處理
讓JAVASCRIPT降到最低
星巴克的響應式網站在chrome下禁用javascript後,桌面端良好的網路環境下花費了3.53秒載入完畢,而啟用javascript後,花費了4.73秒,增加了34%。Javascript對載入時間的影響,在移動端較小的記憶體,cpu及快取下會表現得更明顯。通常,我們要重新思考javascript的使用,並保持其在最小尺寸。
一個很好的例子是BBC移動網站的JavaScript。網站不使用外部JavaScript檔案——都是內聯。內聯指令碼僅限於幾行,沒有顯著影響記憶體,HTML檔案和所有內聯JavaScript花費0.78秒載入完畢。就像BBC那樣,亞馬遜的移動產品頁面也沒有外部JavaScript檔案,而使用最少的內聯指令碼。HTML檔案和所有內聯JavaScript花費0.75秒載入完畢。
(請注意,jQuery不是一個輕量的替代方案,事實上是jquery本身的補充。)這兩個網站在iPhone 4下均在4秒內載入完畢。使用一個JavaScript框架前,考慮它是否真的有必要。在某些情況下,使用少量的JavaScript比呼叫一個框架更有效。
避免元件
元件對實際載入時間的影響是災難性的。為了驗證這一點,我們建立了一系列簡單的HTML檔案,每個檔案包含預設的嵌入程式碼,一個小部件。你可以看到下面的結果多糟糕。注意,這不是一個完美的測試,因為這些都是在模擬環境中的可控實驗,不過結果比較有意思。
在單個頁面中,結合他們為一個小部件,結果只包含這個部件的情況下,載入時間長達4秒。
伺服器端(後端)技術
除了優化前端,伺服器端技術也可以用來加速載入時間。這些技術都值得考慮,但不會在本文中介紹:
- 快取HTTP重定向來加速重複訪問;
- 合併HTTP重定向鏈來減少重定向;
- 使用HTTP壓縮來減少數量的位元組(Gzip或縮小)。
測試移動裝置上的效能
由於移動裝置的不可預知性,測試多個裝置上的效能是很重要的。這裡有一些免費的效能測試工具:
- Mobitest,Akamai:可以對對iPhone 4的 iOS 5.0,iPhone 3 g和Nexus S 生成瀑布圖和HAR檔案 .注意Nexus S測試結果與我們自己的內部測試不一致。我們的伺服器訪問日誌顯示,當我們測試實際安卓2。x裝置時產生了更少的HTTP請求。
- “Network Panel,” Chrome Developer Tools
結論
為了滿足移動使用者的高期望,你需要對網站針對移動裝置進行優化,在4秒或更少的時間裡載入完畢。最好的方式來達到4秒這個魔術時間,是通過減少JavaScript和優化HTML、CSS和影象,保持智慧手機上最少的處理負荷。
使用上面介紹的技術,你就可以自己建立一個符合潮流的移動網際網路體驗!你有什麼要補充的嗎?在評論中讓我們知道。