高性能移動web開發(fā)技巧
移動終端面臨的主要問題:
- 網(wǎng)絡數(shù)據(jù)傳輸延遲(即便是3G網(wǎng)絡)
- CPU運算能力(即便是配有1GHz+的設備)
移動終端可以做的優(yōu)化:
- 根據(jù)設備屏幕來選擇加載資源
- 降低延遲,加快連接速度
- 提高處理性能
本文介紹了一些針對移動設備優(yōu)化技術,特別針對智能移動設備(iOS,Android,WP)。
針對屏幕來優(yōu)化圖片
移動設備有不同屏幕尺寸,分辨率,應當有針對性加載不同的圖片內(nèi)容。
如果你正在開發(fā)一個只有一套帶有很多圖形樣式的站點,那就意味著無論用戶用何種大小設備都會下載這些巨大的圖片。 為什么一定要讓移動用戶下載這些為桌面用戶開發(fā)的樣式圖片呢?
不過不用擔心,現(xiàn)代很多設備都支持 CSS media queries(媒體選擇器)了, 通過media queries 我們可以方便的針對不同設備屏幕特性來加載不同版本的樣式圖片。
- /* Screens bigger than 480px */
- @media only screen and (min-device-width: 481px) {
- #header { background-image: url(header-full.png); }
- }
- /* Screens smaller than 480px */
- @media only screen and (max-device-width: 480px) {
- #header { background-image: url(header-small.png); }
- }
以上css代碼中header-full.jpg 會被自動應用在大屏幕設備里, 另外一個優(yōu)化過的小圖片(header-small.jpg)則會應用到一些小屏幕上。
另外對于一些高顯示密度的設備(如 iPhone4:326PPI),如果使用低于100dpi(dots per inch)分辨率圖片,顯示效果會不那么理想(fuzzy)! 或許可以以犧牲一點點性能的代價換一張高分辨率圖片來彌補這個問題。
可以通過media queries 點密度條件判斷 來加載不同方案:
- /* High dpi */
- @media only screen and (min-resolution: 300dpi),
- only screen and (-webkit-min-device-pixel-ratio: 1.5),
- only screen and (min--moz-device-pixel-ratio: 1.5) {
- #header { background-image: url(header-300dpi.png); }
- }
- /* Low dpi */
- @media only screen and (max-resolution: 299dpi),
- only screen and (-webkit-max-device-pixel-ratio: 1.5),
- only screen and (max--moz-device-pixel-ratio: 1.5) {
- #header { background-image: url(header-72dpi.png); }
- }
你知道嗎? 還可以通過 javascript 訪問 window.devicepixelratio對象來獲取屏幕的分辨率。
針對不同網(wǎng)絡類型
Android 2.2 最近引入了一個 navigator.connection對象, 開發(fā)者可以通過這個對象獲取當前設備的網(wǎng)絡接入類型。這樣就可以通過這個判斷來充分利用連接資源。從而針對高速的網(wǎng)絡提高一些更加優(yōu)質(zhì)的內(nèi)容。
這是一個接入方式為3G的設備中 navigator.connection 對象包含的鍵值:
- navigator = {
- connection: {
- "type": "4",
- "UNKNOWN": "0",
- "ETHERNET": "1",
- "WIFI": "2",
- "CELL_2G": "3",
- "CELL_3G": "4"
- }
- };
通過這些簡單的代碼我們就能檢測網(wǎng)絡類型,然后為HTML元素添加不同的CSS class。
- // Initialize variables
- var connection, connectionSpeed, htmlNode, htmlClass;
- // Create a custom object fallback if navigator.connection isn't available
- connection = navigator.connection || {'type':'0'};
- // Set connectionSpeed
- switch(connection.type) {
- case connection.CELL_3G:
- // 3G
- connectionSpeed = 'mediumbandwidth';
- break;
- case connection.CELL_2G:
- // 2G
- connectionSpeed = 'lowbandwidth';
- break;
- default:
- // WIFI, ETHERNET, UNKNOWN
- connectionSpeed = 'highbandwidth';
- }
這樣我們就能為不同網(wǎng)絡類型提供優(yōu)化過的CSS:
- .highbandwidth .logo { background-image:url('logo-high.jpg'); }
- .mediumbandwidth .logo { background-image:url('logo-medium.jpg'); }
- .lowbandwidth .logo { background-image:url('logo-low.jpg'); }
減少 HTTP請求
這是個老話題了,主要是通過 減少服務器傳輸損耗(roundtrips /round trip time ) 來加速站點。這點在移動網(wǎng)絡尤為明顯。你可能已經(jīng)知道以下幾點技巧:
- 使用CSS3來替代一些圖片效果(border-radius,text-shadow,background linear、radia gradients,box-reflect)
- 在CSS和HTML里使用base64編碼圖像
- 避免重定向(很不幸這個在移動設備很常見,比如用iPhone訪問yahoo.com會重定向到 m.yahoo.com)
- 緩存ajax數(shù)據(jù)
這里有一些你可能聽過的新技巧:
- 用Emoji pictograms 替代圖片(查看列表)(iOS 2.2+, other Japanese phones)
- 把通用的CSS和JS放到外聯(lián)文件里(剛開始會增加請求,緩存后就可以顯著減少請求了)
- 用localStorage替代cookie(每次HTTP請求cookie都會變成而外加載的數(shù)據(jù))
- 用HTML5緩存(cache manifest and client-side databases)來替代傳統(tǒng)緩存,可以查看下擴展閱讀里關于移動設備緩存的研究
減少javascript定時器動畫
JS動畫相對比較 過時(old-school), 新一些的瀏覽器都開始支持CSS3變換還有動畫,像iOS還有一些桌面瀏覽器都支持硬件加速。
你或許會想知道怎么通過JS來介入這些新動畫特性。 其實已經(jīng)有一些新的核心事件可以使用了:
- onwebkittransitionend (ontransitionend for Firefox, onotransitionend for Opera)
- onwebkitanimationstart
- onwebkitanimationiteration
- onwebkitanimationend
對于不支持CSS3動畫的瀏覽器,可以考慮降級使用JS動畫(在一些性能較弱的設備會表現(xiàn)不夠流暢)。因此在測試設備時,應該盡量不要使用模擬器。 因為性能方面的測試很難模擬。
localStorage 和 sessionStorage
localStorage 和 sessionStorage 可以看成javascript對象。sessionStorage的數(shù)據(jù)會在頁面關閉時清空,localStorage則可以長時間存儲數(shù)據(jù)不會因為瀏覽器關閉而自動刪除數(shù)據(jù)。
但是有一點要注意的:
這兩個對象雖然很像常規(guī)的JS對象,但是有個缺點是只能存儲字符串。所以如果你用他保存對象,可能它記錄下來的會是”[object Object]“。 悲催吧,不過可以通過 JSON.stringify() and JSON.parse() 來輔助存儲:
- var user = {
- firstName: 'Joe',
- lastName: 'Schmoe',
- age: 40
- }
- // Store the object
- localStorage.userInfo = JSON.stringify(user);
- // Retrieve the object
- var user = JSON.parse(localStorage.userInfo);
不同瀏覽器為(localStorage/sessionStorage)提供的存儲空間可能會不一樣。但是5Mb貌似是一個公認的最小值。
其他javascript技巧
這邊還有點小技巧可以優(yōu)化移動端的javascript。 但并不完整! 顯然還有更多的技術有待發(fā)現(xiàn)。但是這些將讓你有個好的開始。
- 減少表單驗證中javascript的使用,取而代之利用HTML5的表單驗證功能,如果支持的話:input autofocus attribute,input placeholder text,new form validation (還未完成)
- 減少初始延遲:即使你用的是WIFI,但是性能不佳的設備仍舊會花很多時間來解析腳本!你可以先加載JS再后解析: loading the JS in a comment block and eval’ing later (一個聰明的方法,來自Gmail Mobile team)
- 利用新客戶端數(shù)據(jù)庫技術(indexedDB已經(jīng)開始成為受歡迎的標準),但是iOS4.2與Android2.2還未實現(xiàn)支持
- geolocation:保存或緩存用戶最后記錄的位置
- 利用WebSokects(目前只有iOS4.2+支持 )
結論
要記住移動設備不僅僅只是屏幕大小比較特殊! 內(nèi)容傳輸與處理也比通常情況來得慢,所以要開始重視這個問題。
這是一個甜蜜而又痛苦的事實: 移動設備連接速度與處理能力都比較弱,但是還是可以通過一些可用的很棒的HTML5/CSS3特性來彌補這些不足。
擴展閱讀:
- W3C’s Mobile Web Application Best Practices
- Slides: Mobile Web High Performance (Maximiliano Firtman, author of Programming the Mobile Web)
- Best Practices for a Faster Web App with HTML5
- Nokia JavaScript Performance Best Practices
- Mobile cache file sizes (Steve Souders)
- Mobile Browser Cache Limits, Revisited (Ryan Grove)
- Gmail for Mobile HTML5 Series: Reducing Startup Latency