網站前端優化一些小經驗

榮華發表於2016-03-28
/**
*作者:張榮華
*日期:2008-12-01
**/

乘著第3屆d2論壇的順利結束的秋風,我也來分享一下自己在前端優化方面的一些些小經驗,其實這些經驗本身都是來自yahoo的優化原則,不過經過ahuaxuan自身的實踐和再次的思考,把原來的原則都進行了分組和分析.不過由於ahuaxuan涉及到的東西有限,並沒有經歷過全部的優化點,所以只把自己做過的拿出來和大家討論討論,其中不免加入自己一些觀點,希望大家指正.

先說說目標,前端優化的目標是什麼,一個字:快.兩個字:更快.那麼下面我們來看看慢的網頁將會給我們帶來什麼:
1. 慢的頁面可能會網站失去更多的使用者.

2. 慢500ms意味著20%的使用者將放棄訪問(google)

3. 慢100ms意味著1%的使用者將放棄交易(amazon)

4. 慢 ???ms意味著??%的使用者將放棄xx(your site)

所以我們的目標很明確,就是要網頁展現的速度更快.
經過ahuaxuan的實踐和總結,其實要讓網頁展現更快只需要注意幾個大的方面,下面會一一描述這幾個大的方面.

1減少http請求,我把它排在了第一點,為啥要在第一點呢,很簡單,因為它最重要.

如何做呢.讓ahuaxuan帶著大家分析一下這個問題.從何處著手呢.ahuaxuan大聲疾呼,我們要從資料開始.ok,一般來說,我們從變化性上把資料分成兩種型別,變和不變.那麼不變的資料可以快取,變化的資料不能快取,這是一個常識,也就是說要減少我們的http請求次數這個目標可以轉換成把資料分為變化和不變化兩個部分.不變化的資料不需要再次請求,這樣http請求的次數就減少了,下面我們分點來描述將資料分類的途徑.

1. 合併指令碼檔案
包括指令碼,樣式和圖片,可以有選擇的把一些Js和css可以合併成一個檔案,一些圖片可以使用css sprites技術.這樣做的原因是什麼?做過web開發的人都知道,js和css基本是不變的,是靜態檔案,圖片亦然.那麼不變的檔案如果適當的合併在一起,會有什麼效果呢?請求的次數從多次變成了一次.這樣http請求的次數就減少了.當時合併之後,檔案體積變大了,會影響速度嗎?答:肯定會啊,不過這裡是需要權衡的,比如我100份靜態檔案,合併成10份還是合併成1份這就得看你得具體情況了.

2. 指定Expires或者Cache-Control,
對於靜態內容:設定檔案頭過期時間Expires的值為“Never expire”(永不過期)
動態頁面,在程式碼中新增cache-control,表示多少時間之後過期,如:
response.setHeader(“Cache-Control”, “max-age=3600”);
如果使用了Expires檔案頭,當頁面內容改變時就必須改變內容的檔名。通常是在檔案內容後加版本號
這一點是大多數人都忽略得,之前很多人在罈子上釋出自己得小系統,還有demo,ahuaxuan跑過去一看,my god,一堆又一堆得js,css,既沒有恰當得合併,也沒有設定過期時間.每次重新整理頁面都要重新下載這一堆又一堆的js,css.http請求那叫一個多啊.無謂了流量就這樣產生了.

這一點在企業應用的系統中也時有發生.比如我們使用extjs作為前端的技術,400多k啊,每開啟一個頁面都匯入,下載這個js,夠無聊的.那麼童子們可能就要問了,靜態檔案為啥不用apache,lighttpd等呢,答,用了又怎麼樣,不設expire或者max-age不是一樣要下載,最好的方法是寫一個filter,再filter中判斷,如果url滿足一定的條件(比如符合配置檔案中的正規表示式),那麼就設定一個max-age,這樣就ok,太簡單了,幾行程式碼就可以搞定.快哉.

3. 快取Ajax請求
快取的方法同動態頁面,ajax請求需要使用get方式,url長度為2k(ie)限制(post請求有兩個過程,1傳送請求headers,2傳送請求資料,根據http規範,get請求只會傳送一個tcp包).——–這一段話來自yahoo,先不管其真假,我們從另外一個方面來考慮一下為什麼最好使用get方式,講一個ahuaxuan經歷過的事情,之前有一個專案的ajax請求使用了post方式,後來發現經常出錯,而且丟擲了squid的錯誤,因為我們的網站使用了squid,問題就出在這裡了,從http協議上可以瞭解到,method=post是指把資料提交到伺服器上去,那麼squid的一個特性是不會快取post請求(事實上它確實不應該快取,因為這樣會違反http協議中的語義),把ajax請求改成get方式之後,一切恢復如常.

4. 移除重複的js
重複的js匯入也有可能導致ie重新載入該指令碼.沒啥好說的,照做.

5. 避免重定向
有一種經常被網頁開發者忽略卻往往十分浪費響應時間的跳轉現象。這種現象發生在當URL本該有斜槓(/)卻被忽略掉時。這時候會返回一個301的狀態碼,然後瀏覽器重新發起一次請求.在企業應用裡,重定向是我們在企業應用中常用的技術,不過用在網站專案上,您可要小心了,因為普通的重定向其實是server在response header中設定http status=302,瀏覽器收到之後,判斷出是302,會重新傳送一個請求,目標地址是前一次返回中指定的地址.在網站專案中如果可以不用重定向就別用吧.如果您做企業應用專案,ok,關係不大,您就放心的”定”吧.

