高性能网站建设的最佳实践(二)
原文譯自雅虎開發者社區,轉載譯文請標明出處。
關注我的sina微博,共同進步!
為了讓網頁響應速度更快Exceptional Performance團隊列出了一系列的最佳實踐,包括35個最佳實踐條目,分成7種類型類。
避免重定向
標簽:內容
使用301和302狀態碼可以完成重定向。這里有個301響應的HTTP報文頭部實例:
HTTP/1.1 301 MovedPermanently
Location: http://example.com/newuri
Content-Type: text/html
瀏覽器自動的將用戶引導到location字段所指定的URL地址。所有的重定向的必要信息都位于報文頭部,報文體通常為空。301和302響應并不被緩存除非添加像Expires或者Cache-Controll的報文頭部以指定瀏覽器需要進行緩存。Meta刷新標簽和JavaScript是其他的將用戶引導到不同URL地址的方法,但是如果你必須重定向,更好的方式是使用3xx的HTTP狀態碼,這樣可以確保瀏覽器返回按鈕工作正常。
需要關注的是重定向減慢了用戶的體驗。將重定向插入到用戶和HTML文件中會減慢頁面中的一切,這是由于直到HTML文檔完成加載,頁面中沒有可以被渲染的東西也沒有組件開始被渲染。
一個經常發生的耗費的重定向并且卻通常會被開發者疏忽的問題如下。URL地址末尾本該有的斜線丟失時就會出現這種問題,例如,訪問http://astology.yahoo.com/astrology 會導致301響應的發生,將頁面重定向到http://astology.yahoo.com/astrology/(注意添加了斜線)。在Apache中通過使用Alias或者mod_rewrite或者DirectorySlash來修正。
連接遺留網站到一個新的網站是重定向的另一個應用。其他的情況包括連接網站中不同的部分和基于特定的條件(瀏覽器類型,用戶賬戶)將用戶引導開。使用重定向來連接兩個網站是件容易的事并且需要很少的額外編碼。盡管在這些情況下使用重定向減少了開發者的工作量,這也降低了用戶的體驗??蛇x的方式是當兩套編碼位于同一個服務器上時,使用Alias和mod_rewrite來完成重定向。如果是因為域名更改而需要重定向,一個可選的方法是創建CNAME記錄(創建別名從一個域名指向另一個域名的DNS記錄)結合Alias和mod_rewrite來實現。
移除重復的腳本文件
標簽:JavaScript
在一個頁面中包含同樣的JavaScript代碼兩次會降低性能。你想這種事情可能并不常發生。在對美國前十的網站的一個檢查是發現他們中的兩個包含重復的腳本文件。兩個主要的因素增加了單頁面中腳本文件重復的偶然性:團隊規模和腳本文件的個數。當這樣的是發生時,重復的腳本元素通過創建不必要的HTTP請求以及浪費JavaScript的執行資源來降低性能。
不必要的HTTP請求會在IE中發生,然而在Firefox中卻沒有。在IE中,如果外聯的腳本文件被包含兩次并且未被緩存,IE就在頁面渲染的過程中產生兩個HTTP請求。即使腳本文件被緩存了,額外的HTTP請求在頁面重新加載的過程中也會發生。
除了產生不必要的HTTP請求,腳本的多次執行也浪費了時間。多余的JavaScript執行會在IE和Firefox中同時發生,而不管是否緩存。
一個避免意外的包含兩次同樣的腳本的方法是實現你的模板系統中的腳本管理模塊。典型的方法是在HTML頁面中使用Script標簽。
<script type=”text/javascript”src=”menu.js”></script>
在PHP中可以借助于調用insertScript函數來實現
<?php insertScript(“menu.js”)?>
除了防止同腳本文件被插入兩次,這個函數可以處理其他的腳本問題,比如依賴檢查以及為腳本的文件名中添加版本號以支持長時間過期的頭部(ExpiresHeader)。
配置ETags
標簽:服務器端
實體標簽(ETags)是web服務器和瀏覽器用來判斷緩存中的組件和源服務器中的組件是否匹配的機制。(“entity”是“component”的另一種表述:圖像,腳本,樣式等)ETags通過提供比last-modified日期更富有彈性的機制來驗證實體。一個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.git 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
ETags的問題在于它們使用特殊屬性來構建,使得它們只對應于一個特定的服務器。當從一個服務器上得到一個源組件稍后又從另一個不同的服務器上去驗證的情況下,ETag是不會匹配的,這種情況在使用服務器集群處理請求的Web站點中是很普遍的現象。默認情況下,Apache和IIS都為ETag嵌入了數據奇跡般的較少了驗證過程中的奇怪特性,這在基于多個服務器上的web站點上測試可行。
Apache1.3和2.x上ETag格式是inode-size-timestamp,盡管在多個服務器上會處于同一個目錄下、有著同樣的尺寸、許可、時間戳等。inode卻隨著不同的服務器而不同。
II5.0和6.0在ETags上有相似的問題。ETags在IIS上的格式是:Filetimestamp:ChangeNumber。“ChangeNumber”是用于記錄對IIS的配置改變。在一個Web站點的所有的IIS服務器上,ChangeNumber一般是不同的。
結果就是由Apache和IIS為一個相同的模塊產生的ETags在不同的服務器上并不匹配。如果ETags不匹配,用戶也就不會獲得簡短快速的304響應,而那恰恰是ETags被設計出目的;取而代之的是他們將會獲取一個正常的200響應,這個響應攜帶了所有的組件數據。如果你僅僅在一個服務器上管理你的站點,這不是問題。但是如果你有多個服務器來管理站點,并且使用Apache和IIS的默認ETag配置,你的用戶就獲得了更慢的頁面加載,你的服務器負荷也會加重,你浪費了更多的帶寬,并且代理也不會很好的緩存你的內容。即使你的組件有長時間過期的頭部,一個有條件GET請求也會發出無論用戶是點擊了重新加載或者刷新按鈕。
如果你沒有利用ETags所提供的所有的彈性驗證模型,最好直接移除ETag機制。Last-Modified頭部依據組件的時間戳來驗證。移除ETag會在相應報文和后續的請求中減少了HTTP頭部的大小。這篇MicrosoftSupport文章介紹了如何移除ETags。在Apache中,在配置文件中僅僅加入下面這句話就能移除ETags:
FileETag:none
讓Ajax請求可被緩存
標簽:內容
Ajax的一個廣為人知的好處就是它為用戶提供了即時的反饋,因為它異步的從后端服務器上加載信息。然而使用Ajax可能使得用戶為了等待異步的JavaScript和XML響應而開始把玩他的大拇指,用戶是否一直等待取決于Ajax如何被使用。例如,在一個基于Web的郵件客戶端中,用戶一直等待Ajax的請求結果從而找到他們想要查詢的Email信息。記住異步并不意味著實時。
為了提升性能,優化Ajax的響應至關重要。最重要的一個途徑是將請求結果緩存起來,就像在“添加Expires和Cache-Contoll”一節中討論的那樣。一些其他的規則也適用于Ajax:
Gzip壓縮組件
減少DNS查詢
壓縮JavaScript
避免重定向
配置ETags
讓我們看看一個例子。一個Web2.0的郵件客戶端或許自動使用Ajax來加載用戶的地址簿。如果自從上次使用email web程序以來,用戶沒有改變地址簿,之前的地址簿響應數據可以從緩存中讀取,前提是Ajax緩存通過使用Expires或者Cache-Contolle頭部實現。瀏覽器必須被通知什么時候使用之前的緩存地址簿數據或者請求新的數據。這可以通過為地址簿的Ajax地址添加時間戳來標注最后一次用戶更改地址簿的時間,從而實現上述目的,例如&t=1190241612。如果地址簿自從上一次加載以來沒有被改變,時間戳不變,瀏覽器會從緩存中獲取地址簿數據從而減少了一個HTTP往返請求。如果用戶改變了地址簿數據,時間戳確保一個新的URL地址和緩存中的響應不同,瀏覽器就向更新的地址簿入口請求數據。
盡管Ajax響應報文被動態的創建,但僅僅對單戶起作用,他們可以被緩存。這將使你的Web2.0應用的更快。
盡早的清除緩存
標簽:服務器端
當用戶請求頁面,無論如何需要200-500ms的時間讓后端服務器生成一個頁面。在這個時間內,瀏覽器因為等待數據的到大而處于空閑的狀態。在PHP中有flush函數。它能夠將部分準備好了的HTML響應發送給瀏覽器,使得瀏覽器可以開始加載組件而你的后端服務器忙于生成其他的HTML頁面。在忙碌的后端和松閑中都可以看到這樣做的好處。
一個添加好的flushing的地方就在HEAD標簽后,因為html的Head標簽通常容易生成,并且允許包好任何的CSS和JavaScript文件,這樣瀏覽器開始并行請求數據而后端仍然在處理其他的東西。
例如:
…<!—css, js-->
</head>
<?php flush();?>
<body>
…<!—content-->
Yahoo! Search主導了這方面研究并且在真實的用戶上進行測試,從而證明使用這項技術的好處。
用GET發送AJAX請求
標簽:服務器端
Yahoo!Mail團隊發現當使用XMLHttpRequest時,POST在瀏覽器中經歷了兩個步驟的處理:先發送請求頭部,然后發送數據。所以最好使用GET,僅僅使用一個TCP數據包發送請求(除非你有很多的cookies)。在IE中最大URL長度是2K,如果發送多于2K的數據,你就不能使用GET。
一個讓人感興趣的個例是POST如果沒有發送任何數據的時候的行為類似于GET?;?/span>HTTP的規范,GET為的是獲取信息,所以在僅僅只是請求數據的時候使用GET是有意義的(從語義上),而和向服務器端發送數據則不同。
延遲加載模塊
標簽:內容
你可以仔細看下你的頁面,問問自己:“為了完成頁面的起始渲染,哪些是絕對需要的?”其余的內容和組件可以稍后加載。
JavaScript是很適合置于onload事件觸發之前或之后。例如,如果你使用JavaScript或者庫來完成拖動和動畫的任務,這些可以等待。因為在頁面上拖動元素在初始渲染之后才可用。其他的可以在加載事件之后獲取的包括隱藏的內容(在用戶的某個操作后出現的內容)或者圖片折疊。
有些工具可以幫助你達成目的:YUI Image Loader允許你延遲加載位于折疊區域之后的圖片并且YUIGet Utility是一個簡單的方法來實時加載JS和CSS。例如可以使用Firebug面板看看Yahoo!Home Page的加載狀況。
當性能目標和其他的web開發最佳實踐相關聯時。這種情況下,漸進增強的方法告訴我們JavaScript可以提升用戶體驗,但是你不得不確認頁面在沒有JavaScript的情況下也是可用的。所以當你確認頁面工作良好,你可以通過一些后加載的腳本提升頁面,隨后當你的拖動效果和動畫效果發揮效應時會給你帶來跟多的喝彩。
繼續閱讀:高性能網站建設的最佳實踐(三)
原文譯自:http://developer.yahoo.com/performance/rules.html
轉載于:https://blog.51cto.com/moviejs/1305404
總結
以上是生活随笔為你收集整理的高性能网站建设的最佳实践(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在Excel表数据中快速创建新增脚本
- 下一篇: java jespa_Jespa实际运用