MSDN Magazine > Home > All Issues > 2008 > 十一月 >  公用程式焦點:使用 Visual Round Trip Analyzer 加快網頁速度的 12...
公用程式焦點
使用 Visual Round Trip Analyzer 加快網頁速度的 12 個步驟
Jim Pierson

本文是根據 VRTA 的搶鮮版所撰寫。本文包含的所有資訊均有可能變更。

本文討論下列主題:
  • 剖析資料的來回作業
  • 加快網頁速度的秘訣
  • Visual Round Trip Analyzer
本文使用下列技術:
Visual Round Trip Analyzer
有非常多的因素會影響網頁的效能,包括伺服器與用戶端的距離、網頁項目的大小、瀏覽器載入這些項目的方法,以及可用的頻寬。要找出這些瓶頸和揪出禍首並不容易。不過,找出原因確實可以使效能獲得明顯的改善。
在本文中,我將告訴您如何找出並矯正一些造成效能不彰的常見原因。我也會介紹 Visual Round Trip Analyzer (VRTA),這個工具可以分辨各種造成效能問題的因素,然後以圖形來呈現。接著,我會教您如何使用 VRTA 來執行分析。但是,在開始之前,請先回答本文中的快速測驗:「如何改善網頁載入的速度?」,以了解您目前的程度。

位置決定一切
造成網頁載入延遲的兩個最大因素,就是用戶端與伺服器之間的距離 (以來回時間 (RTT) 表示),以及來回的次數。來回作業是指一個網路封包從用戶端傳送到伺服器,再由伺服器回傳一個回應封包。如果一個網頁的內容很簡單,則此網頁的下載過程可能只需要來回 2、3 次,但如果網頁的外觀很複雜,則可能需要來回數十次。開啟 TCP 連線需要來回一次。傳送 Get 並接收最前面的 3KB 也需要來回一次。傳送更多資料的「認可」則需要多次來回。
如果使用者所在位置接近網站資料中心,假設距離在幾百哩之內,例如洛杉磯的使用者連線到矽谷的伺服器,則來回時間 (RTT) 只要 20 毫秒 (.020 秒),這不算是會影響網頁載入時間的重要因素。在這樣的情況下,即使用戶端與伺服器之間需要來回 50 次,網頁的載入時間也只會有 1 秒的網路延遲,但這尚未加計任何伺服器時間 (50 RT × 20 毫秒 = 1 秒)。
如果是位於歐洲或亞洲的使用者連線到同樣是矽谷的那一部伺服器,情況可就不同。目前,從加州到日本和英國的來回時間至少要 120 毫秒。相對於需要數百毫秒且要重複許多次的來回時間,相較於每一個要求的伺服器磁碟搜尋時間 (通常小於 10 毫秒),距離和來回次數很明顯就是造成網頁載入時間冗長的最重要因素。
為了克服長時間來回的影響,您可以試著採取三種主要的解決方案:您可以盡量以平行方式處理並去除額外負荷來減少序列式來回的次數,還可以將所在位置移至較靠近使用者的位置來縮短來回時間,或者,您也可以縮短伺服器的作業時間。
若要分析效能,以視覺化的方式準確地呈現網頁下載時的實際流量是很重要的。例如,若沒有視覺化,很難看出網頁的哪些部分是以序列的方式下載,以及哪些部分是以平行的方式下載。通常會以瀑布式的視覺方式來呈現檔案的下載 (如 [圖 1] 所示),報告中每一列代表一個檔案。但是,這樣的表達方式並未考量到自 HTTP1.1 起,會重複使用 TCP 連線的事實。保持連線開啟並在現有連線上呼叫其他檔案,可以減少來回次數,但在傳統的瀑布式圖表中,很難看出這一點。為了更準確呈現網頁實際載入的情形,您需要在圖片中加入 TCP 通訊埠當作做維度。
\\msdnmagtst\MTPS\MSDN\issues\en\08\11\Pierson - FasterWeb.1108\figures\fig01a.gif
圖 1 HTTP1.0 瀑布式圖表
[圖 2] 顯示七個 TCP 通訊埠 (以灰色水平線表示) 載入檔案的情況,以及已經過的毫秒數。彩色橫條代表檔案;紅色代表 HTML 文字,金色代表樣式表,深黃褐色代表 JavaScript、藍色線條則代表影像。最初會開啟一個通訊埠,接著再開啟其他兩個通訊埠。載入第一批檔案 (CSS) 之後,會透過相同的通訊埠載入其他檔案 (JavaScript 和影像)。
\\msdnmagtst\MTPS\MSDN\issues\en\08\11\Pierson - FasterWeb.1108\figures\fig02b.gif
圖 2 HTTP1.1 持續作用
VRTA 會在 Microsoft Network Monitor (簡稱 NetMon) 3.2 封包分析程式之上運作,不過,您不必去了解如何使用 NetMon。在這個工具的最新版本中 (即將公開發行),全球效能 (Global Performance) 團隊已加入檔案和封包的視覺化詳細資料。[圖 3] 顯示這些詳細資料。在建立 TCP 連線之後,粉紅色網底線條顯示從伺服器傳回的 TCP 回應封包。灰色線條代表從伺服器傳回第一個位元組的時間,階梯則指出使用 TCP 緩慢啟動時的回應封包增加情形。
圖 3 檔案和封包的詳細資料

