一個end user 下載html通常只佔總時間的 10~20%,其他80~90%的時間,都在下載相關的library,component,image,所以我們要想辦法減少這些 library 的下載與載入時間 。
Http Request
Http request類型有 GET,POST,HEAD,DELETE,PUT,OPTIOS,TRACE,其中最常用到的就是 Get and POST,這裡就給一個 Http Get Request 的範例。
- //Http request example
- Get /index.html HTTP/1.1
- Host www.yahoo.com.tw
- User-Agent Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1
- Accept-Encoding gzip, deflate
- //Http response example
- HTTP/1.1 200 OK
- Content-Type: application/x-javascript
- Last-Modified: Wed, 23 Jan 2011 05:05:15 GMT
- Content-Length: 255
- Content-Encoding: gzip
- http request & response 壓縮
- Accept-Encoding: 代表 browser 可接收的壓縮方式
- Content-Encoding: 代表Web伺服器的壓縮方式
Cache (http status : 304 Not Modified)
Browser會自動檢查目前要 Request 的 file 是否已有cache,若是已經有cache file,而且尚未過期,Browser 就會詢問伺服器, Request file是否需要更新,這裡有兩個比對是否需要更新的機制,Expired Date 和 Etag ,我們先來看看 check Cache 的Request and Respose吧。
- // Request Example
- GET /xxx.css HTTP/1.1
- Host: www.yahoo.com.tw
- User-Agent: Mozilla/5.0 ...
- If-Modified-Since: Sun, 23 Oct 2011 09:32:39 GMT
- If-None-Match: "60034-24c6-4aff3fcc2382d"
- Cache-Control: max-age=0
- // Response Example
- HTTP/1.1 304 Not Modified
- Date: Mon, 31 Oct 2011 15:52:07 GMT
- Server: Apache/2.2.19 (Unix) PHP/5.2.17
- Etag: "60034-24c6-4aff3fcc2382d"
- Expires: Thu, 10 Nov 2011 15:52:07 GMT
- Cache-Control: max-age=864000
- Expires : Browser 會送出 If-Modified-Since 時間,去伺服器比對是否要有過期,若是時間沒有過期,伺服器會回傳 「304 Not Modified 和 新的 Expires」,代表檔案沒有更新,Browser就會直接讀取本機端的暫存檔。
- Etag : 這是一個不重覆的字串,就相當於 url 的版本,當版本未更新,Browser就不需要下載新的 file 。當 Request 發生,Browser會先送出目前url 的 Etag,並使用 If-Modified-Since方式傳給伺服器,伺服器比對後,若是檔案沒有更新,就會回傳「304 Not Modified」,Browser就會直接讀取本機端的暫存檔,
keep-alive : Persistent Connections
Http Request 有一個語法是 Connection:keep-alive ,因為早期的Browser 一 Http Request 必須建立一個 Socket Connection,後來發展一個比較有效率的Request方式,可以讓多個 Request 透過同一個 Socket來傳輸,這就是connection keep-alive。
- Connection:keep-alive 可以告訢server保持永久連線,直到timeout。
- Browser 可以傳送Connection: close 指令,close socket connection。
- Pipelining : 是指多個 Http request同時在一個socket 上傳輸,並且沒有先來後到的順序, request 和 response 同時進行,不過通常伺服器會有限制一個 connections的 request上限。
- //連續傳送多個 Request
- GET /image1.jpg HTTP/1.1
- Host: www.yahoo.com.tw
- Connection: Keep-Alive
- GET /image2.jpg HTTP/1.1
- Host: www.yahoo.com.tw
- Connection: Keep-Alive
- GET /image3.jpg HTTP/1.1
- Host: www.networkerror.org
- Connection: Keep-Alive
- Connection: Close
把Scripts放在網頁html最下方
brower 下載 script時,動作和下載圖片不一樣,圖片可以一次下載很多張,因為沒有順序的問題,但是script必須按照順序一個一個下載並執行,所以當browser碰到script時,網頁就得停下來等他,解決辦法就是把 script 語法放在網頁的最下面顯示。
手動壓縮 JS , css
Javascript 與 CSS 這兩種檔案都是純文字檔,因為是單純的文字檔,所以這是可以事先壓縮的,縮小後的檔案有利於線上傳輸,可以減少網路傳輸的時間,不過若你是使用自我解縮的方式,壓縮 Javascript 的話,解壓的時間也要算到效能喔,目前網頁的瓶頸,大多是網路傳輸最慢,所以不太需要考慮解壓的時間,到是 JQuery 不知他加壓的方式為何,竟然碰到解壓時間大於傳輸時間。
Javascript & CSS 壓縮工具如下
- YUI Compressor: http://yui.github.io/yuicompressor/
- Google Closure : https://developers.google.com/closure/
只能對 Javascript 壓縮的工具
- Packer: http://jscompress.com/
只能對 CSS 壓縮的工具
- cssmin: http://cssminifier.com/
伺服器 GZip , deflate
大部分的網頁伺服器都有支搜 GZip 檔案壓縮工具,每次伺服器將網頁內容回應給 Browser 時,都會先進行壓縮,然後 Browser 再解壓縮。
Browser 在發出 Request 時,在 HTTP Header 會加上 「accept-encoding: gzip,deflate」,這句的意思是代表說,Browser 可以支援的壓縮模式有 gzip 與 deflate ,而伺服器看到這個 Header 之後,就會選擇一個最佳的方式來壓縮。
如果你是使用 Apache Web Server ,又想要支援 gzip , deflate 等等的壓縮方式的話,你必需先確認有安裝以下的 Module 。
- mod_gzip
- mod_deflate
DNS resolve
前端頁面需要去下載 CSS., JS, 圖片還有 AJAX Request ,這些網址的 Domain 如果不同於主網站,那麼瀏覽器就會先去對各個不同的 Domain 做一次 DNS Resolve,去取得每個 Domain 的 IP ,這個動作也是很花時間的,我們可以在 HTML Head 加上 dns-prefetch ,讓瀏覽器提早做 DNS Resolve 這件事。