移動網(wǎng)站性能優(yōu)化:網(wǎng)頁加載技術(shù)概覽
性能一直是網(wǎng)站成功的關(guān)鍵。越來越多的研究已經(jīng)證明,不管是小型電商,還是像沃爾瑪那樣的連鎖店,即使是頁面加載時間方面的細微改善,都可以帶來更多的業(yè)務(wù),更多的廣告收入,更多的用戶粘性和更多的客戶滿意度。
在過去幾年,Web開發(fā)者都是基于改善硬件或者提高帶寬速度來優(yōu)化用戶體驗。但是最近幾年,爆炸式的移動Web瀏覽器的使用打破了這個途徑。低帶寬,高延遲,小內(nèi)存,低處理器性能的移動設(shè)備環(huán)境,迫使開發(fā)者不得不想辦法通過優(yōu)化前端頁面的性能來滿足用戶的性能預(yù)期。
在強調(diào)如何解決移動端性能問題上,這篇文章總結(jié)了一些前端優(yōu)化的案例,并且概括了一些加速頁面的方法和策略。
為什么性能會影響這么多
不論你的頁面設(shè)計地多么有趣、漂亮、交互性好,不管是在桌面還是移動設(shè)備上,如果頁面需要花2到3秒時間去渲染展示,那么用戶都會很快變得不耐煩的??梢灶A(yù)期的是,在頁面還在加載的時候,用戶很有可能從瀏覽購買的行為轉(zhuǎn)變?yōu)辄c擊回退鍵或者是關(guān)閉瀏覽器的行為。
不到1秒鐘的延遲甚至也會顯著地影響收入。在2006年,當(dāng)時還在Google工作的Marissa Mayer說,由于用戶表示希望在一個搜索頁上看到多于10個搜索結(jié)果,Google就實驗性地修改為30個。但是讓人吃驚的是,在這個實驗里,流量和投 資都減少了20個百分點,顯然是由于更多的搜索結(jié)果導(dǎo)致多花費了半秒時間來加載頁面。^5
用戶的期望總是在不斷的提升。2009年,F(xiàn)orrester研究所的Akamai的一項研究發(fā)現(xiàn)表明,網(wǎng)頁響應(yīng)時間可容忍的閥值是2秒,一旦網(wǎng)頁 相應(yīng)時間超過3秒,會有40%的用戶放棄瀏覽頁面。一年之后,Akamai的另一項研究表明,超過3秒放棄瀏覽頁面的用戶比例上升到了57%。^1,7
此外,移動端的用戶希望移動設(shè)備上的頁面性能不亞于桌面PC。由Tealeaf科技(現(xiàn)在已經(jīng)并入IBM)委托的“Harris的互動2011移動 交互調(diào)查”顯示,在前一年有過移動消費經(jīng)歷的成年人中,有85%希望移動設(shè)備上的體驗?zāi)芘c手提電腦或者PC上的體驗相當(dāng),甚至于更好。并且有63%的人表 示,一旦他在移動設(shè)備上的交易遇到了一個問題,他們就不會再想通過其他渠道去購買這個公司的其他產(chǎn)品了。^10換句話說,差勁的移動頁面性能會影響到公司 其他各種平臺的銷售,這其中當(dāng)然也包括線下的實體店。
移動流量正在迅速增長。對許多消費者而言,他們的手機或者平板設(shè)備已經(jīng)成為他們?yōu)g覽網(wǎng)絡(luò)的主要入口了,但是其性能表現(xiàn)卻差強人意。2011年2 月,Compuware公司委托Equation 研究所做的一項研究表明,幾乎一半的移動用戶(46%)表示他們手機上的網(wǎng)站加載速度過慢。60%的用戶希望頁面能在3秒或者更少的時間內(nèi)加載完 成,74%的用戶表示,當(dāng)單個頁面加載時間花費5秒或者更多的時候,他們會選擇離開這個頁面。在2012年,由Strangeloop網(wǎng)絡(luò)(現(xiàn)已并入 Redware)發(fā)起的一項針對200家領(lǐng)先的電子商務(wù)網(wǎng)站研究表明,3G網(wǎng)絡(luò)環(huán)境下,平均加載時間為11.8秒(圖1),而在LTE(4G)環(huán)境下,加 載時間只有輕微的改善,為8.5秒。
移動設(shè)備表現(xiàn)性能的三種影響因素
正如上文所說的,移動設(shè)備天生有下面三種性能限制:帶寬低,內(nèi)存小,處理器性能低。這些性能挑戰(zhàn)又加上一些其他的問題,例如:
網(wǎng)頁比以前更大。根據(jù)HTTP Archive網(wǎng)站的分析,現(xiàn)在平均的一個web頁面需要加載超過1MB的數(shù)據(jù),其中包含有圖片,Javascript,CSS(Cascading Style Sheets)等。更大的網(wǎng)頁會影響桌面PC的顯示性能。對于移動端的性能 — 特別是3G環(huán)境下的性能 — 影響更嚴重。這個影響會在今后的三年更加明顯。以現(xiàn)在的頁面增長速度來說,到2015年,平均的頁面大小會達到2MB。
延遲相差巨大。對LTE來說,延遲大概有34ms,對3G來說,延遲大概有350毫秒甚至更多。移動端的延遲性 唯一不變的就是延遲時間永遠是不定的,即使是在同一個地點,每次的延遲都是不定的。這是由于大量的數(shù)據(jù)是通過信息塔進行傳輸?shù)?。因此諸如天氣,甚至是持有 者所面向的方向都有可能成為影響因素。
下載速度相差巨大。下載速度的范圍從3G環(huán)境下的1Mbps到LTE環(huán)境下的31Mbps。把這個和美國平均的帶寬15Mbps相比是一個很有意思的事情,3G環(huán)境比平均帶寬慢了15倍,而LTE卻能達到平均帶寬的2倍那么快。
M.SITES并不能完全解決移動端性能的問題。
許多網(wǎng)站建設(shè)者嘗試針對多用戶訪問,大網(wǎng)頁和低流量連接的訪問頁面,開發(fā)出短小,快速,精簡的m.sites;但是,這些嘗試并沒有什么用,當(dāng)用戶有選擇權(quán)的時候,高達35%的移動用戶會選擇瀏覽完整的網(wǎng)站。
這些選擇瀏覽完整網(wǎng)站的用戶顯然比瀏覽m.sites的用戶更有購買欲望。一個研究表明,移動端每$7.00的消費中,有$5.50是來自于網(wǎng)站的網(wǎng)站瀏覽,只有$1.00是來自于m.sites,剩下的$0.50則是來自于客戶端。
解決問題
改善網(wǎng)站性能的主要策略并沒有因為從PC變成手機或者平板設(shè)備而有變化,只是會參雜一些小的策略。
不論在PC還是在移動瀏覽器上,頁面展示需要的時間里,只有20%是用來讀取頁面的HTML的。剩下的80%是用來加載額外的像樣式表、腳本文件、或者圖片這樣的資源和執(zhí)行客戶端的程序。
三個主要的改善性能的策略是:
- 減少每個頁面需要獲取額外資源的HTTP請求數(shù)
- 減少每個請求加載的大小
- 優(yōu)化客戶端執(zhí)行的優(yōu)先級和腳本執(zhí)行的效率
由于移動網(wǎng)絡(luò)通常比桌面機器的網(wǎng)絡(luò)慢,所以減少請求數(shù)和請求加載量是非常重要的。由于移動端的瀏覽器解析HTML和執(zhí)行JavaScript的效率 比桌面PC低,所以優(yōu)化客戶端程序也是非常關(guān)鍵的。另外,移動端瀏覽器的緩存大小比桌面PC低,所以需要有方法能重復(fù)利用本地的緩存資源。
文章剩余部分總結(jié)了能解決這些問題的方法。雖然這些方法大都可以自動化解決,當(dāng)然也可以由有經(jīng)驗的前端工程師來手動解決。關(guān)鍵就是要知道人工解決這 些技術(shù)的方法如何控制資源的請求。通常在CMS(內(nèi)容管理系統(tǒng))或者其他Web應(yīng)用中,有些頁面包含一些自動生成好的或者離線的HTML片段、CSS或者 Javascript文件,這樣的頁面開發(fā)者就不需要去優(yōu)化它們了。
減少請求
最大的性能漏洞就是一個頁面需要發(fā)起幾十個網(wǎng)絡(luò)請求來獲取諸如樣式表、腳本或者圖片這樣的資源。這個在相對低帶寬和高延遲的移動設(shè)備連接上來說影響 更嚴重。CDNs(內(nèi)容分發(fā)網(wǎng)絡(luò))把資源放在離用戶地理位置更近的地方對解決這個問題能起到很大作用,但是比起獲取請求,大量的請求對頁面加載時間的影響 更為嚴重。而且最近的發(fā)現(xiàn)表明,CDNs對移動端用戶的性能影響越來越低。
下面的章節(jié)討論了簡化HTTP請求的幾種方法。
整合資源
對開發(fā)者來說,將Javascript代碼和CSS樣式放到公共的文件中供多個頁面共享是一種標準的優(yōu)化方法。這個方法能很簡單的維護代碼,并且提高客戶端緩存的使用效率。
在Javascript文件中,要確保在一個頁面中相同的腳本不會被加載多次。當(dāng)大團隊或者多個團隊合作開發(fā)的時候,這種冗余的腳本就很容易出現(xiàn)。你可能會對它的發(fā)生頻率并不低感到非常吃驚。
Sprites是css中處理圖片的一項技術(shù)。Sprites就是將多張圖片整合到一個線性的網(wǎng)狀的大圖片中。頁面就可以將這個大圖片一次性獲取回 來并且做為css的背景圖,然后使用css的背景定位屬性展示頁面需要的圖片部分。這種技術(shù)將多個請求整合成一個,能顯著地改善性能。
實現(xiàn)小貼士:平穩(wěn)地改進但是需要對資源有控制權(quán)限。根據(jù)開發(fā)者的網(wǎng)站不同權(quán)限,一些資源并不需要被整合起來(例如,一些由CMS生成的資源)。還 有,對于一些外部域引用的資源,強行整合可能會導(dǎo)致問題。需要注意的是,整合資源對手機瀏覽器來說是一把雙刃劍。整合資源確實會在首次訪問減少請求,但是 大的資源文件可能會導(dǎo)致緩存失效,所以,需要小心地使用各種技術(shù)整合資源,以達到優(yōu)化本地存儲的目的。
使用瀏覽器緩存和本地緩存
現(xiàn)在所有的瀏覽器都會使用本地資源去緩存住那些被Cache-Control或者Expires頭標記的資源,這些頭能標記資源需要緩存的時間。另 外,ETag(實體標簽)和Last-Modified頭來標識當(dāng)資源過期后是否需要重新請求。瀏覽器為了減少不必要的服務(wù)器請求,盡可能地從本地緩存中 獲取資源,并且將那些已經(jīng)過期的、或者當(dāng)緩存空間減小的時候?qū)⒛切┖芫貌挥玫馁Y源進行清理。瀏覽器緩存通常包括圖片,CSS,Javascript代碼, 這些緩存能合理地提高網(wǎng)站的性能。(比如為了支持后退和前進的按鈕,使用一個單獨的緩存來保存整個渲染的頁面)。
移動瀏覽器緩存,通常是比桌面PC小的多,這就導(dǎo)致了緩存的數(shù)據(jù)會很經(jīng)常被清理。HTML5的緩存基于瀏覽器緩存提供了一個很好的替換方案。 Javascript的localStorage已經(jīng)在所有主流的桌面和移動端瀏覽器上都實現(xiàn)了。使用腳本代碼能簡便地支持HTML5的 localStorage操作,可以讀寫鍵值數(shù)據(jù),每個域名大概有5MB的容量。雖然不同的移動瀏覽器上讀寫速度相差很大,但是localStorage 大容量的緩存使得它很適合作為客戶端的緩存。從localStorage獲取資源明顯快于從服務(wù)器上獲取資源,而且在大多數(shù)移動設(shè)備上也比依靠緩存頭或者 瀏覽器的本地緩存更靈活可靠。這是移動瀏覽器比桌面PC更有優(yōu)勢的一個地方,在桌面PC上,本地緩存仍然優(yōu)先使用標準的瀏覽器緩存,導(dǎo)致桌面PC本地緩存 的性能落后于移動瀏覽器。
實現(xiàn)小貼士:需要進一步考慮。雖然localStorage的機制易于實現(xiàn),但是它的一些控制機制卻是非常復(fù)雜的。你需要考慮到緩存帶給你的所有問題,比如緩存失效(什么時候需要刪除緩存?),緩存丟失(當(dāng)你希望數(shù)據(jù)在緩存中的時候它并不在怎么辦?),還有當(dāng)緩存滿的時候你怎么辦?
首次使用的時候在HTML中嵌入資源
HTML的標準是使用鏈接來加載外部資源。這使得更容易在服務(wù)器上(或者在CDN上)操作更新這些資源,而不是在每個頁面上修改更新這些資源。根據(jù)上文討論的,這種模式也使得瀏覽器能從本地緩存而不是服務(wù)器上獲取資源。
但是對還沒有緩存到瀏覽器localStorage的資源來說,這種模式對網(wǎng)站的性能有負面的影響。一般來說,一個頁面需要幾十個單獨的請求來獲取 資源從而渲染頁面。所以說,從性能的角度來說,如果一個資源沒有很高的被緩存的幾率的話,最好把它嵌入到頁面的HTML中(叫inlining),而不是 使用鏈接外部。腳本和樣式是支持內(nèi)嵌到HTML中的,但是圖片和其他的二進制資源其實也是可以通過內(nèi)嵌包含base64編碼的文本來嵌入到HTML中的。
內(nèi)嵌的缺點是頁面的大小會變得非常大,所以對于Web應(yīng)用來說,關(guān)鍵的是能夠跟蹤分析這個資源什么時候需要從服務(wù)端獲取,什么時候已經(jīng)緩存到客戶端 了。另外,在第一次請求資源后必須能夠使用代碼在客戶端緩存資源,因此,在移動設(shè)備上,使用HTML5 localStorage能很好地做到內(nèi)嵌。
實現(xiàn)小貼士:平穩(wěn)處理。由于不知道用戶是否已經(jīng)訪問過這個頁面了,所以需要網(wǎng)站有機制能生成不同版本的頁面。
使用HTML5服務(wù)端發(fā)送事件
Web應(yīng)用已經(jīng)使用了各種從服務(wù)器上輪詢資源的方法來持續(xù)地更新頁面。HTML5的EventSource對象和Server-Sent事件能通過 瀏覽器端的JavaScript代碼打開一個服務(wù)端連接客戶端的單向通道。服務(wù)端可以使用這個寫通道來發(fā)送數(shù)據(jù),這樣能節(jié)省了HTTP創(chuàng)建多個輪詢請求的 消耗。這種方式比HTML的WebSocket更高效。WebSocket的使用場景是,當(dāng)有許多客戶端和服務(wù)端的交互的時候(比如消息或者游戲),在全 雙工連接上建立一個雙向通道。
實現(xiàn)小貼士:需要進一步考慮。這個技術(shù)是基于具體的技術(shù)實現(xiàn)的。如果你的網(wǎng)站當(dāng)前是使用其他的Ajax或者Comet技術(shù)來輪詢的,轉(zhuǎn)變成Server-Sent 事件需要重構(gòu)網(wǎng)站的Javascript代碼。
消除重定向
當(dāng)用戶在一個移動設(shè)備上訪問桌面PC網(wǎng)站的時候,Web網(wǎng)站應(yīng)用通常讀取HTTP的user-agent頭來判斷這個用戶是否是來自移動設(shè)備的。然 后應(yīng)用會發(fā)送帶有空HTTP body和重定向HTTP地址頭的HTTP 301(或者302)請求,把用戶重定向到網(wǎng)站的移動版本上去。但是,這個額外的客戶端和服務(wù)端的交互通常在移動網(wǎng)絡(luò)上會消耗幾百毫秒。因此,在原先的請 求上傳遞移動的web頁會比傳遞一個重定向的信息并讓客戶端再請求移動頁面更快。
對于那些想要在移動設(shè)備上看桌面PC網(wǎng)站的用戶來說,你可以在移動web頁面上提供一個鏈接入口,這樣也能同時表示你的網(wǎng)站是并不提倡這種行為的。
實現(xiàn)小貼士:雖然這個技術(shù)在理論上是簡單的,但是實際上并不易于實施。由于有些m.sites是宿主在其他地方 的,所以許多網(wǎng)站會選擇重定向到一個不同的服務(wù)器上。有的網(wǎng)站則是會在重定向請求的時候種植上Cookie告訴Web應(yīng)用這個用戶是在使用移動設(shè)備。這種 方法可能對web應(yīng)用來說更容易控制。
減少資源負載
大小問題。渲染小頁面更快,獲取小資源也更快。減小每個請求的大小通常不如減少頁面請求個數(shù)那么顯著地提高性能。但是,有些技術(shù)在性能方面,特別是在需要對帶寬和處理器性能精打細算的移動設(shè)備環(huán)境下,仍然是能帶來很大利益的。
壓縮文本和圖像
諸如gzip這樣的壓縮技術(shù),依靠增加服務(wù)端壓縮和瀏覽器解壓的步驟,來減少資源的負載。但是,一般來說,這些操作都是被高度優(yōu)化過了。而且測試表 明,壓縮對網(wǎng)站還是起到優(yōu)化性能的作用的。那些基于文本的響應(yīng),包括HTML,XML,JSON(Javascript Object Notation),Javascript,和CSS可以減少大約70%的大小。
瀏覽器在Accept-Encoding請求頭中申明它的解壓縮技術(shù),并且當(dāng)它們接收到服務(wù)端返回的Content-Encoding響應(yīng)頭標示的時候,就會按照這個響應(yīng)頭自動做解壓操作。
實現(xiàn)小貼士:易于實現(xiàn)。如果設(shè)置正確的話,現(xiàn)在所有的Web服務(wù)器都支持壓縮響應(yīng)。但是,也有一些桌面PC的安全工具會將請求頭中的Accept-Encoding頭去掉,這樣即使瀏覽器支持解壓縮,用戶也無法獲取到壓縮后的響應(yīng)。
代碼簡化
簡化通常是使用在腳本和樣式文件中,刪除一些不必要的字符,比如空格,換行符,或者注釋等。不需要暴露給外部的命名就可以被縮短為一個或者兩個字 符,比如變量名。合適的簡化資源通常在客戶端不需要做任何其他的處理,并且平均減少20%的資源大小。內(nèi)嵌在HTML中的腳本和樣式文件也是可以精簡的。 有很多很好的庫來做精簡化的操作,這些庫一般也同時會提供合并多個文件這樣減少請求數(shù)的服務(wù)。
簡化帶來的好處并不局限于減少帶寬和延遲,對于那些移動設(shè)備上緩存無法保存的過大資源來說,也是很有改善的。Gzip在這個方面并沒有任何幫助,因為資源是在被解壓后才被緩存起來的。
實現(xiàn)小貼士:易于實現(xiàn)。Google的Closure Compiler已經(jīng)難以置信地完成了理解和簡化Javascript的工作。但是CSS的簡化則沒有那么容易,因為對不同瀏覽器來說有不同的CSS技術(shù) 能迷惑CSS簡化工具,然后讓CSS簡化后無法正常工作。必須要注意的是,已經(jīng)有這樣的案例了,即使只是刪除了不必要的字符,簡化工作也有可能破壞頁面。 所以當(dāng)你應(yīng)用簡化技術(shù)之后,請做一下完整的功能測試工作。
調(diào)整圖片大小
圖片通常是占用了Web頁面加載的大部分網(wǎng)絡(luò)資源,也占用了頁面緩存的主要空間。小屏幕的移動設(shè)備提供了通過調(diào)整圖片大小來加速傳輸和渲染圖片資源的機會。如果用戶只是在小的移動瀏覽器窗口中看圖片的話,高分辨率的圖片就會浪費帶寬、處理時間和緩存空間。
為了加速頁面渲染速度和減少帶寬及內(nèi)存消耗,可以動態(tài)地調(diào)整圖片大小或者將圖片替換為移動設(shè)備專用的更小的版本。不要依靠瀏覽器來將高分辨率的圖片轉(zhuǎn)換成小尺寸的圖片,這樣會浪費帶寬。
另外一個方法是先盡快加載一個低分辨率的圖片來渲染頁面,在onload或者用戶已經(jīng)開始和頁面交互以后將這些低分辨率的圖片替換成為高分辨率的圖片。
實現(xiàn)小貼士:特別應(yīng)用在高度動態(tài)化的網(wǎng)站是有優(yōu)勢的。
使用HTML5和CSS 3.0來簡化頁面
HTML5包括了一些新的結(jié)構(gòu)元素,例如header,nav,article和footer。使用這些語義化的元素比傳統(tǒng)的使用div和span 標簽?zāi)苁沟庙撁娓唵魏透菀捉馕?。一個簡單的頁面更小加載更快,并且簡單的DOM(Document Object Model)代表著更快的JavaScript執(zhí)行效率。新的標簽?zāi)芎芸斓貞?yīng)用在包括移動端的新瀏覽器版本上,并且HTML5設(shè)計讓那些不支持它的瀏覽器 能平穩(wěn)過渡使用新標簽。
HTML5的一些表單元素提供了許多新屬性來完成原本需要javascript來完成的功能。例如,新的placeholder屬性用于顯示在用戶輸入進入輸入框之前顯示的介紹性文字,autofocus屬性用于標示哪個輸入框應(yīng)當(dāng)被自動定位。
也有一些新的輸入框元素能不用依靠Javascript就可以完成一些通用的需求。這些新的輸入框類型包括像e-mail,URL,數(shù)字,范圍,日 期和時間這樣需要復(fù)雜的用戶交互和輸入驗證的元素。在移動瀏覽器上,當(dāng)需要輸入文本的時候,彈出的鍵盤通常是由特定的輸入框類型來做選擇的。不支持指定的 輸入類型的瀏覽器就會只顯示一個文本框。
另外,只要瀏覽器支持內(nèi)建的層次,圓角,陰影,動畫,過渡和其他的圖片效果,CSS 3.0就能幫助你創(chuàng)建輕便簡易的頁面了,而這些圖片效果原先是需要加載圖片才能完成的。這樣,這些新特性就能加速頁面渲染了。
有很多Web站點都提供哪些移動或者桌面瀏覽器支持哪項性能的更新說明。(例如:http://caniuse.com/ 和 mobilehtml5.org)。
實現(xiàn)小貼士:需要進一步考慮。人工地做這些改動是非常復(fù)雜和耗時的。如果你使用CMS,它可以幫你生成許多你不需要控制的HTML和CSS。
優(yōu)化客戶端的程序處理
瀏覽器按照什么順序來執(zhí)行代碼生成一個頁面,和頁面復(fù)雜性及JavaScript的技術(shù)選擇,都對性能有很大的影響。特別在客戶端相對較慢的CPUs和少內(nèi)存的移動端中尤為明顯。下面的章節(jié)提供一些策略來提升頁面處理的性能。
延遲渲染”BELOW-THE-FOLD”內(nèi)容
可以確定的是如果我們將不可見區(qū)域的內(nèi)容延遲加載,那么頁面就會更快地展現(xiàn)在用戶面前,這個區(qū)域叫做”below the fold”。為了減少頁面加載后需要重新訪問的內(nèi)容,可以將圖片替換為正確的高寬所標記的<img>標簽。
實現(xiàn)小貼士:平穩(wěn)處理。一些好的Javascript庫可以用來處理這些below-the-fold 延遲加載的圖像。
延遲讀取和執(zhí)行的腳本
在一些移動設(shè)備上,解析Javascript代碼的速度能達到100毫秒每千字節(jié)。許多腳本的庫直到頁面被渲染以后都是不需要的加載的。下載和解析 這些腳本可以很安全地被推遲到onload事件之后來做。例如,一些需要用戶交互的行為,比如托和拽,都不大可能在用戶看到頁面之前被調(diào)用。相同的邏輯也 可以應(yīng)用在腳本執(zhí)行上面。盡量將腳本的執(zhí)行延遲到onload事件之后,而不是在初始化頁面中重要的可被用戶看到的內(nèi)容的時候執(zhí)行。
這些延遲的腳本可能是你自己寫的,更重要的是,也有可能是第三方的。對廣告、社交媒體部件、或者分析的差勁的腳本優(yōu)化會導(dǎo)致阻塞頁面的渲染,會增加 珍貴的加載時間。當(dāng)然,你需要小心地評估諸如jquery這樣為移動網(wǎng)站設(shè)計的大型腳本框架,特別當(dāng)你僅僅只是使用這些框架中的一些對象的時候更要小心評 估。
實現(xiàn)小貼士:平穩(wěn)處理。許多第三方的框架現(xiàn)在提供延遲加載的異步版本的API。開發(fā)者只需要將原先的邏輯轉(zhuǎn)化到 這個異步版本。一些JavaScript要做延遲加載會有些復(fù)雜,因為在onload之后執(zhí)行這些腳本需要注意很多注意事項。(例如,你有個腳本需要綁定 到onload事件上,你需要做什么?如果你將腳本延遲到onload事件之后,就一定就會失去很多執(zhí)行的時機。)
使用Ajax來增強進程
Ajax(Asynchronous JavaScript and XML)是一項使用XHR(XMLHttpRequest)對象來從Web服務(wù)器上獲取數(shù)據(jù)的技術(shù),它并不需要更新正在運行的頁面。Ajax能更新頁面上 的某個部分而不需要重新構(gòu)建整個頁面。它通常用來提交用戶的交互相應(yīng),但是也可以用來先加載頁面的框架部分,然后當(dāng)用戶準備好瀏覽網(wǎng)頁的時候再填充詳細的 內(nèi)容。
盡管是這個名字,但是XMLHttpRequest并不強制要求你只能使用XML。你可以通過調(diào)用overrideMineType方法來制 定”application/json”類型來使用json替換XML。使用JSON.parse會比使用原生的eval()函數(shù)快了幾乎兩倍,并且更為 安全。
同時,切記Ajax的返回響應(yīng)也會得益于那些應(yīng)用在普通的返回響應(yīng)的優(yōu)化技術(shù)上面。確保對你的Ajax返回響應(yīng)使用了緩存頭,簡化,gzip壓縮,資源合并等技術(shù)。
實現(xiàn)小貼士:由于這個技術(shù)是根據(jù)具體應(yīng)用不同而不同的,所以很難量化。或許由于跨域問題,你需要使用XHR2,這個技術(shù)能使用外部域的資源,從而能進行跨域的XHR請求。
根據(jù)網(wǎng)絡(luò)狀況進行適配處理
由于使用更多帶寬會使用更多移動網(wǎng)絡(luò)的費用,所以只有能檢測網(wǎng)絡(luò)的類型才能使用針對特定網(wǎng)絡(luò)的優(yōu)化技術(shù)。例如,預(yù)加載未來使用到的請求是非常聰明的做法,但是如果用戶的帶寬很稀有,并且加載的有些資源是永遠不會用到的話,這個技術(shù)就是不合理的了。
在Android 2.2+,navigator.connection.type屬性的返回值能讓你區(qū)分Wifi和2G/3G/4G網(wǎng)絡(luò)。在Blackberry 上,blackberry.network也能提供相似的信息。另外,服務(wù)端通過檢測請求中的User-Agent頭或者其他的嵌入到請求中的信息能讓你 的應(yīng)用檢測到網(wǎng)絡(luò)狀況。
實現(xiàn)小貼士:需要進一步考慮。檢測網(wǎng)絡(luò)信息的API最近已經(jīng)有所變化了。^11 接口現(xiàn)在不是直接定義Wi-Fi,3G等網(wǎng)絡(luò)狀況,而是給出了帶寬信息和諸如“非常慢,慢,快和非???rdquo;這樣的建議。有個屬性能給出估計的MB/s值和一 個“meterd”的Boolean值來表示它的可信度,但是對瀏覽器來說,很難根據(jù)這個來判斷環(huán)境。判斷當(dāng)前網(wǎng)絡(luò)環(huán)境然后適配仍然是一種最好的方法,但 是這種方法正在被考慮被替換。
對多線程來說盡量使用HTML5的WEB WORKER特性
HTML5中的Web Worker是使用多個線程并發(fā)執(zhí)行Javascript程序。另外,這種特別的多線程實現(xiàn)能減少困惑開發(fā)者多年的,在其他平臺上遇到的問題。例如,當(dāng)一 個線程需要改變一個正在被其他線程使用的資源該如何處理。在Web Worker中,子線程不能修改主用戶界面(UI)線程使用的資源。
對提高移動站點的性能來說,Web Worker中的代碼很適合用來預(yù)處理用戶完成進一步操作所需要的資源的,特別是在用戶的帶寬資源不緊缺的情況下。在低處理器性能的移動設(shè)備上,過多的預(yù) 加載可能會干擾當(dāng)前頁面的UI響應(yīng)。使用多線程代碼,讓W(xué)eb Worker對象(并且盡可能使用localStorage來緩存數(shù)據(jù))在另外一個線程中操作預(yù)加載資源,這樣就能不影響當(dāng)前的UI表現(xiàn)了。
要特別說明的是,Web Worker只在Android 2.0以上的版本實現(xiàn),而且iphone上的ios5之前的版本也不支持。在桌面PC上,總是落后的IE只在IE 10才支持Web Worker。
實現(xiàn)小貼士:平穩(wěn)過渡。雖然這項技術(shù)并不是非常難實現(xiàn),但是對Web Workers來說,有一些限制需要強制遵守。Web Workers不能進入到頁面的DOM,也不能改變頁面上的任何東西。Web Worker很適合那種需要后臺計算和處理的工作。
將CLICK事件替換成TOUCH事件
在觸摸屏設(shè)備上,當(dāng)一個用戶觸碰屏幕的時候,onclick事件并沒有立即觸發(fā)。設(shè)備會使用大約半秒(大多數(shù)設(shè)備差不多都是300毫秒)來讓用戶確 定是手勢操作還是點擊操作。這個延遲會很明顯地影響用戶期望的響應(yīng)性能。要使用touchend事件來替換才能解決。當(dāng)用戶觸碰屏幕的時候,這個事件會立 即觸發(fā)。
為了要確保不會產(chǎn)生用戶不期望的行為,你應(yīng)該也要使用touchstart和touchmove事件。例如,除非同時有個touchstart事件 在button上,否則不要判斷touchend事件在button上就意味著點擊行為 — 因為用戶有可能從其他地方觸碰開始,然后拖拽到button上觸碰結(jié)束的。你也可以在touchstart事件之后使用touchmove事件來避免將 touchend事件誤判為點擊,當(dāng)然前提是需要假設(shè)拖拽的手勢并不是預(yù)期產(chǎn)生點擊行為。
另外,你也需要去處理onclick事件來讓瀏覽器改變button的外觀從而標識為已點擊的狀態(tài),同時你也需要處理那些不支持touch事件的瀏 覽器。為了避免代碼在touchend和onclick代碼中重復(fù)執(zhí)行,你需要在確保用戶觸碰事件已經(jīng)在touchend執(zhí)行了之后,在click事件中 調(diào)用preventDefault和stopPropagation方法。^4
實現(xiàn)小貼士:需要進一步考慮。這種技術(shù)需要更多工作才能在一個頁面中增加和維護鏈接。touch事件的代碼必須考慮其他手勢,因為替換click的還有可能是縮放或者敲擊動作。
支持SPDY協(xié)議
應(yīng)用層HTTP和HTTPS協(xié)議導(dǎo)致的一些性能瓶頸,使得不論是桌面還是移動端的網(wǎng)站都非常難受。在2009年,谷歌開始研發(fā)一種叫做SPDY(諧 意是”speedy”)的協(xié)議來替換已有的協(xié)議,這種協(xié)議宣稱能突破這些限制。這個協(xié)議的目標是讓多種瀏覽器和多種Web服務(wù)都能支持,所以這個協(xié)議是開 源的,但是初步地,只有Google的Chrome瀏覽器(在版本10及之后的)和google的站點支持。一旦一個Web服務(wù)支持SPDY,那么它上面 的所有站點都可以和支持這個協(xié)議的瀏覽器使用SPDY進行交互。將SPDY應(yīng)用在25個top100的Internet網(wǎng)站上,Google收集到的數(shù)據(jù) 是網(wǎng)站的速度會改善27%到60%不等。^2
SPDY自動使用gzip壓縮所有內(nèi)容,和HTTP不同的是,它連header的數(shù)據(jù)也使用gzip壓縮。SPDY使用多線程技術(shù)讓多個請求流或者響應(yīng)流能共用一個TCP連接。另外SPDY允許請求設(shè)置優(yōu)先級,比如,頁面中心的視頻會比邊框的廣告擁有更高的優(yōu)先級。
或許SPDY中最變革性的發(fā)明就是流是雙向的,并且可以由客戶端或者服務(wù)端發(fā)起,這樣能使得信息能推送到客戶端,而不用由客戶端發(fā)起第一次請求。例 如,當(dāng)一個用戶第一次瀏覽一個站點,還沒有任何站點的緩存,這個時候服務(wù)端就可以在響應(yīng)中推送所有的請求資源,而不用等候每個資源被再次獨立請求了。作為 替換協(xié)議,服務(wù)端可以發(fā)送暗示給客戶端,提示頁面需要哪些資源,同時也允許由客戶端來初始化請求。即使是使用后一種這樣的方式也比讓客戶端解析頁面然后自 己發(fā)現(xiàn)有哪些資源需要被請求來得快。
雖然SPDY并沒有對移動端有什么特別的設(shè)置,但是移動端有限的帶寬就使得如果支持SPDY的話,SPDY在減少移動網(wǎng)站的延遲是非常有用的。
實現(xiàn)小貼士:依據(jù)網(wǎng)站和服務(wù)的環(huán)境來進行平穩(wěn)操作或進一步考慮。Google有一個SPDY模塊支持 Apache2.2 – mod_spdy – 這個模塊是免費的;但是mod_spy有線程上的問題,并且和mod_php協(xié)作并不是很好,所以要求你使用這個技術(shù)的時候要確保你的網(wǎng)站的正常運行。 ^6
永遠別忘記測試!
如果缺少了持續(xù)和仔細的測試提醒,性能的優(yōu)化就只是討論而已,是無法完成的。如果沒有指定基準做比較,你系統(tǒng)上的任何改動都僅僅是理論而已。如果沒有真實的測試數(shù)據(jù),猜測性能的瓶頸是毫無意義的。
有很多開源和通用的工具能進行集成測試,并且能進行不同地域和帶寬/延遲的測試。另外,RUM(real user monitoring)工具能將測試環(huán)境從實驗室變成不可預(yù)測的真實用戶行為。
觀察移動設(shè)備的測試選擇和桌面場景一樣。如果你在選擇一個自動化的解決方案,請確保使用一個能持續(xù)測試,并且能區(qū)分出應(yīng)用優(yōu)化方法前后的變化的解決方案。
如果性能優(yōu)化如果只是在發(fā)展過程中的一個步驟而已,它不會有什么效果的。它必須成為一個持續(xù)改善網(wǎng)站的一部分。