小節,ahuaxuan把減少http請求次數分為了以上5個小點,每個小點之後附加一些例項,大家可以根據這些點來判斷自己的專案是否可以有優化的地方.

使用cdn
讓內容更靠近使用者,這有啥好說呢,原理很簡單,就是根據使用者瀏覽器所在機器的ip來判斷哪些伺服器離使用者最近,瀏覽器會再次去請求這些最近的機器.一般的cdn服務商是通過開發自己的dns server來達到這個目的的.不過這個是通常情況哦,技術實力比較高,或者場景比較特殊的公司會開發自己的cdn.當然不管怎麼說,使用cdn肯定可以使頁面響應更快(也包括音訊,視訊,圖片,文字檔案,等等等等)

減小返回資料的體積
1. 使用gzip壓縮返回資料
Gzip壓縮所有可能的檔案型別是減少檔案體積增加使用者體驗的簡單方法。比如本來400k的檔案,壓縮一下之後只有50k-100k,那麼網路的流量就立刻下來了,壓縮的代價是伺服器端要壓縮檔案,需要消耗cpu,瀏覽器需要解壓檔案,也需要消耗cpu,不過對於現代這麼nb的pc,來說,瀏覽器解壓一下資料帶來的cpu消耗簡直不值一提.所以您就壓吧.不過壓的時候要小心哦,有的瀏覽器在特定場景下會出去一些小bug,導致頁面不正常.比如ie6在跨域的時候可能會有些小麻煩,把這部分資料的gzip去掉就可以了.

2. 最小化js檔案和css檔案
壓縮js可以使用JSMin或者YUI Compressor,後者同時可以壓縮css,這個也沒啥好說的,照做吧.

3. 將css和js獨立成外部檔案
其實這一點也可以看成是區分不變資料和變化資料.很多人喜歡在頁面商寫很多很多的js和css,這些資料其實都是不會變化的資料,也就是說這些資料也是可以快取在瀏覽器上的,通過把它們獨立成外部檔案,可以把這些資料快取起來.這樣做看上去是增加的請求的次數,但是由於第一次請求之後該部分資料已經被快取,所以第二次就無需再請求後端,減少了網路頻寬的開銷.

優化Cookie
1. 減小cookie體積
能不放就別放吧,為啥呀,cookie就象鑰匙串,只有出門和回家得時候才用,但是一整天你都要帶在身上,麻煩不.
2. 合理設定Cookie域
由於二級域名可以拿到一級域名得cookie,那麼如果,而二級域名之間確不能相互共享cookie,所以合理得設定cookie得域名也可以避免無必要得頻寬浪費和響應速度得增加.
3. 設定合理的cookie過期時間
該過期就過期,不要讓不必要的資料一直帶在身上走來走去.
4. 使用域分離
為圖片或者其他靜態資原始檔使用子域或者建立新的獨立域名(申請新的域名),避免無必要的cookie傳輸,當然也是要在有必要得情況下,圖片類網站肯定有必要,javaeye上得圖片並沒有使用域分離,所以我們得cookie其實會帶到罈子得圖片伺服器上去,每次請求圖片都是如此(不過還好,罈子裡沒有什麼圖片,所以這方面的浪費不大).

小結,其實cookie上得問題,單詞請求看上去也不是什麼大問題,好像是無所謂得事情,就那麼幾十個byte,至於嗎,不過大家都聽說過水滴石穿,繩鋸木斷的故事.所以該做的,我們還是要做,正所謂,勿以善小而不為,勿以惡小而為之.
優化瀏覽器載入
1. 將css放在頁面頂部載入
把樣式表放在文件底部的問題是在包括Internet Explorer在內的很多瀏覽器中這會中止內容的有序呈現。瀏覽器中止呈現是為了避免樣式改變引起的頁面元素重繪。使用者不得不面對一個空白頁面。
HTML規範清 楚指出樣式表要放包含在頁面的<head />區域內:“和<a />不同,<link />只能出現在文件的<head />區域內,儘管它可以多次使用它”。無論是引起白屏還是出現沒有樣式化的內容都不值得去嘗試。最好的方案就是按照HTML規範在文 檔<head />內載入你的樣式表。

2. 將js放在頁面底部載入
指令碼帶來的問題就是它阻止了頁面的平行下載。HTTP/1.1 規範建議,瀏覽器每個主機名的並行下載內容不超過兩個。如果你的圖片放在多個主機名上,你可以在每個並行下載中同時下載2個以上的檔案。但是當下載指令碼時,瀏覽器就不會同時下載其它檔案了,即便是主機名不相同。

Js放在底部載入其實並不影響瀏覽器展示頁面,除非使用者會在js載入完成之前就呼叫某個js方法,比如說頁面剛展現到一半,但是恰好這一半里有一部分是呼叫了還未下載的js,這個時候就會出問題了,如果童子們遇到這種情況,可以把這部分js先載入.

總結一下下:以上這些優化點其實只是前端優化的部分內容,不過根據80/20原則,這些優化點已經覆蓋了80%的情況了,同時前端優化其實也不是什麼複雜的東西,原理上是很簡單的,更多的是需要我們的實踐,因為我們可能會碰到各種各樣的問題,而很多的這些問題其實一般是預測不到的.只有遇到過才知道.
說的不對的地方請大家拍磚,或者童子們也可以把自己的經驗在這裡和大家分享一下.代表其他童子表示十分的感謝.

當然,由於ahuaxuan水平有限,文章中難免有不到之處,還望不吝指正,謝謝.


相關文章