web前端性能優化

不管是在工做中,仍是在面試中,web前端性能的優化都是很重要的,那麼咱們進行優化須要從哪些方面入手呢?本文將遵循yahoo前端性能團隊總結的35條黃金定律。javascript

網頁內容

1.減小HTTP請求次數。

減小頁面的HTTP請求數是個起點,這是提高站點首次訪問速度的重要指導原則。css

相關的方案以下:html

  • 合併文件前端

  • CSS Spritesjava

  • 圖像映射。web

    能夠把多張圖片合併成單張圖片,總大小是同樣的,但減小了請求數並加速了頁面加載。圖片映射只有在圖像在頁面中連續的時候纔有用,好比導航條。給image map設置座標的過程既無聊又容易出錯,用image map來作導航也不容易,因此不推薦用這種方式。面試

    具體用法見 HTML圖像映射ajax

  • 行內圖片(Base64編碼)express

2.減小DNS查詢次數

相關方案以下:瀏覽器

  • DNS緩存

  • 減小不一樣的主機名,從而減小DNS查找

    減小不一樣主機名的數量同時也減小了頁面可以並行下載的組件數量,避免DNS查找削減了響應時間,而減小並行下載數量卻增長了響應時間。這是同時減小DNS查找和容許高併發下載的折中方案。

3.避免頁面跳轉

當客戶端收到服務器的跳轉回復時,客戶端再次根據服務器回覆中的location指定的地址再次發送請求,例如如下跳轉回復。

HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/html
複製代碼

當客戶端遇到這種回覆的時候,用戶只能等待客戶端再次發送請求,有的網站甚至會一直跳n次,跳到他想帶你去的地方…固然在這個時候用戶看不到任何頁面內容,只有瀏覽器的進度條一直在刷新。

重定向會拖慢用戶體驗,在用戶和HTML文檔之間插入重定向會延遲頁面上的全部東西,頁面沒法渲染,組件也沒法開始下載,直到HTML文檔被送達瀏覽器。因此要避免頁面跳轉。

4.緩存Ajax

Ajax能夠幫助咱們異步的下載網頁內容,可是有些網頁內容即便是異步的,用戶仍是在等待它的返回結果,例如ajax的返回是用戶聯繫人的下拉列表。因此咱們仍是要注意儘可能應用如下規則提升ajax的響應速度。

相關方案以下:

  • 添加ExpiresCache-Control報文頭使響應能夠被客戶端緩存
  • Gzip壓縮傳輸文件
  • 減小DNS查詢
  • 壓縮響應內容
  • 避免頁面跳轉
  • 配置ETags

5.延遲加載

這裏討論延遲加載須要咱們知道咱們的網頁最初加載須要的最小內容集是什麼。剩下的內容就能夠推到延遲加載的集合中。

Javascript是典型的能夠延遲加載內容。一個比較激進的作法是開發網頁時先確保網頁在沒有Javascript的時候也能夠基本工做,而後經過延遲加載腳原本完成一些高級的功能。

6.提早加載

與延遲加載目的相反,提早加載的是爲了提早加載接下來網頁中訪問的資源

下面是提早加載的類型:

  • 無條件提早加載:當前網頁加載完成後,立刻去下載一些其餘的內容。例如google會在頁面加載成功以後立刻去下載一個全部結果中會用到的image sprite。
  • 有條件加載:根據用戶的輸入推斷須要加載的內容,雅虎的示例是search.yahoo.com
  • 有預期的的加載:這種狀況通常發生在網頁從新設計時,因爲用戶常常訪問舊網頁,本地對舊的網頁內容緩存充分從而顯得舊網頁速度很快,而新的網頁內容卻沒有緩存,設計者能夠在舊網頁的內容中預先加載一些新網頁中可能用到的內容,這樣新的網頁就會生下來一些須要下載的資源。

7.減小DOM元素數量

網頁中元素過多對網頁的加載和腳本的執行都是沉重的負擔,500個元素和5000個元素在加載速度上會有很大差異。

想知道你的網頁中有多少元素,經過在瀏覽器中的一條簡單命令就能夠算出,

document.getElementsByTagName('*').length

多少算是多了呢?雅虎在寫這篇文章的時候號稱主頁只有700多元素,但如今接近多了一倍。咱們的網頁至少別比雅虎還多吧。。。

8.根據域名劃份內容