12 個簡單的步驟
通常都以為網頁一定是以最快速度下載,且較多位元組只會減緩網頁的速度。但事實上,除非使用者很靠近資料中心,否則瀏覽器幾乎不會使用所有可用的頻寬。以下有 12 個步驟,可讓您減輕問題的影響。
1. 開啟足夠的通訊埠 瀏覽器與應用程式都會限制可同時開啟的通訊埠數目。Internet Explorer 7.0 以及較舊的版本中,會將每個網域的 HTTP1.1 通訊埠數目限制為兩個。例如,msn.com 只能使用兩個通訊埠。如果您將所有靜態 JavaScript、CSS 及影像全部裝載在一個網域中,如 [圖 4] 所示,舊版的瀏覽器仍然只會開啟兩個通訊埠。將內容分散到多個網域上,可讓瀏覽器開啟更多通訊埠。另外,也可以修改瀏覽器來開啟更多通訊埠。Internet Explorer 團隊目前正在考慮這種做法。
網頁通常會在下載單一檔案時遭遇瓶頸,如果是一連串相繼的單一檔案,則情況會更槽。理論上,一個網頁會同時載入六到八個檔案。請看一下 [圖 4] 中的位元速率圖。在圖中,您可以看到前三秒的流量非常少。在 [圖 5] 中,圖表左上角的橘色檔案是 SSL 信號交換。矩形框內會指出封包流量,我稍後會再詳細討論。如果您在圖上由左往右看,並計算各個時間點所下載的檔案數目,就會發現開始下載三秒之後,才會開始並行載入多個檔案。SSL 會先開始,接著連續載入其他兩個紅色 HTML 檔案,最後才使用六個通訊埠來載入九個檔案。
\\msdnmagtst\MTPS\MSDN\issues\en\08\11\Pierson - FasterWeb.1108\figures\fig04a.gif
圖 4 有許多小檔案,而通訊埠太少
\\msdnmagtst\MTPS\MSDN\issues\en\08\11\Pierson - FasterWeb.1108\figures\fig05a.gif
圖 5 並行通訊埠
2. 限制要下載的小檔案數目 傳送許多小檔案時,不容易充分利用整個廣域網路 (WAN) 的頻寬。[圖 4] 說明在整個網頁載入過程中的這種情形,尤其是在第十秒之後。這些圖示影像檔案全部都小於 500 個位元組。如果從使用者到伺服器的來回時間 (RTT) 為 200 毫秒,且每一個檔案需要來回一次,則每秒只能載入其中的五個檔案 (5 個檔案/秒 × 500 個位元組/檔案 × 8 個位元/位元組 = 每個 TCP 通訊埠 20Kbps)。
如果將小檔案合併成大檔案,則在每一次來回時即可傳送更多位元組。對於影像來說,這叫做影像叢集化 (Image Clustering) 或使用 Sprite。單一檔案中會有許多並排的影像一起下載,然後再裁剪這些影像,以放到網頁上。以下是此概念的實際範例:我們之前在發表 Windows 2000 時,有使用者報告從 Remond 下載德文版的升級套件需要六個小時。我的分析發現,有 30,000 個小檔案是以每次一個檔案的方式傳送。我將這些檔案全部壓縮成單一檔案之後,結果在 35 分鐘內就下載完成。
3. 在 JavaScript 引擎之外載入 JavaScript 檔案 執行 Internet Explorer 7 及較舊版本的瀏覽器,在遇到 JavaScript 檔案時會停頓。這些瀏覽器通常會以所謂的推測模式,盡快下載檔案。但在遇到 JavaScript 時,瀏覽器會脫離這種模式來專程下載 JavaScript。如果您曾經在 VRTA 中看過這種情形,會發現 JavaScript 檔案都沒有重疊,且很少有其他類型的檔案會同時下載。
有一種解決辦法是將 JavaScript 檔案的下載挪到最後,但這樣一來,反而錯失了有大量頻寬可用的情況。更好的解決方案是使用 Document Write 來處理檔案,在 JavaScript 引擎之外將檔案載入瀏覽器中,如下所示:
function AsyncLoad()
{
var l = arguments.length;
for (var i=0;i<l;i++)
{
document.write("<script src='" + arguments[i] + "'></" + "script>");
}
}
AsyncLoad(
"file1.js",
"file2.js",
"file3.js");
我們認為 Internet Explorer 8.0 將會解決這個問題。
4. 啟用持續作用 開啟一個 TCP 通訊埠會使用一次來回,取得一個檔案至少也要用到一次來回。如果您讓連線持續開啟著來處理更多檔案,則可以減少來回次數,並提高傳送量的效率。在 [圖 6] 中,請注意每個 TCP 連線 (灰色水平線) 只有一個通訊埠。位元速率只會在碰到大檔案時才暴增。在每一個檔案矩形框內,您可以看到回應量增加所形成的階梯模式。
\\msdnmagtst\MTPS\MSDN\issues\en\08\11\Pierson - FasterWeb.1108\figures\fig06b.gif
圖 6 持續作用
這是 TCP 的緩慢啟動演算法在發揮作用,每一次成功來回時都可以傳送更多位元組。這就是大檔案的傳送速度比較快的原因。重複使用 TCP 連線可讓後續的檔案繼續利用已擴大的視窗大小,而不必重頭再來一次。根據預設,IIS 中會啟用「持續作用」,除非您只裝載一個檔案,否則應該永遠保持啟用。
5. 識別網路擁塞的問題 您必須區別伺服器的延遲和網路的延遲。查看 TCP 連線時間或尋找重新傳輸的情形,通常可以發現網路延遲。在 [圖 7] 的差異欄中,您可以看到封包之間的時間差 (以毫秒為單位)。用戶端傳送的第一個封包,是開啟連線的 TCP 要求 ([圖 7] 中的 Frame 67)。經過 2914 毫秒 (2.9 秒) 之後,因為沒有收到來自伺服器的回應,所以用戶端又重送要求 (圖中的 Frame 306)。送出第二次要求之後,伺服器在 110 毫秒之後回應 (Frame 307)。
圖 7 封包之間的時間
有趣的是,TCP 連線封包會以指數原則來重新傳輸,而連線內的資料封包則會迅速地重新傳輸。因此,失敗的連線通常需要經過兩秒以上,才會開始第一次重新傳輸,而資料封包可能只經過幾百毫秒就會逾時。
6. 增加網路最大傳輸單位 (Max Transmit Unit,MTU) 或 TCP 視窗大小 乙太網路上的封包大小最大為 1,514 個位元組。有時,伺服器會將 MTU (封包的大小) 限制得很小。如果您發現有大檔案的回應封包明顯小於 1,500 位元組,則應該進行檢查。
另一個相關問題是 TCP 視窗大小。這通常是 16KB 或 32KB,視 OS 而定。這表示 TCP 在必須等待認可之前,可以增加其傳送的位元組數目。您可以將這一點視為每一次來回的位元組數目 (儘管是過度簡化)。TCP/HTTP 通常一開始會在第一個回應中傳送含有兩個封包的視窗,大約 3KB 的資料。接著,伺服器會先等待認可,然後才傳送另一個視窗。視窗大小會隨著收到每一個成功的認可而增加。這樣可讓 TCP 判斷兩個裝置之間有多少頻寬可用。
請尋找長時間從伺服器傳來小於 16KB 的視窗大小,然後將這些視窗大小變更回預設值。若要找出視窗大小,請開啟 NetMon,並查看伺服器回應封包的「視窗大小 (Window Size)」。
7. 識別伺服器擁塞的問題 速度慢的伺服器通常會顯現很快的 TCP 連線時間,在 TCP 層次有很快的認可回應,但是資料回應封包的第一個位元組時間 (Time-To-First-Byte) 卻會很慢。請將伺服器視為分層運作 (如同在 Open System Interconnection (OSI) 模型中一樣),彼此獨立運作。TCP 層在核心層次或 NIC 卡中執行,速度非常快。當要求封包傳入時,它會將資料向上轉送到 HTTP 層,而 HTTP 層可能需要執行磁碟搜尋。在 HTTP 層能夠回應之前,TCP 層無法送出認可 (請參閱 [圖 8])。
圖 8 緩慢的伺服器
8. 檢查多餘的來回次數 網頁載入期間所發生的一切,並不一定都是需要的。某些動作的執行或所做的決定,純粹是因為瀏覽器沒有獲得適當的指示,例如一個檔案要快取多久。
9. 設定到期日 瀏覽器會快取 JavaScript、CSS、影像及 XML 等靜態檔案,供使用者下次載入網頁時使用。瀏覽器會在檔案的 HTTP 標頭中尋找到期日,以確定檔案是否仍然有效。可惜的是,很多網站都沒有設定這些日期。因此,瀏覽器會從快取中取出檔案,但因為找不到日期,所以會傳送 Get-if-Modified (若有修改則擷取) 給伺服器。在大多數情況下,伺服器會回應 304 Not-Modified (未修改),因此就會使用快取中的檔案。
很有效率的網站會將日期設定在三年以後。如果變更檔案名稱或路徑,或加入引數字串,則會造成瀏覽器重新載入檔案。請停下來思考,有多少網站和多少頻寬是用來處理使用者已擁有之檔案的 Get 要求。
到期日的另一項好處,在於它們對於 Entity 標記 (Etag) 的影響。Etag 很容易造成效能問題。它們的主要用途,是使用伺服器產生的號碼來唯一識別檔案。在伺服器叢集內,每一部伺服器會建立不同的號碼。例如,假設瀏覽器針對在快取中找到的檔案傳送 Get-If-Modified。如果只有一部伺服器,則檔案非常可能相符,且將會傳送 304 Not-Modified 的錯誤。但是,如果使用者存取的是龐大的伺服器陣列,則很可能連上具有不同 Entity 標記的另一部伺服器,導致該伺服器將整個檔案重新載入瀏覽器中。
使用 VRTA 時,如果您發現有多個 JavaScript 檔案收到伺服器傳回的 200-OK,則表示伺服器無法辨認 Entity 標記,且會重新送整個檔案。這樣不僅會重新載入檔案,瀏覽器通常還會辨認出檔案與快取中的檔案相同,並嘗試阻止伺服器重送整個檔案。
在做法上,瀏覽器會傳送 Reset 旗標來關閉 TCP 通訊埠。這樣反而會增加來回次數,因為必須由新的通訊埠來完成剩餘的檔案下載作業。一個簡單的解決方案,就是設定檔案的到期日,讓瀏覽器可以重複使用快取的檔案,而不必對伺服器執行呼叫。
測驗:如何改善網頁載入的速度?
在閱讀本文之前,請先回答這些 Web 效能問題,然後在讀完本文之後再測驗一次,以了解您自己的改善程度!
1. 您應該有多少個同時執行的通訊埠?
a. 愈少愈好
b. 寬頻上較多,窄頻上較少
2. 透過 WAN 時,何者的下載速度較快?
a. 很多小檔案
b. 相同彙總比重的少數大檔案
3. JavaScript 只會阻擋其他 JavaScript 檔案。
a. 錯
b. 對
4. 根據預設會啟用「持續作用」嗎?
a. 會
b. 不會
5. 預設的到期日
a. 是空的
b. 是自下載日起的 30 天
6. 您該如何阻止 Etag 重新載入檔案?
a. 設定到期日
b. 要求使用者等待檔案重新載入
7. HTML、JavaScript 及 CSS 檔案的壓縮,通常可以達到多少壓縮比例?
a. 1.5 比 1
b. 3 (或以上) 比 1
8. 影像檔案一律會壓縮。
a. 對
b. 錯

