原文地址https://www.ibm.com/developerworks/cn/web/wa-speedweb/?S_TACT=105AGX52&S_CMP=tec-csdn
使用良好的結構
可擴展 HTML (XHTML) 具有許多優勢,但是其缺點也很明顯。XHTML 可能使您的頁面更加符合標準,但是它大量使用標記(強制性的 <start>
和 <end>
標記),這意味着瀏覽器要下載更多代碼。所以,事情都有兩面性,嘗試在您的網頁中使用較少的
XHTML 代碼,以減小頁面大小。
如果您確實不得不使用 XHTML,試着儘可能對它進行優化。例如,刪除空格並採用嚴格的 XHTML 編碼實踐,提高下載和解析速度。要嚴格執行 XHTML Strict 規則,向文檔中添加以下 doctype
語句:
1
2
|
<!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
XHTML 1.0 Strict 與 Strict HTML 4.01 是等效的,包含的屬性和元素沒有出現在 HTML 4.01 規範的反對內容中。記住,有兩個標記能夠在 XHTML Transitional 中使用,但不能在 XHTML Strict 中使用,例如:
-
<center>
-
<font>
-
<iframe>
-
<strike>
-
<u>
不要使佈局超載
在博客(和新的站點)流行起來之前,讓頁面水平滾動甚至垂直滾動被認爲是糟糕的實踐。頁面越小,越難以(但並不是不可能)完好地填充屏幕。現在,對於博客和內容驅動的網站,不時可以看到幾百 Kb 大小的長頁面。是的,您需要填充更多空間,但是這並不意味着您必須使用大的背景圖像、大量表格或者許多內容來填充。堅持簡約原則:少即是多。頁面中充斥着各種類型的圖像、視頻、廣告等,這大大違背實用性原則,因此,在增加頁面的內容時請三思。
不要使用圖像來表示文本
我們很少會控制字體在不同瀏覽器中的顯示方式,與字體不同的是,圖像總是精確地按照其設計方式來顯示。但這不能當作使用圖像來表示文本的藉口。
使用圖像表示文本的最常見示例就是在導航欄中。美觀的按鈕更加具有吸引力,但是它們的加載速度很慢。此外,圖像仍然不能由搜索引擎直接索引,因此,使用圖像進行導航不利於搜索引擎優化(search engine optimization,SEO)。當無需圖像就可以通過大量 CSS 技巧創建漂亮的按鈕時,絕不使用圖像來表示文本。
一種適用於 CSS 樣式的特定導航類型就是選項卡式導航,如 圖 3 所示。
圖 3. 選項卡式導航
除了體積較小之外,這種實現導航的方式也更加符合 Web 標準。
清單 1. 基於選項卡導航的 CSS 文檔清單 1 和 清單 2 中的代碼以純 CSS/XHTML 的形式實現基於選項卡的導航功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#nav
{ float:left; width:100%; background:#E7E5E2; font-size:95%; line-height:normal; border-bottom:1px
solid #54545C; } #nav
ul { margin:0; padding:10px
10px 0 50px; list-style:none; } #nav
li { display:inline; margin:0; padding:0; } #nav
a { float:left; background:url("tableftK.gif")
no-repeat left top; margin:0; padding:0
0 0 4px; text-decoration:none; } #nav
a span { float:left; display:block; background:url("tabrightK.gif")
no-repeat right top; padding:5px
15px 4px 6px; color:#FFF; } /*
Commented Backslash Hack hides rule from IE5-Mac \*/ #nav
a span {float:none;} /*
End IE5-Mac hack */ #nav
a:hover span { color:#FFF; background-position:100%
-42px; } #nav
a:hover { background-position:0%
-42px; } #nav
a:hover span { background-position:100%
-42px; } |
清單 2. 基於選項卡導航的 HTML 代碼
1
2
3
4
5
6
7
8
9
|
< div id = "nav" > < ul > < li >< a href = "#" title = "Link
1" >< span >Link
1</ span ></ a ></ li > < li >< a href = "#" title = "Link
2" >< span >Link
2</ span ></ a ></ li > < li >< a href = "#" title = "Link
3" >< span >Link
3</ span ></ a ></ li > < li >< a href = "#" title = "Longer
Link Text" >< span >Longer
Link Text</ span ></ a ></ li > < li >< a href = "#" title = "Link
5" >< span >Link
5</ span ></ a ></ li > </ ul > </ div > |
檢查 cookie 使用情況
cookie 可能是很小的文件,但是瀏覽器仍然需要下載它們。較大的 cookie 所需的下載時間更長,進而增加了瀏覽器加載網頁的時間。正因爲如此,儘可能縮小 cookie 來最小化對瀏覽器響應時間的影響非常重要。
此外,設置一個較早的 expire
日期或者根本不設置 expire
日期,會縮短響應時間。要在
PHP 語言中設置 cookie 的 expire
日期,使用以下代碼:
1
2
3
4
5
|
<? php $ expire =
2592000 +
time(); //
Add 30 day’s to the current time setcookie(userid,
“123rrw3”, $expire); ?> |
這段代碼設置 cookie userid
,並將 expire
日期設置爲自當前日期之後
30 天。
不要包含不必要的 JavaScript 代碼,儘可能將其外部化
與 cookie 類似,JavaScript 文件的下載也需要時間,這不可避免地會降低整個頁面的加載速度。因此,明智地使用 JavaScript(僅在真正必要時才使用)並優化腳本的大小和速度。
縮短 JavaScript 下載時間的另一種方式是使用外部文件,而不是包含腳本內聯。這種方法也適用於 CSS,因爲瀏覽器會緩存外部化的文本,而(在 HTML 頁面自身中)以內聯方式編碼的 CSS 或 JavaScript 每次都會隨 HTML 一起加載。要通過在 HTML 中引用 CSS 和 JavaScript 代碼來外部化它們,可以使用具有以下形式的代碼:
1
2
|
< link href = "/stylesheets/myStyle.css" media = "all" rel = "Stylesheet" type = "text/css" /> <script
src="/javascripts/myJavascript.js" type="text/javascript"> </script> |
儘可能避免使用表格
表格被用作網頁的主要構建塊,但是作爲頁面佈局元素,使用表格現在被認爲是糟糕的做法。有時候,您必須使用表格(並且它們被認爲是顯示錶格數據的出色實踐)。如果是這樣,明確地指定表格單元格、行和列的寬度和高度,否則,瀏覽器必須執行許多操作來計算如何顯示它們,這會降低頁面加載速度:
1
|
< td width = "50px" height = "10px" >...</ td > |
刪除任何不必要的元素
可能這是所有技巧中最顯而易見的一個,但是它也是最容易忘記的一個技巧。我曾經提到過 “少即是多”:這不僅是爲了真正吸引更廣泛的用戶,還意味着需要下載和處理的東西更少。如果您真正需要在網頁上放置許多內容,考慮將網頁分爲 2 個、3 個或更多的獨立頁面。
一些優化網頁的技巧
可以使用許多方法來優化您的網頁,包括壓縮 JavaScript 文件,使用超文本傳輸協議(Hypertext Transfer Protocol,HTTP)壓縮,以及設置圖像大小。
壓縮和縮小 JavaScript 文件
JavaScript 文件可能非常大,這意味着在某些情形中,它們的下載時間可能比所有其他組件下載時間之和還長。解決此問題的一種方法是壓縮 JavaScript 文件。您可以使用 GNU zip (gzip) 來完成此任務,因爲許多瀏覽器都支持這種壓縮算法。
另一種替代方法是縮小文件。這種方法刪除代碼中所有不必要的字符,比如製表符(tab)、新行和空格。它刪除代碼中的註釋和空白,進一步縮小文件大小。外部和內部樣式表都可以縮小。兩種最流行的縮小工具是 JSMin 和 YUI Compressor(參見 參考資料)。
使用 HTTP 壓縮,並始終使用小寫的 div 和類名
可以使用 HTTP 壓縮來減少服務器與瀏覽器之間的通信量。可以在 Apache 中配置 HTTP 壓縮(.htaccess 文件),或者可以將其包含到頁面中(對於 PHP,可以使用一個 HTTP_ACCEPT_ENCODING
選項)。但是請注意:不是所有瀏覽器都支持壓縮。即使是支持壓縮的瀏覽器,壓縮和解壓縮都會加重處理器的負載。要在
Apache 中啓用地毯式(blanket)壓縮(即壓縮所有文本和 HTML),使用以下命令:
1
|
AddOutputFilterByType
DEFLATE text/html text/plain text/xml |
另外,考慮一下您想要壓縮的內容。圖像、音樂和視頻在創建時已經進行了壓縮,因此您可以將壓縮對象限制爲 HTML、CSS 和 JavaScript 文件。
另一種減少壓縮工作的技巧是使用小寫形式的 <div>
元素和類名。由於大小寫敏感性,並且使用的是無損壓縮,<header>
與 <Header>
不同,它們被壓縮爲兩個不同的標記。在下面的例子中,對於壓縮程序來說,Important
類與 important
類是不同的,這意味着對於壓縮程序,它們表示不同的對象,因此被分別壓縮爲兩段不同的文本。
1
2
|
< div class = "Important" >read
this!</ div > < div class = "important" >This
will cost you some valuable load time</ div > |
留意細節似乎無關緊要。但是當您優化文件時,所有細微的細節都應考慮在內。
設置圖像大小
與表格單元格、行和列一樣,當您未明確設置圖像大小時,瀏覽器需要執行計算來顯示圖像,這會降低處理速度。此外,在某些情形下,圖像大小的計算結果可能不正確,因此圖像會發生變形。
將 CSS 圖像映射用於裝飾功能
使用圖像映射代替多個圖像,這是另一種縮短加載時間的方式,因爲同時下載圖像的各個獨立部分能夠加快整個頁面的下載進度。或者,您可以使用某種名爲 CSS sprites 的工具(參見 參考資料)。CSS sprites 可幫助減少 HTTP 請求的數量。一個圖像可以包含裝飾或佈置頁面所需的所有圖像元素。您使用 CSS 來選擇(通過調用某些位置和維度)用於特定元素的映射。
儘可能延遲腳本加載
我 在前面 提到過,移除完全不需要的 JavaScript 代碼能夠加快加載和處理速度。但是如果代碼已經非常精簡併且必須在頁面中包含 JavaScript 代碼的話,該怎麼辦?
在這種情形下,一種提升頁面下載速度的潛在方式是將腳本放在頁面的底部,使頁面加載更迅速。通常,瀏覽器只能(從同一個域)下載不超過兩個並行對象,如果一個對象是一段 JavaScript 代碼,那麼在該腳本下載完之前,其他頁面組件的下載將會暫停。如果將 JavaScript 代碼放在頁面底部,(在大多數情況下)它將在最後下載,這時所有其他組件都已下載完。
使用 Firebug 擴展跟蹤加載緩慢的文件,我敢打賭您的 JavaScript 文件是下載最慢的文件。壓縮 JavaScript 文件會有所幫助,但是僅僅這樣可能還不夠。您可以使用以下代碼片段延遲 JavaScript 的加載:
1
2
|
var
delay = 5; setTimeout("heavy();",
delay * 1000); |
這段代碼將對 heavy()
方法的調用延遲了 5 秒。您可以將這段代碼與下面的技巧結合使用來延遲整個 JavaScript
文件的加載。
按需加載 JavaScript 文件
要按需加載 JavaScript,使用 import() 函數,如 清單 3 所示。
清單 3. import() 函數
1
2
3
4
5
6
7
8
9
10
11
12
13
|
function
$import(src){ var
scriptElem = document.createElement('script'); scriptElem.setAttribute('src',src); scriptElem.setAttribute('type','text/javascript'); document.getElementsByTagName('head')[0].appendChild(scriptElem); } //
import with a random query parameter to avoid caching function
$importNoCache(src){ var
ms = new Date().getTime().toString(); var
seed = "?" + ms; $import(src
+ seed); } |
驗證函數加載
也可以驗證一個函數是否被加載,如果沒有,加載 JavaScript 文件。爲此,使用 清單 4 中的代碼。
清單 4. 驗證函數是否被加載
1
2
3
4
5
6
|
if
(myfunction){ //
The function has been loaded } else{
// Function has not been loaded yet, so load the javascript. $import('http://www.yourfastsite.com/myfile.js'); } |
注意:可以使用 defer
屬性,但不是所有瀏覽器(包括
Firefox)都支持它。
優化 CSS 文件
如果經過適當優化和維護,CSS 文件不一定很大。例如,具有很多獨立類的 CSS 文件會影響下載速度。與 JavaScript 文件一樣,您需要優化 CSS 文件,使其包含所需的所有內容,同時保持合理的大小。另外,使用外部文件代替內聯定義來適應瀏覽器的緩存機制。
使用內容分佈網絡
內容分佈網絡(Content-distribution network,CDN)是另一種縮短下載時間的好方法。當您將靜態圖像放在 Internet 上的許多服務器上時,用戶能夠從離他們最近的服務器下載這些圖像。此外,大多數 CDN 都在快速服務器上運行,因此無論服務器的加載速度如何,其響應速度都比小型的超載服務器快。
對資產使用多個域來增加連接
CDN 的另一個優勢是它們是獨立的域。因爲您的瀏覽器將併發連接的數量限制到一個單一的域,因此無論何時加載一個頁面,都很容易佔滿所有線程。因此,到其他資產的連接被延遲了。然而,您的瀏覽器能夠打開新線程或到其他域的連接,這樣,從另一個域加載的任何資產都可以與其他所有資產同時加載。
在合適的時候使用 Google Gears
使用 Google Gears(參見 參考資料)是避免用戶反覆下載同一內容的另一種好方法。Gears
允許用戶離線訪問 Web 應用程序,但是也允許將頁面元素持久化到用戶的計算機上。因此,頻繁加載但未進行更新的內容可以存儲在 Gears 數據庫中,該數據庫是一個 SQLite3 關係數據庫管理系統。對同一內容的所有 next
請求都可以從數據庫(而不是服務器)直接加載。
安裝 Gears 之後,獲取 gears_init.js 文件,以便輕鬆訪問 Gears 工廠和應用程序編程接口(API),將其保存爲 gears_init.js,通過以下方式在您的代碼中引用它:
1
|
<script
type="text/javascript" src="gears_init.js"> </script> |
要確定是否已安裝 Gears,使用 清單 5 中的代碼。
清單 5. 確定是否已安裝 Gears
1
2
3
4
5
6
|
<script> if (!window.google
|| !google.gears) { location.href
= "http://gears.google.com/?action=install&message=<welcome
message>" + "&return=<return
url>" ; } </script> |
如果未安裝 Gears,代碼將向您提供下載 Gears 的 URL。
當所有元素都通過驗證並且 Gears 已安裝之後,您可以測試 Gears 的極其有用的數據庫功能,使用 清單 6 中的 JavaScript 代碼。
清單 6. 測試數據庫功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<script
type="text/javascript"> var db
= google.gears.factory.create( 'beta.db' ); db.open( 'database-test' ); db.execute( 'create
table if not exists Test'
+ '
(Phrase text, Timestamp int)' ); db.execute( 'insert
into Test values (?, ?)' ,
[ 'Monkey!' , new Date().getTime()]); var rs
= db.execute( 'select
* from Test order by Timestamp desc' ); while (rs.isValidRow())
{ alert(rs.field(0)
+ '@' +
rs.field(1)); rs.next(); } rs.close(); </script> |
這段代碼在您的計算機或服務器上創建一個本地數據庫 db。如果表 Test 不存在,則創建一個,然後插入測試數據(Monkey! 和時間)。代碼從數據庫獲取數據,並在瀏覽器中以警告的形式呈現出來。
想像一下可能發生的結果!
使用 PNG 格式的圖像
Graphic Interchange Format (GIF) 和 Joint Photographic Experts Group (JPEG) 圖像格式都已過時了:Portable Network Graphic (PNG) 是未來流行的格式。當然,您可以說 GIF 和 JPEG 已經消亡,或者 PNG 沒有任何缺陷,但是所有事物都有各自的優缺點,PNG 以最佳的文件大小提供了出色的質量。因此,如果進行選擇的話,應該儘可能使用 PNG 圖像。
保持 Ajax 調用簡短、準確
當統稱爲 Asynchronous JavaScript + XML (Ajax) 的技術在兩年前出現時,這些技術爲處理頁面請求和響應提供了一種革命性方法。然而,撥號用戶可能從來沒機會體驗其真正的優勢,因爲在許多情形下,Ajax 需要在瀏覽器與服務器之間大量通信。因此,如果您能夠保持 Ajax 調用簡短和準確,可以避免用戶花費無止盡的時間來等待元素刷新或響應。
進行一次較大的 Ajax 調用並在本地處理客戶機數據
如果不能進行簡短的 Ajax 調用,或者如果這些調用不能提供期望的結果,可以考慮一種替代方法:進行一次大的 Ajax 調用來獲取所需的一切內容,然後讓客戶機在本地處理數據。通過這種方式,客戶機只需等待一次(獲取傳入的數據),但是在此之後(當瀏覽器與服務器之間沒有必要通信時),處理速度將更快。當然,還有大量 Ajax 優化技術,本教程無法一一列出。如果想要了解關於 Ajax 的更多信息,請查看 參考資料。
在沙箱中測試代碼
還有一個經常被遺忘的常用技巧。儘管清醒的 Web 開發人員通常會在啓動應用程序之前對其進行測試,但是有時候測試會使他們不那麼重視維護任務,或者新功能添加得太快,並且未經過充分考慮或測試。結果,餘下的腳本減緩了應用程序的速度。
如果您添加一項新功能,可以首先在沙箱裏(完全脫離了應用程序的其餘部分)進行測試,查看它作爲單個函數的行爲。通過這種方式,您可以反覆檢查,並分析性能和響應時間,無需考慮 Web 應用程序的其餘部分。然後,當新功能的行爲符合預期時,可以將其引入到應用程序的其餘部分中,運行其他測試,保證功能本身的行爲符合預期。
分析站點代碼
在許多場景中,自我反省是一個不錯的建議。幸運的是,在開發過程中,我們可以使用工具來幫助反省,並儘可能客觀地進行實踐。像 JSLint(參見 參考資源)這樣的工具的價值是無法衡量的,儘管其站點宣稱它 “可能令您備受挫折”,因爲它向您提供了所有的潛在代碼缺陷,這些缺陷不但使調試更加困難,而且可能導致更長的響應時間。
使用 JSLint 檢查 JavaScript 代碼中的錯誤或糟糕的編碼實踐
您不需要像完美主義者那樣追求完美無缺的 JavaScript 代碼。但是,許多開發人員沒有認真對待代碼分析,通常在開發過程中跳過了這個步驟。不幸的是,錯誤和糟糕的編碼實踐不僅不太專業,而且可能減緩應用程序的速度。當瀏覽器忙於應付錯誤和糟糕的編碼實踐時,加載不僅需要更多時間,還會導致難以調試的錯誤。
因此,如果想要獲得良好的代碼,可以考慮使用代碼分析工具。有許多不同的工具可供使用,但是最適合 JavaScript 語言的工具非 JavaScript Lint 莫屬,它也叫做 JSLint(參見 參考資料)。也可以使用 Firebug,但是 JSLint 更加正式,它包含在 YSlow 中。
檢查孤立的文件和丟失的圖像
檢查孤立的文件和丟失的圖像是一種明智之舉。大部分 Web 開發人員都會檢查錯誤的文件引用,但是這裏仍然需要說明一下。丟失的文件容易引起各種問題,因爲它們會導致 “The image/page cannot be displayed” 之類的錯誤消息。但是在網頁速度優化方面,它們具有更大的缺陷:當瀏覽器尋找丟失的或孤立的文件時,它會消耗資源,這不可避免地會導致頁面處理速度變慢。因此,請檢查孤立或丟失的文件,包括拼寫錯誤的文件名。