瀏覽器通常對同一個域的下載鏈接數有所限制,按照域名劃分下載內容能夠瀏覽器增大並行下載鏈接,可是注意控制域名使用在2-4個之間,否則dns查詢也是個問題。

通常網站規劃會將靜態資源放在相似於static.example.com,動態內容放在www.example.com上。這樣作還有一個好處是能夠在靜態的域名上避免使用cookie。後面咱們會在cookie的規則中提到。

9.減小iframe數量

使用iframe要注意理解iframe的優缺點

優勢:

  • 能夠用來加載速度較慢的內容,例如廣告
  • 安全沙箱保護。瀏覽器會對iframe中的內容進行安全控制。
  • 腳本能夠並行下載

缺點:

  • 即便iframe內容爲空也消耗加載時間
  • 會阻止頁面加載
  • 沒有語義

10.避免404

404咱們都不陌生,表明服務器沒有找到資源,咱們要特別要注意404的狀況不要在咱們提供的網頁資源上,客戶端發送一個請求可是服務器卻返回一個無用的結果,時間浪費掉了。

更糟糕的是咱們網頁中須要加載一個外部腳本,結果返回一個404,不只阻塞了其餘腳本下載,下載回來的內容(404)客戶端還會將其當成Javascript去解析。

css部分

11.避免CSS表達式

CSS表達式能夠動態的設置CSS屬性,在IE5-IE8中支持,其餘瀏覽器中表達式會被忽略。例以下面表達式在不一樣時間設置不一樣的背景顏色。

background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
複製代碼

CSS表達式的問題在於它被從新計算的次數遠比咱們想象的要多,不只在網頁繪製或大小改變時計算,即便咱們滾動屏幕或者移動鼠標的時候也在計算,所以咱們仍是儘可能避免使用它來防止使用不當而形成的性能損耗。

若是想達到相似的效果咱們能夠經過簡單的腳本作到

var currentTime = new Date().getHours();
if (currentTime%2) {
    if (document.body) {
        document.body.style.background = "#B8D4FF";
    }
}
else {
    if (document.body) {
        document.body.style.background = "#F08A00";
    }
}
複製代碼

12.用代替@import

避免使用@import的緣由很簡單,由於它至關於將css放在網頁內容底部。

13.避免使用Filters

AlphaImageLoad也是IE5.5 - IE8中支持,這種濾鏡的使用會致使圖片在下載的時候阻塞網頁繪製,另外使用這種濾鏡會致使內存使用量的問題。IE9中已經再也不支持。

14.將樣式表置頂

經樣式表(css)放在網頁的HEAD中會讓網頁顯得加載速度更快,由於這樣作可使瀏覽器逐步加載已將下載的網頁內容。這對內容比較多的網頁尤爲重要,用戶不用一直等待在一個白屏上,而是能夠先看已經下載的內容。

若是將樣式表放在底部,瀏覽器會拒絕渲染已經下載的網頁,由於大多數瀏覽器在實現時都努力避免重繪,樣式表中的內容是繪製網頁的關鍵信息,沒有下載下來以前只好對不起觀衆了。

Javascript

15.去除重複腳本

重複的腳本不只浪費瀏覽器的下載時間,並且浪費解析和執行時間。通常用來避免引入重複腳本的作法是使用統一的腳本管理模塊,這樣不只能夠避免重複腳本引入,還能夠兼顧腳本依賴管理和版本管理。

16.減小DOM訪問

經過Javascript訪問DOM元素沒有咱們想象中快,元素多的網頁尤爲慢,對於Javascript對DOM的訪問咱們要注意應更迅速,應該:

  • 緩存已經訪問過的元素
  • 先「離線」更新節點而後再加回DOM Tree
  • 避免經過Javascript修復佈局問題

17.使用智能事件處理

這裏說智能的事件處理須要開發者對事件處理有更深刻的瞭解,經過不一樣的方式儘可能少去觸發事件,若是必要就儘早的去處理事件。

有時候感受頁面反映不夠靈敏,是由於有太多頻繁執行的事件處理器被添加到了DOM樹的不一樣元素上,這就是推薦使用事件委託的緣由。若是一個div裏面有10個按鈕,應該只給div容器添加一個事件處理器,而不是給每一個按鈕都添加一個。事件可以冒泡,因此能夠捕獲事件並得知哪一個按鈕是事件源。

18.將腳本置底