10. 重新導向之前先考慮清楚 網站位址會隨著時間而改變,通常會利用重新導向讓使用者前往新的位置。不過,重新導向很浪費時間,因此應該取代之。請改以考慮網站是否可以從舊的 URL 來做回應。
11. 壓縮檔案 大多數的 JavaScript、CSS 及 HTML 檔案都可以壓縮到高達 4 比 1 的比例。XML 的壓縮比甚至可以更高。這些檔案類型的好處,在於伺服器可以將它們壓縮一次,然後儲存已壓縮的版本。這樣可以降低伺服器上的 CPU 負載以及網路上的傳輸位元數量。
動態檔案 (例如 ASPX) 需要隨著每一位使用者而即時壓縮,因此,通常是由外部裝置來壓縮,例如負載平衡器。我常被問到壓縮是否會在瀏覽器上浪費許多時間,以及是否所有瀏覽器都能處理壓縮。首先,請思考透過網路來載入一個大檔案所花費的時間。如果 VRTA 將每一個檔案放入壓縮公用程式內壓縮,然後在壓縮率欄中顯示新檔案與舊檔案的比例,則比例為 1 或更小的數據,即代表已壓縮的檔案。在那種情況下,載入此網站上的 JavaScript 檔案需要一至五秒。
在較新型的 PC 上解壓縮這些檔案通常只需要數毫秒的時間。瀏覽器必須在 Get 要求中傳送 "will accept gzip, deflate" (可接受壓縮檔自行解壓縮) 的聲明,讓伺服器知道它有能力處理壓縮作業。
完整大小的影像要做為縮圖使用時,一律必須重新格式化。另外,最好試驗影像的各種不同格式,找出何者的壓縮效果最好 (JPG、GIF 或 PNG)。很奇怪,我曾經發現影像沒有縮壓的情形,因此,千萬別以為所有影像都會理所當然地壓縮。
此外,請記得去除檔案中的空白部分,因為這通常可以將大小降低 20%。請注意,空白部分包括定位點、換行字元,尤其是備註。有許多工具可以為您代勞。緊縮和壓縮都可考慮使用,因為效果都會累積。
12. 編輯您的 CSS 不知道為什麼,開發人員總是在 CSS 檔案中寫出每一個字型執行個體,卻不利用階層式樣式。如果您在 CSS 檔案中看到相同的字不斷地重複出現,就表示檔案的寫法沒有效率。
使用 Visual Round Trip Analyzer
您已經知道要追求什麼,現在請回去查看您的網站。請從 MSDN Magazine 網站下載 VRTA 並執行安裝程式。如果您尚未安裝 NetMon 3.2 版或更新的版本,則會提示您安裝 NetMon。在您使用的機器上,您需要有系統管理員權限才能執行這項動作。
完成安裝之後,VRTA 會自動啟動。桌面上也會出現圖示。請按一下 [啟動 (Start)] 按鈕,讓 VRTA 啟用 NetMon 擷取。現在,請再一次造訪您的網站。請一次僅執行一個不可部分完成的交易 (稱為「工作」)。瀏覽到一個網頁並任由其呈現,這樣就是一個交易。停止 VRTA 來檢視交易。在按 [下一步 (Next)] 按鈕之前,請先重新啟動 VRTA,然後在呈現之後重複同樣的動作。
接下來,開啟左邊的資料夾來開啟現有的擷取檔案。這也可以用來檢視所有檔案。VRTA 會建立所有檔案的純文字版本,稱為 RTA.txt。NetMon 圖示可讓您直接開啟擷取檔案。像往常一樣儲存、複製、貼上及列印工作。您已經使用過 [啟動 (Start)] 和 [停止 (Stop)] 按鈕。[縮放 (Zoom)] 按鈕可讓您放大檔案視覺效果。這在查看詳細資料時很實用。請使用 [選取網路 (Select Network)],以指示 VRTA 監聽您的有線 LAN 介面或無線裝置。請使用最長時間下拉式清單來選取比例。
工具中有三個浮動視窗。第一個是在 [主要圖表 (Main Chart)] 索引標籤上,您在此可以看到各通訊埠下載的檔案。將滑鼠移到任何檔案上,即可查看其他詳細資料。在 [所有檔案 (All Files)] 索引標籤上,您會看到依啟動順序排序的檔案。將滑鼠移到 URI 上,即可查看每一個檔案的詳細資料。在 [分析 (Analysis)] 索引標籤上,將滑鼠移到任何規則上,即可查看檔案的例外清單。
除了 [複製 (Copy)] 和 [貼上 (Paste)] 按鈕,VRTA 還會建立兩個檔案。NetMon 擷取檔案中會包含原始封包詳細資料。根據此檔案,您可以重新建立所有的 VRTA UI。您也可以深入查看擷取的內容,以獲取超越工具所能呈現的資訊。RTA.txt 檔案採用表格的格式,其中包含 page-load-time (頁面載入時間) 統計資料。您可以使用 Microsoft Office Excel 來輕鬆閱讀此檔案。
當您使用工具來查看不同的網頁時,請注意 Web 效能測試的一些重點。如果您在測試時非常靠近伺服器 (基本上表示距離在幾百哩之內),但您的使用者分散在世界各地,那您就必須到全球各地,或是使用 WAN 模擬器。有一些軟體公用程式可以針對您所使用的網路,修改其位元速率、來回時間 (RTT) 及封包遺漏等數據。
在 Microsoft,我們採用 300/64Kbps 位元速率的 WAN 模擬器基準測試,全球內容的來回時間 (RTT) 設定為 300 毫秒,而本機內容傳遞網路 (Content Delivery Network) 的來回時間 (RTT) 則設定為 50 毫秒。我們的封包遺漏率設定為 3%。此基準測試可讓我們測試多個應用程式的多個版本,在相同的環境下查看其相對效能。
切記,只取樣一次的測試只能代表單一情況。每一次的擷取都會稍微不同,有時候通常會大有不同,這是因為會有變動的廣告內容且網路或伺服器會有擁塞的問題。我強烈建議您進行多次取樣,直到能夠看到穩定的狀態為止。
NetMon 安裝時會包含一個命令列版本,稱為 NM_cap.exe。請建立指令碼來啟動 NM_cap、瀏覽到一個網頁,然後在呈現之後停止 NM_cap 並儲存檔案。請使用 VRTA UI 來開啟並檢閱該檔案。
您也應該移至 "About:Blank" 網頁,然後在 [Internet Explorer] | [工具] | [網際網路選項] 中刪除快取檔案,以重建使用者的初次載入經驗 (稱為 Page-Load-Time 1)。我們使用空白網頁是要 Internet Explorer 自動重新載入正在檢視的網頁。請關閉瀏覽器,以強制關閉任何 TCP 連線。接著,開啟瀏覽器並連上您正在測試的網頁。若要進行 Page-Load-Time 2 (次日使用者第二次回來造訪) 的測試,請直接關閉瀏覽器,再重新開啟並連上測試網頁。
最後一項警告:請注意公司的 Proxy 伺服器,這些伺服器可以保護公司資源,防堵來自網際網路的惡意入侵者。不過,這些伺服器也會造成您的效能樣本失真。通常會停用壓縮,這可能會讓您誤以為來源伺服器上也停用壓縮。Proxy 也會遮蔽「持續作用」。進行測試時,最好是在公司 Proxy 之外,也就直接在網際網路上進行。

結論
由 VRTA 產生的報告及您在本文中看到的最佳做法,代表目前所知的情況,但這不代表全部。請深入研究 NetMon 擷取的原始資料,為自己找出新的模式和最佳做法。
非常感謝下列優秀的團隊協助我建立這套新的視覺化工具:Ron Oshima、Lucius Fleuchaus、Jason He 以及 Doug Franklin。

Jim Pierson 已在 Microsoft 任職 12 年,其中有 5 年的時間致力於發展 Web 效能工程。Jim 是 GlobalPerf 團隊的小組總經理,負責對 MSN 和 Windows Live 線上服務的最佳做法提供衡量、分析及訓練的工具。

測驗答案: 1=b,2=b,3=a,4=a,5=a,6=a,7=b,8=b

Page view tracker