原文:Best Practices for Speeding Up Your Web Site
11 避免重定向 (Avoid Redirects)
tag:content
重定向結束于301或302狀态碼。這裡有一個301響應的HTTP頭的例子:
HTTP/1.1 301 Moved Permanently
Location: http://example.com/newuri
Content-Type: text/html
浏覽器會自動把使用者轉向Location域中指明的Url位址。HTTP頭裡包含了重定向所需的所有資訊。響應的主體一般是空的。301或者302響應都不會被實際緩存,除非添加額外的頭部,比如
Expires或者
Cache-Control指明了它應該被緩存。meta refresh标簽和JavaScript也可以将使用者重定向到不同的URL,但如果你必須執行重定向,最好的方法是使用标準的3XX HTTP狀态代碼,以便使後退按鈕工作正常。
需要謹記的是,重定向降低了使用者體驗。在使用者和HTML文檔之間插入的重定向延誤了頁面的呈現群組件下載下傳,因為它們都不可能在獲得HTML文檔之前開始。
一種最浪費性能的重定向頻繁發生而網絡開發者們卻往往沒有意識到,那就是當位址中應當有一個左斜線(/)卻沒有的時候。比如,通路http://astrology.yahoo.com/astrology會導緻一個301效應并重定向到http://astrology.yahoo.com/astrology/(注意這裡加了一個左斜線)。在Apache中,這可以使用mod_rewrite,或者在Apache事件進行中使用DirectorySlash指令來修補。
使用重定向的另一個常見場景是連接配接舊網站和新網站。還包括連接配接網站的不同部分,或者在不同情況下(比如依據浏覽器的類型,使用者的類型等)重定向使用者。使用重定向來連接配接兩個網站很簡單而且需要很少的額外代碼。雖然在這些情況下使用重定向減少了開發者的麻煩,但卻降低了使用者體驗。如果兩部分在同一個伺服器上,可以使用Alias 和rewrite來替代重定向。如果域名變更引起了重定向,可以建立一個CNAME(一種可以建立一個别名使一個域名指向另一個的DNS記錄)結合
Alias或者
mod_rewrite
來替代重定向。
12 移除重複的腳本 (Remove Duplicate Scripts)
tag:javascript
在同一個頁面中包含兩個相同的腳本檔案降低了性能。這并不如你想象的那麼罕見。在對美國十大網站中的檢查中,發現它們中的兩個包含了重複的腳本。有兩個主要因素增加了一個頁面包含兩個相同腳本的幾率——團隊的大小和腳本的數量。當腳本被重複包含時,由于增加了不必要的HTTP請求和JavaScript的執行,影響了性能。
不必要的HTTP請求在IE中存在,而Firefox終沒有。在IE中,如果一個外部腳本被包含了兩次而且沒有被緩存,在頁面加載的過程中會産生兩次HTTP請求。即使腳本被緩存了,當使用者重載頁面時,多餘的HTTP請求也會發生。
産生多餘的HTTP請求的同時,多次執行腳本也會浪費時間。在Firefox和IE中,無論是否被緩存,腳本都會被重複執行。
避免腳本被意外加載兩次的一個方法是在你的模闆系統中執行一個腳本管理子產品。通常的方式是在HTML頁面中使用SCRIPT标簽來添加一個腳本:
<script type="text/javascript" src="menu_1.0.17.js"></script>
PHP中,可以選擇建立一個叫做insertScript的方法:
<?php insertScript("menu.js") ?>
這個函數不僅僅能防止腳本被重複加載多次,還可以解決腳本的其他問題,比如獨立性檢測以及為腳本添加版本号碼以應對far future Expires頭部。
13 設定ETags (Configure ETags)
tag:server
實體标簽(ETags)是伺服器和浏覽器用于确定浏覽器中緩存的元件和伺服器中的是否對應的一種機制。("entity"是元件的另一種說法:圖檔、腳本、樣式表等等)添加ETags用于辨識元件提供了比單純利用“最後修改時間”更為靈活的機制。ETag是一個唯一辨別元件的特定版本的字元串。它的唯一格式規範是字元串必須被引号引用。來源伺服器使用ETag響應頭來設定一個元件的ETag:
HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195
當浏覽器晚些時候需要檢測一個元件時,它使用If-None-Match 頭部把ETag傳回來源伺服器。如果ETag比對了,會傳回一個304狀态碼,在這個例子裡它會減少12195個位元組的響應:
GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
If-None-Match: "10c24bc-4ab-457e1c1f"
HTTP/1.1 304 Not Modified
ETag的問題是它們往往在網站的一個伺服器中被設為唯一的,當浏覽器從一個伺服器得到了元件并在稍後試圖到另一個伺服器驗證時,ETag會不比對,而這在使用多個伺服器來處理請求的網站中是很常見的。預設情況下,Apache和IIS在ETag中嵌入的資料戲劇性的減少了應用多台伺服器的網站的ETag驗證成功幾率。
Apache1.3和2.新版本的ETag格式是inode-size-timestamp。雖然一個給定的檔案在多台伺服器中處于同一個目錄,而且有同樣的大小,權限,時間戳,但它的inode在不同伺服器中是不同的。
IIS5.0和6.0有同樣的問題。IIS中ETag的格式是Filetimestamp:ChangeNumber。ChangeNumber用來跟蹤IIS配置的改變次數。一個網站的所有IIS不可能有相同的ChangeNumber。
這導緻的結果是,Apache和IIS對完全相同的元件産生的ETag在不同伺服器間不能比對。如果ETags不比對,使用者不會得到小而快的304響應,而是一個普通的200響應群組件的所有資料。如果你把你的網站放在了一個伺服器裡,這不會是一個問題。但如果你的網站有多台伺服器,而且你使用了Apache和IIS預設的ETag配置,你的使用者會通路頁面的速度會變慢,你的伺服器加載的程度更高,消耗了更大的帶寬,代理伺服器不能有效的緩存你的内容。即使你的元件有一個ar future
Expires
頭部,當使用者重載或者重新整理頁面時,依然會發送一個GET請求。
如果你不打算利用ETags提供的靈活的驗證模式,你最好把ETag統統移除。Last-Modified頭部的驗證方式給予元件的時間戳。移除ETag同時減少響應和随後的請求中的HTTP頭部大小。這篇微軟的支援文檔描述了怎樣在IIS中移除ETags。在Apache中,你隻要在Apache配置檔案中添加如下一行:
FileETag none