HTTP/1.1官方文檔建議瀏覽器每一個主機名下並行下載的文件數不要超過兩個,若是圖片來自多個主機名,並行下載的數量就能夠超過兩個。若是腳本正在下載,瀏覽器就不開始任何其它下載任務,即便是在不一樣主機名下的。由於瀏覽器要在腳本下載以後依次解析和執行。

所以對於腳本提速,咱們能夠考慮如下方式,

  • 把腳本置底,這樣可讓網頁渲染所須要的內容儘快加載顯示給用戶。
  • 如今主流瀏覽器都支持defer關鍵字,能夠指定腳本在文檔加載後執行。
  • HTML5中新加了async關鍵字,可讓腳本異步執行。

19.使用外部Javascirpt和CSS文件

使用外部Javascript和CSS文件可使這些文件被瀏覽器緩存,從而在不一樣的請求內容之間重用。

同時將Javascript和CSS從inline變爲external也減少了網頁內容的大小。

使用外部Javascript和CSS文件的決定因素在於這些外部文件的重用率,若是用戶在瀏覽咱們的頁面時會訪問屢次相同頁面或者能夠重用腳本的不一樣頁面,那麼外部文件形式能夠爲你帶來很大的好處。

但對於用戶一般只會訪問一次的頁面,例如microsoft.com首頁,那inline的javascript和css相對來講能夠提供更高的效率。

20.精簡Javascript和CSS

精簡就是將Javascript或CSS中的空格和註釋全去掉,

body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
複製代碼

精簡後版本

body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}
複製代碼

統計代表精簡後的文件大小平均減小了21%,即便在應用Gzip的文件也會減小5%。

例如個人網站上有5個CSS,4個Javascirpt,下面是分別通過bundling和minify以後的結果。

沒有任何處理以前

捆綁Javascript和CSS以後

精簡Javascript和CSS以後

圖片

21.優化圖像

當美工完成了網站的圖片設計後,咱們能夠在上傳圖片以前對其作如下優化

  • 檢查GIF圖片中圖像顏色的數量是否和調色板規格一致。若是你發現圖片中只用到了4種顏色,而在調色板的中顯示的256色的顏色槽,那麼這張圖片就還有壓縮的空間。

    可使用imagemagick檢查:identify -verbose image.gif

  • 嘗試把GIF格式轉換成PNG格式,看看是否節省空間。大多數狀況下是能夠壓縮的。

    能夠安全地把GIF格式轉換爲PNG格式:convert image.gif image.png

  • 在全部的PNG圖片上運行pngcrush(或者其它PNG優化工具)。

    例如: pngcrush image.png -rem alla -reduce -brute result.png

  • 在全部的JPEG圖片上運行jpegtran。這個工具能夠對圖片中的出現的鋸齒等作無損操做,同時它還能夠用於優化和清除圖片中的註釋以及其它無用信息

    jpegtran -copy none -optimize -perfect src.jpg dest.jpg

22.優化CSS Sprite

  • Sprite圖片中橫向排列通常都比縱向排列的最終文件小
  • Sprite中把顏色較近的組合在一塊兒能夠下降顏色數,理想情況是低於256色以便適用PNG8格式;
  • 不要在Sprite的圖像中間留有較大空隙。這雖然不大會增長文件大小,但對於用戶代理來講它須要更少的內存來把圖片解壓爲像素地圖。100×100的圖片爲1萬像素,1000×1000就是100萬像素。

23.不要在HTML中縮放圖片

不要經過圖片縮放來適應頁面,若是你須要小圖片,就直接使用小圖片吧。

24.使用小且可緩存的favicon.ico

網站圖標文件favicon.ico,無論你服務器有仍是沒有,瀏覽器都會去嘗試請求這個圖標。因此咱們要確保這個圖標

  • 存在
  • 文件儘可能小,最好小於1k
  • 設置一個長的過時時間

cookie

25.減小Cookie大小

Cookie被用來作認證或個性化設置,其信息被包含在http報文頭中,對於cookie咱們要注意如下幾點,來提升請求的響應速度,

  • 去除沒有必要的cookie,若是網頁不須要cookie就徹底禁掉
  • 將cookie的大小減到最小
  • 注意cookie設置的域級別,必要狀況下不要影響到其它子域
  • 設置合適的過時時間,比較長的過時時間能夠提升響應速度。

26.頁面內容使用無cookie域名

