前端工程師經常被提起網站性能,如何讓網站訪問更快等問題,本文就作個總結。javascript
用戶在瀏覽網頁時,超過80%的時間都是在請求下載網頁資源,包括圖片,樣式,腳本,Flash等等,減小這些資源的下載請求數目,便成了讓網頁提速的關鍵。
固然,若是頁面很簡單,資源少,網頁請求天然就少,若是網頁內容不少,咱們如何作到減小資源請求數呢?這裏有幾個方法:css
合併靜態文件,將全部腳本、樣式文件合併到一個文件裏,能夠大大減小HTTP請求數。但若是每一個頁面的靜態文件都不同,全部文件都合併到一塊兒也會帶來麻煩,因此須要在開發過程當中均衡處理合並。html
CSS雪碧圖(Sprites),將CSS中用到的背景圖片合併到一張圖片上,而後經過background-position
去定位想用到的圖片塊,能夠減小圖片請求數。前端
使用data: URL scheme將圖片數據寫入到HTML或CSS文件中,雖然增長了HTML或CSS文件大小,但必要時,仍是須要這麼作來減小HTTP請求數。java
當頁面內容不少時,咱們但願邊加載邊正確的顯示給用戶,你可能想把CSS文件放到頁面底部,這樣就能夠優先展現用戶內容,但這會引發一個嚴重的問題,用戶先看到的是一個沒有樣式的頁面,以後閃一下(頁面重繪)又從新定義了樣式,這其實很影響用戶體驗。而最好的作法就是遵循HTML規範,把CSS文件放到文檔的HEAD標籤裏。express
JS腳本所引發的問題是阻塞了瀏覽器的並行下載,HTTP/1.1規範指出:每一個域名下的資源的並行下載數量不得超過兩個,當瀏覽器在下載JS文件時,不會進行其餘下載,即便資源被分發在不一樣的域名。瀏覽器
若是要動態設置CSS屬性,CSS表達式(CSS expressions)就顯得尤爲強(wei)大(xian),它在IE5.0中開始被支持,但又在IE8.0中被廢棄。好比如下樣式,背景色會在每一個小時都被定義一次。緩存
background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
能夠看粗,expression
方法接受一個Js語句去設置CSS屬性值,它只能被IE識別,因此在跨瀏覽器開發時(兼容IE),它就有了用武之地。安全
可是它的問題在於它執行的很是頻繁,網頁渲染時執行,窗口改變時執行,甚至頁面滾動時、用戶移動鼠標時它都會執行!前端工程師
減小CSS表達式執行次數的方法是:當頁面渲染完成後就給CSS屬性設定一個明確的值,或者在Js中監聽網頁事件,事件觸發時再去設置CSS屬性值。若是必定要使用CSS表達式,請記住,它極可能會被執行成千上萬次。
之因此外鏈CSS和JS文件會使頁面更快,是由於它們能夠被瀏覽器緩存,不然每次請求HTML文檔時都會重複下載CSS和JS代碼,雖然內聯CSS和JS能夠減小HTTP請求數,可是使得HTML文檔更大。
若是頁面比較簡單,JS和CSS都不多,使用內聯代碼減小HTTP請求,反而會讓頁面更快。
市面上的壓縮工具備不少,好比JSmin, YUI Compressor,GCC,pngcrush等等,能夠根據業務須要選擇工具去壓縮靜態文件。
使用XMLHttpRequest
對象進行POST請求時,咱們發現,它實際上是分爲兩步完成,現發送請求頭信息,再發送請求數據,因此最好使用GET請求,只須要發送一個TCP數據包(除非有不少Cookie數據),並且GET請求的數據能夠被緩存。但須要提的是,IE中對GET請求的URL長度限制在2K字節之內(參考support.microsoft.com),因此若是URL超過這個長度,只能使用POST請求。
開發過程當中,想一想這個元素或腳本是否是頁面初始化所必須的,若是不是,就能夠考慮延遲加載它們,好比默認被摺疊的元素、須要用戶觸發才須要顯示的元素以及首屏以後的頁面元素等等。
預加載看上去和上條矛盾,其實否則。當瀏覽器處於空閒時,咱們能夠預先加載以後會使用到的頁面的元素(好比:圖片,JS,CSS),以後頁面再使用這些元素時會優先從緩存中讀取。預加載分爲這兩種形式:
若是一個頁面太複雜,意味着下載時間更長,同時JS訪問DOM的速度也會變慢。減小DOM數並不意味着須要移除內容,而是咱們可使用更合理的HTML標籤。還在使用Table
佈局?頁面一堆DIV
標籤,也許咱們有更好更語義化的佈局方法。
想知道頁面的DOM數量很簡單,只須要一行JS語句:
document.getElementsByTagName('*').length
使用多域名分發內容能夠能夠增長瀏覽器並行下載數,因爲DNS解析也要耗時,通常2-4個域名比較合適。好比你能夠把HTML或JSP,PHP等文檔文件放在www.example.org這個域名上,而把靜態文件放在static1.example.or或者static2.example.org上。
iframe可讓HTML文檔嵌套在另外一個HTML文檔內,想要更好的使用它們就必須知道它們的工做原理。
iframe優勢:
* 延遲加載廣告等第三方內容
* 提供安全沙箱
* 並行下載腳本
iframe缺點:
* 代價昂貴
* 阻止父級頁面的加載
* 非語義化
Cookie經常被用在身份驗證或者存儲我的信息,他會經過HTTP頭信息在服務端和瀏覽器之間傳輸,爲了減小HTTP響應時間,咱們有必要減少Cookie。一般有如下幾個方法:
更多關於Cookie的信息能夠參考 When the Cookie Crumbles
頻繁用JS操做DOM的開銷很大,咱們能夠經過如下幾種方式減小這種開銷:
1. 緩存獲取到的DOM元素
2. 批量處理元素,一次性更新到文檔
3. 儘可能避免用JS改變頁面佈局
當過多的元素被綁定頻繁被觸發的事件,頁面響應會變慢,這時咱們就須要採用事件委託。若是你不須要等待全部圖片下載完成,可使用DOMContentLoaded
事件來代替onload
事件。
以前提到過,要將CSS文件放在HEAD標籤裏,在IE中,@import至關於把CSS文件放到了頁面底部,因此最好不用這麼使用。
在IE7一下,AlphaImageLoader
用於解決PNG圖片透明問題,若是圖片設置了這個屬性,當它在下載時,會阻塞瀏覽器渲染頁面,甚至讓瀏覽器卡死,這個問題是很嚴重。
favicon.ico是網站根目錄的一張圖片,即使你不在HTML中設置它,瀏覽器也會發出請求,而且帶上Cookie等信息。
想要較少favicon.ico帶來的不良影響,須要作到:
1. 文件小,最好在1K一下
2. 在HTTP header中設置適當的過時時間(Expires)
空的圖片src屬性有三種形式:
HTML
<img src="" />
CSS
.class{background:url("")}
JS
var img = new Image(); img.src = "";
這麼作各瀏覽器發出請求狀況各有差別,具體以下:
* IE會向頁面的目錄發出請求;
* Safari和Chrome會向當前頁面本身發出請求;
* Firefox 3及一下版本和Safari同樣,向當前頁面本身發出請求;
* Firefox 4及以上版本和Opera不發出請求;
本文粗譯自http://developer.yahoo.com/performance/rules.html,有所刪減並加了不少本身的理解。若是有錯誤或不恰當的地方,歡迎指正。
有些知識點只是粗描淡寫,好比靜態資源並行下載數、@import各瀏覽器表現差別等,歡迎在評論中詳細討論。