閱讀本文英文原文(翻譯:劉松濤)
本文英文版由Port80 Software公司授權發(fā)表
這個分為三部分的文章概述了一個直觀的、省時省力的方法來提升訪問網站的速度,這是基于網站性能有關的兩個簡單法則:
若使用得當,此兩條法則會:
使用這些技巧來開發(fā)網站,不僅能夠提高用戶對一個網站或者是基于web的一個應用的滿意度,更可以節(jié)約網站數據傳輸的成本。這篇文章所講述的技術細節(jié)可幫助我們寫出很好很實用的代碼,從更廣泛的角度來講,這也將會給網站打造出良好的可用性基礎。
為自己寫代碼,為使用而編譯
任何一個程序員都很清楚地知道,之所以不把自己所使用的代碼作為最終的代碼來交付是有它合理的原因的。寫代碼時最好要盡可能多寫些注釋,通過編排格式在最大程度上提高代碼的可閱讀性,同時避免過分的簡潔不讓晦澀的代碼給日后的維護帶來困難。之后,我們再使用編譯器等把源代碼轉化成其他格式,一方面達到最優(yōu)執(zhí)行,另一方面可以防止反編譯,以免造成源代碼被剽竊。上述的這種模式其實也適用于網站的開發(fā)。具體做法是:先制作好網站和網頁的源代碼,再利用一些簡單的技術(比如:減少空白區(qū)域,進行圖片和腳本的優(yōu)化,文件重命名等)把源代碼減肥然后你就可以將準備好的網站和網頁交付使用了。
希望這種概念對于你來說并不突兀,因為起碼你很有可能正是在您站點的副本上操作,而不是直接在正在運行的站點上作修改更新。如果你不是這樣做的,那么請馬上停止閱讀本文,趕緊去給你的站點做個副本吧!無論您的網站的內容是靜態(tài)的手冊還是非常復雜的使用內容管理系統(tǒng)來驅動(CMS-driven)的應用,這都是唯一正確的開發(fā)網站的方式。你要是現(xiàn)在還不相信的話,那么我敢說很快的等到你損毀了網站的一些文件卻發(fā)現(xiàn)難以恢復的時候你就信了。
在建造網站時,您可能會把注意力放在導致下載速度降低的最大元兇—圖片、二進制文件(如Flash等)上。減少GIF圖片文件的顏色數、壓縮JPEG圖片文件的大小、優(yōu)化SWF文件固然頗有裨益,其他大有幫助的方法也不能小覷。要記得網站性能法則中的第一條,我們得不斷的努力以盡可能少地傳輸數據,不論它是markup文件、圖片還是腳本。把精力放在減少(X)HTML、CSS和JavaScript文件的字節(jié)數上似乎是瞎忙乎,可是,這可能恰恰就是最應該注意的地方。
在一個典型的網頁加載過程中,(X)HTML文件是最先被瀏覽器讀到的。既然這個文件決定了其他文件的關系,我們可以管這個文件叫主文件(host document)。瀏覽器一旦接收到這個主文件,便開始解析各種markup;一般在解析的同時,也會觸發(fā)一系列對相關對象的請求,例如外部腳本、關聯(lián)的樣式表單、圖片、或嵌入式Flash等等。這些CSS和JavaScript文件有可能繼續(xù)觸發(fā)一些對相關圖片或腳本等的請求。這些對相關文件的請求排成隊列的速度越快,它們到達瀏覽器的速度也就越快,從而越早的開始顯示出頁面來。了解了主文件的重要性,我們便知道把它盡快地傳給瀏覽器并加以解析的重要性,因為盡管主文件本身相對來說整個傳輸量來說只是一小部分,它卻能夠嚴重地阻礙網頁的加載速度。要明白,用戶才不在乎你使用的字節(jié)數的多少,用戶在乎的是時間!
那么您具體需要怎么做才能作到最優(yōu)傳輸的萬全準備呢?一個基本的方法是減少空白區(qū)域,精簡CSS和JavaScript,更改文件名,以及對要提交的代碼也采用前述相同的策略,使之越簡潔越好(Google 就是一個例子). 這些目前大家都熟知的通用技巧,在很多網站和一些書中比如Andy King的 《Speed up Your Site: Website Optimisation 》都能找到。本文則列出我們認為最有效的優(yōu)化markup和代碼的二十大技巧。當然,您可以手動來做部分優(yōu)化,或者使用網頁編輯器及工具來完成一些優(yōu)化,當然還可以開發(fā)出您自己的精簡工具。我們要向你介紹一個由Port80軟件公司開發(fā)的工具w3compiler. 它幾乎實現(xiàn)了下面將要提到的所有技巧,而且它也反映出在“真實”世界里代碼優(yōu)化任務的商業(yè)價值。接下來,我們來談談這些技巧!
Markup優(yōu)化
典型的markup要么是手工編輯出來的,在非常緊湊,注重標準的格式基礎上加入注釋和空白區(qū)域(white space)的文件;要么是編輯器生成的,非常之肥胖,帶有過分的格式編排及編輯器特有的通常用來控制結構的注釋,甚至還會有不少重復的和沒有用修飾或者代碼。這兩者都不是最優(yōu)傳輸的情況。下列技巧既安全又容易,是減小文件尺寸的好方法:
1、盡可能的除去空白區(qū)域
一般而言,空白區(qū)域字符(空格、制表符、換行符等)都可以安全刪除,但要避免修改pre
, textarea
, 及受CSS屬性中white-space
影響的標簽。
2、除去注釋
除了在客戶端給IE和doctype
聲明的條件注釋外,幾乎所有的注釋都可以安全去除掉。
3、使用最短格式的顏色表示
使用顏色時,不要一股腦的使用十六進制或全顏色名稱(full color name),要盡可能根據實際情況使用最短格式的顏色表示。比如,一個為 4、 使用最短格式的字符表示 和最短顏色表示一樣,一些名稱可以用最短字符來表示,我們可以用較短的數字來代替某些長長的字母。比如: 5、 除去無用的標簽 有些‘垃圾’markup,比如使用了多次的重復標簽或者某些編輯器里用作廣告的 CSS也有一套成熟而又簡單的優(yōu)化方法。實際上,時下大多數的CSS都較 (X)HTML更容易壓縮。下面所列的技巧除了最后一條都是安全的。最后一條涉及到客戶端的網頁技術,可能會變得比較復雜。 6、除去CSS中的空白區(qū)域 相比起(X)HTML來,CSS對于空白區(qū)域沒有那么敏感,所以除去空白區(qū)域便可以極大地減少CSS文件和 7、 除去CSS注釋 如同除去markup代碼中的注釋一樣,由于CSS中的注釋對普通的最終用戶來說并沒有什么實用價值,所以也應該被除去。不過,如果考慮到較低級的瀏覽器,則在CSS中的 8. 使用最短格式來表示顏色值 和HTML一樣,CSS顏色也可以用詞語或十六進制格式表示。注意,在CSS中這樣做的效果會稍微明顯一些。主要是因為CSS中支持3位的十六進制色值,例如對白色可用 9、對CSS的規(guī)則進行合并、減少或刪除 CSS中的諸如字體大小、字體重量等規(guī)則往往可以使用一種單屬性字體的速記注釋方式來表示。使用得當的話,這個技巧可以讓您把如下的規(guī)則: 改寫成下面簡短的形式: 如果繼承方法使用得當的話,您還會發(fā)現(xiàn)在樣式表單中的一些規(guī)則可以顯著的減少或干脆刪掉。到目前為止尚沒有能自動移除規(guī)則的工具,所以只能通過手工調整CSS向導(Wizard)來進行這些工作。不過即將推出的w2compiler 2.0會有這個功能。 10、對類和ID值進行重命名 在CSS優(yōu)化中最危險的動作可能是重命名類或ID值了??纯慈缦乱?guī)則: 可將其更名為sS。而對ID值一樣可以遵循這樣的原則,例如對于: 則可將原來的 ”#firstParagraph” 重命名為 ”#fp”,并在整個文檔中重復這一動作 。誠然,這樣做可能會涉及到“標識-樣式-腳本”互相依賴的問題:如果一個“tag”有一個ID值,而這個值又可能不但用于樣式表,還可能用于腳本參考,甚至可能是一個鏈接目標地址。在這種情況下,您一旦修改了這個值,您就必須得保證對所有相關的腳本和鏈接參考都進行了相應的修改,包括其他文件中的這個值,所以千萬要小心細致。 改變類的值相對改變ID值來說,危險性小一些。因為經驗告訴我們,比較起ID值來說,大多數JavaScript程序員都不太經常處理類的值。然而,改變類的名稱來縮減CSS的尺寸也面臨著和改變ID名稱同樣的問題,所以再次強調,要小心謹慎。 請注意:最好不要更改名稱屬性,尤其是表單區(qū)域中的名稱屬性。因為這些數值也會被服務器端程序所操作。雖然不是不可能,但對多數的網站來講,要計算好這些相互依賴關系是困難的。 越來越多的網站都依賴于JavaScript來生成導航菜單、表格確認和其他各種各樣實用的東西。不足為奇,大多數這些代碼都非常笨重,亟待優(yōu)化。對JavaScript代碼的很多優(yōu)化技術同那些用于markup代碼和CSS的技術很相似。不過,對JavaScript的優(yōu)化必須更加小心翼翼,因為一旦操作有誤,其后果可能不僅僅是顯示變形,并且可能導致網頁殘缺不全。下面我們先來看看一些最簡單明了的方法,然后再探討那些需要小心操作的技巧。 11. 除去JavaScript注釋 除了 注釋,其他所有的 // or /* */ 注釋都可以安全刪除,因為 它們對于最終使用者來說沒有任何意義(除非有人想了解您的腳本是如何工作的)。 12.除去JavaScript中的空白區(qū)域 有意思的是,除去JavaScript中的空白區(qū)域并不象想象的那么有用。一方面,像如下代碼: 顯然可以簡短得寫成 然而,很多隨便的JavaScript程序員會忘記在兩行之間加上分號,這時空白區(qū)域的除去就會帶來問題。比如,下面合法的JavaScript使用了暗示的(implied)分號: 草率地刪除了空白區(qū)域則會產生如下表達式: 顯然,錯誤就產生了。但如果您加上必需的分號,如下: 則在字節(jié)數上并沒有減少。然而在此,我們仍然鼓勵這種格式的變化,因為對w3compiler Beta版的測試反饋中,很多人對‘看起來壓縮了的’腳本非常滿意(也許這是因為視覺上確認了對原始代碼的格式轉變)。他們也喜歡這種處理方法產生的另一個效果,那就是讓交付的代碼變得更難讀。 13.進行代碼優(yōu)化 簡單的方法如除去暗示的(implied)分號,某些情形下的變量聲明或者空回車語句都可以進一步減少腳本代碼。一些簡略的表達方式也會產生很好的優(yōu)化,例如: 可以寫成: 不過得小心謹慎,不然代碼很容易出錯。 14.重命名用戶自定義的變量和函數 為了閱讀方便,我們都知道在腳本中應該使用象 15.改寫內建(built-in)對象 長長用戶變量名會造成JavaScript代碼過長,除此之外,內建(built-in)對象(比如Window、Document、Navigator等)也是原因之一。例如: 可以改寫成如下簡短的代碼: 如果這幾個對象使用頻繁的話,這樣改寫帶來的好處就不言而喻了。事實上這些對象也的確經常被調用。然而我要提醒的是,如果Window或Navigator對象僅僅被使用了一次的話,這樣的替換反而使代碼變得更長。所以手工進行這種優(yōu)化時要格外小心,不過好在目前市面的常用的JavaScript代碼優(yōu)化工具都已經考慮到這個因素了。 這個技巧帶來一個對象更名后腳本執(zhí)行效率的問題:除了代碼長短上帶來的好處,這種改寫更名實際上還會稍微的提高一點腳本執(zhí)行的速度,因為這些對象將會被放在所有被調用對象中比較靠前的位置。JavaScript游戲開發(fā)程序員使用這個技巧已經有多年了,下載和執(zhí)行速度都會有所提高,并且對本地瀏覽器的內存花銷也會降低,可謂一石三鳥。 最后一類的優(yōu)化技巧與文件和站點的組織有關。下面談及的一些技巧可能會牽扯到服務器的調整和站點的重構。 16.重命名用戶訪問不到的獨立文件和目錄 一些站點往往包含有諸如 或者更糟糕的象 既然這些文件從來都不會被訪問到,對于最終使用者而言,方便不方便閱讀便無關緊要??紤]下載速度的因素,上述句子改成下列形式更有意義: 然而手工的文件和目錄的修改工作量太大了,我們可以借助一些內容管理系統(tǒng)來完成相關的工作,比如將內容重命名成簡短格式等。前面提到的w3compiler就有自動復制并且檢查相互依賴關系的功能。如果使用得當,這個技巧會給引用這些文件的(X)HTML文件減肥不少,并且也讓那些剽竊(X)HTML的人重新使用這些文件設置了重重障礙。 17.使用URL rewriter來縮短所有的網頁URL 注意在剛才提到的技巧中并不建議對網頁的文件名(例如 就會變成 這背后的主要原因是讀者會看到一個這樣的URL: 不過,在不犧牲網頁URL原義的前提下,假如我們結合更名技巧和修改服務器配置的話,我們還是有可能從縮短文件名中得到收獲。譬如,在源代碼中把 由于這個技巧依賴于URL的復寫,并且缺少對服務器端工具(如復寫模塊)的廣泛接觸渠道和理解,即使是象w3compiler之類的高級工具在目前也不推崇使用這個技巧。然而, 考慮到像Yahoo!這樣的大型網站通過積極使用該技巧得到了顯著的獲益,這個技巧是不能夠被忽視的,畢竟它給目錄及文件名稱都是非常具描述性的站點提供了明顯的減肥(X)HTML文件的效果。 18.除去或縮短文件擴展名 想想看,其實有些情況下文件的擴展名并沒有多大用處,比如 簡化為: 或是結合文件名目錄名重命名,我們可以得到: 您可別乍一看這個結果就嚇跑了, 不過,為了使用這個相對高級的技巧,您還需要對服務器來做一下修改。主要要做的工作是啟用一個叫做“內容協(xié)商”(content negotiation)的東西。它可能是服務器自帶的,也可能需要一個擴展(比如象Apache的mod_negotation 模塊或者IIS里Port80的PageXchanger )來支持。這樣做會有一個負面的影響,它可能會造成服務器性能的一點損失。然而,內容協(xié)商的功能所帶來的好處遠大于所付出的。干凈利落的URL可讓您的網站即安全又輕便,甚至還使得自適應的內容傳遞變成可能:根據訪問者瀏覽器的功能和系統(tǒng)的設置來向他傳輸不同類型的圖片或語言!更多的說明請參看同作者所著的 Towards Next Generation URLs 一文。 注意:少了擴展名的URL不會降低您網站在搜索引擎上的排名。Port80軟件和其他知名網站(如W3C網站)都使用此技術而沒有負面效果。 19. 重構 我們常常在一個HTML文件頭中看到這樣標記代碼: 大多數情況下,上述代碼應該被簡化成: 其中 20.考慮代碼級的cache能力 提高網站性能中最重要的方法之一是提高緩沖能力(cacheability)。網頁開發(fā)者對使用 現(xiàn)在,您已經了解了20條有用的優(yōu)化技巧來使您的網站變得更快。從單條來看它們可能沒有很大的作用??墒前阉鼈兒掀饋硎褂玫脑挘W站的傳輸能力便會有明顯的提高。在下一篇文章中,我們將重點放在緩沖處理上。我們會解釋緩沖如何經常會被錯誤使用,以及如何通過一些小小的改動來取得性能的顯著提高。 Joe Lima 是Port80軟件公司的首席構架師(architect),同時教授UCSD 擴展的服務器技術。 Port80軟件公司 從Amazon.co.uk購買作者的書籍: 如您喜歡我們的文章并希望轉載,請閱讀我們的轉載注意事項#ff0000
的顏色屬性可以直接用red</code來說明,而
lightgoldenrodyellow
可以換成 #FAFAD2#FAFAD2
。 È
; 可以變成È
。或者,偶爾這個方法反過來也行,比如:ð
如果變成ð
則可以省一個字節(jié)。不過,這個方法不太安全,而且成效有限。meta
標簽,都可以安全地被刪除。 CSS優(yōu)化
style
樣式表區(qū)域的大小。style
標簽中的屏蔽注釋信息不可以被除去。#fff
來表示。p {font-size: 36pt;
font-family: Arial;
line-height: 48pt;
font-weight: bold;}p{font:bold 36pt/48pt Arial;}
.superSpecial {color: red; font-size: 36pt;}
#firstParagraph {background-color: yellow;}
JavaScript優(yōu)化
x = x + 1;
x=x+1;
x=x+1
y=y+1x=x+1y=y+1
x=x+1;y=y+1;
x=x+1;
x++;
sumTotal
這樣的變量而不是s
。不過,考慮到下載的速度,sumTotal
這個變量就顯得冗長了。這個長度對于最終使用者來說沒有意義,但對瀏覽器下載則是個負擔。這個時候s
就成為較好的選擇了。先寫好方便閱讀的代碼,然后再使用一些工具來處理以供交付。這種處理方式在這里再一次展示了其價值所在。將所有的名稱都重新用一個或兩個字母來命名將帶來顯著的改善。alert(window.navigator.appName);
alert(window.navigator.appVersion);
alert(window.navigator.userAgent);w=window;n=w.navigator;a=alert;
a(n.appName);
a(n.appVersion);
a(n.userAgent);文件方面的優(yōu)化
SubHeaderAbout.gif
或 rollover.js
等是用戶無法通過URL來訪問的文件。它們通常都保存在一個標準名稱的目錄中,比如/images,因此我們常常會在markup代碼中看到這樣的句子:<img src="/images/SubHeaderAbout.gif">
<img src="../../../images/SubHeaderAbout.gif">
<img src="/0/a.gif">
products.html
)進行重命名。那樣的話,則下面的標示:<a href="products.html">Products</a>
<a href="p.html">Products</a>
http://www.sitename.com/p.html
相比起http://www.sitename.com/products.html
來,后者比前者要來的更有意義、更好用的多。products.html
用p.html
l替換掉,之后再設立一個URL復寫(rewrite)規(guī)則,由服務器端的一個類似復寫模塊的過濾器比如 來使用這個規(guī)則,從而再把這個URL擴展成一個較為用戶友好的值。注意這個竅門,如果這個復寫規(guī)則只執(zhí)行‘外部’(external)重定向的話,新的URL僅僅會寫在使用者瀏覽器的地址條處,因而會強迫瀏覽器重新請求該頁。在此種情況下,文件本身沒有被重命名,僅僅是在源代碼中URL里使用了重命名的簡短的文件名。.gif, .jpg, .js
等。瀏覽器不會依賴這些擴展名來顯示頁面,而是在處理時使用MIME類的頭信息(header)。了解了這一點,我們就可以把:<img src="images/SubHeaderAbout.gif">
<img src="images/SubHeaderAbout">
<img src="/0/sA">
..sA.gif
仍然是.sA.gif
文件,只不過網頁的訪問者不知道罷了。<script>
和<style>
調用方式來優(yōu)化請求次數<script src="/scripts/rollovers.js"></script>
<script src="/scripts/validation.js"></script>
<script src="/scripts/tracking.js"></script><script src="/0/g.js"></script>
g.js
包含了所有供全局使用的函數。雖然把腳本文件分成三份對于維護來說是有道理的,但對于代碼的傳輸則沒有意義。單個的腳本下載要比三個分離的請求高效的多,并且這也同時簡化了markup代碼的長度。有趣的是,這個方法模仿了傳統(tǒng)編程語言編譯器的連接概念<meta>
標簽來設置緩沖控制都很熟悉,可是撇開meta對代理的緩沖毫無用處不說,緩沖能力的真正價值是其對相關對象(比如圖片或腳本)方面的應用。為了提高緩沖能力,您要考慮根據改變頻率對相關對象進行分段,把更適合緩沖處理的東西放在某個目錄中(比如:/cache
或者/images/cache
。一旦您按照這個方法來組織您的網站,添加緩沖控制規(guī)則就很容易了,這樣你的網站就會向經常來的訪問者“跳”出來。Thomas A. Powell 是PINT公司的創(chuàng)始人,也是加州大學San Diego分校計算機科學系的講師,以及一些網頁開發(fā)書籍的作者,其所著書目包括《HTML & XHTML: The Complete Reference》和 《JavaScript: The Complete Reference》等。
Port80 Software, Inc. 是微軟 Internet Information Services (IIS) 網絡服務的領先的開發(fā)商. 公司同時提供w3compiler, 一套優(yōu)化代碼的桌面應用軟件。Port80 Software 是微軟認證合作商(MCP ISV)。它位于San Diego, CA. 更多信息請見公司網站 www.port80software.com.