大多數網站的靜態資源都不必cookie,咱們能夠採用不一樣的domain來單獨存放這些靜態文件,這樣作不只能夠減小cookie大小從而提升響應速度,還有一個好處是有些代理拒絕緩存帶有cookie的內容,若是能將這些靜態資源cookie去除,那就能夠獲得這些代理的緩存支持。

常見的劃分域名的方式是將靜態文件放在static.example.com,動態內容放在www.example.com。

也有一些網站須要在二級域名上應用cookie,全部的子域都會繼承,這種狀況下通常會再購買一個專門的域名來存放cookie-free的靜態資源。例如Yahoo!的yimg.com,YouTube的ytimg.com等。

移動端

27.保持單個內容小於25KB

這限制是由於iphone,他只能緩存小於25K,注意這是解壓後的大小。因此單純gzip不必定夠用,精簡文件工具要用上了。

28.打包組建成符合文檔

把頁面內容打包成複合文本就如同帶有多附件的Email,它可以使你在一個HTTP請求中取得多個組件。當你使用這條規則時,首先要肯定用戶代理是否支持(iPhone不支持)。

服務器

29.Gzip壓縮傳輸文件

Gzip一般能夠減小70%網頁內容的大小,包括腳本、樣式表、圖片等文件。Gzip比deflate更高效,主流服務器都有相應的壓縮支持模塊。

值得注意的是pdf文件能夠從須要被壓縮的類型中剔除,由於pdf文件自己已經壓縮,gzip對其效果不大,並且會浪費CPU。

30.避免圖片src屬性爲空

空的圖片src仍然會使瀏覽器發送請求到服務器,這樣徹底是浪費時間,並且浪費服務器的資源。尤爲是你的網站天天被不少人訪問的時候,這種空請求形成的傷害不容忽略。

主要以兩種形式出現:

  • straight HTML

    <img src=」」>

  • JavaScript

    var img = new Image();
    
    img.src = 「」;
    複製代碼

31.配置ETags

雖然標題叫配製ETags,可是這裏你要根據具體狀況進行一些判斷。首先Etag簡單來講是經過一個文件版本標識使得服務器能夠輕鬆判斷該請求的內容是否有所更新,若是沒有就回復304 (not modified),從而避免下載整個文件。

可是Etags的版本信息即便主流服務器也未能很好地支持跨服務器的判斷,好比你從一個服務器集羣中一臺獲得Etags,而後發送到了另外一臺那麼校驗頗有可能會失敗。

32.使用GET的Ajax請求

瀏覽器在實現XMLHttpRequest POST的時候分紅兩步,先發header,而後發送數據。而GET卻能夠用一個TCP報文完成請求。另外GET從語義上來說是去服務器取數據,而POST則是向服務器發送數據,因此咱們使用Ajax請求數據的時候儘可能經過GET來完成。

33.儘早flush輸出

網頁後臺程序中咱們知道有個方法叫Response.Flush(),通常咱們調用它都是在程序末尾,但注意這個方法能夠被調用屢次。目的是能夠將現有的緩存中的回覆內容先發給客戶端,讓客戶端「有活幹」。

那在何時調用這個方法比較好呢?通常狀況下咱們能夠在對於須要加載比較多外部腳本或者樣式表時能夠提早調用一次,客戶端收到了關於腳本或其餘外部資源的連接能夠並行的先發請求去下載,服務器接下來把後續的處理結果發給客戶端。

34.使用CDN(內容分發網絡)

再次強調第一條黃金定律,減小網頁內容的下載時間。提升下載速度還能夠經過CDN(內容分發網絡)來提高。CDN經過部署在不一樣地區的服務器來提升客戶的下載速度。若是你的網站上有大量的靜態內容,世界各地的用戶都在訪問,那CDN是必不可少的。事實上大多數互聯網中的巨頭們都有本身的CDN。咱們本身的網站能夠先經過免費的CDN供應商來分發網頁資源。

35.添加Expires或Cache-Control報文頭

這條規則分爲兩個方面:

  • 對於靜態內容添加Expires,將靜態內容設爲永不過時,或者很長時間之後。在IIS中設置Expires能夠看Configure the HTTP Expires Response Header (IIS 7)。
  • 對於動態內容應用合適的Cache-Control,讓瀏覽器根據條件來發送請求。關於asp.net的caching,能夠看asp.net cache feature和asp.net caching best practices。

參考連接

相關文章
相關標籤/搜索