DNS查詢也消耗響應時間,若是咱們的網頁內容來自各個不一樣的domain (好比嵌入了開放廣告,引用了外部圖片或腳本),那麼客戶端首次解析這些domain也須要消耗必定的時間。DNS查詢結果緩存在本地系統和瀏覽器中一段時間,因此DNS查詢通常是對首次訪問響應速度有所影響。下面是我清空本地dns後訪問網頁dns的查詢請求。javascript
當客戶端收到服務器的跳轉回復時,客戶端再次根據服務器回覆中的location指定的地址再次發送請求,例如如下跳轉回復。html
HTTP/1.1 301 Moved Permanently Location: http://example.com/newuri Content-Type: text/html
當客戶端遇到這種回覆的時候,用戶只能等待客戶端再次發送請求,有的網站甚至會一直跳n次,跳到他想帶你去的地方…固然在這個時候用戶看不到任何頁面內容,只有瀏覽器的進度條一直在刷新。
80%的響應時間花在下載網頁內容(images, stylesheets, javascripts, scripts, flash等)。減小請求次數是縮短響應時間的關鍵!能夠經過簡化頁面設計來減小請求次數,但頁面內容較多能夠採用如下技巧。前端
1. 捆綁文件: 如今有不少現成的庫能夠幫你將多個腳本文件捆綁成一個文件,將多個樣式表文件捆綁成一個文件,以此來減小文件的下載次數。例如在asp.net中可使用ScriptManager,asp.net MVC中的Bundling。java
2. CSS Sprites: 就是把多個圖片拼成一副圖片,而後經過CSS來控制在什麼地方具體顯示這整張圖片的什麼位置。給你們看個熟悉的Sprites實例。豆瓣把他的圖標集中在一塊兒,而後咱們看他如何控制只顯示第一個圖標的web
.app-icon-read {ajax
background-position: 0 0;瀏覽器
}.app-icon {緩存
background安全
: url("/pics/app/app_icons_50_5.jpg") no-repeat scroll 0 0 transparent;服務器
border-radius: 10px 10px 10px 10px;
box-shadow: 1px 1px 2px #999999;
display: inline-block;
height: 50px;
width: 50px;
}
3. Image Maps: 也是將多幅圖拼在一塊兒,而後經過座標來控制顯示導航。這裏有個經典的例子,選中圖片中的某我的就會將你帶到不一樣的連接。
4. Inline images: 經過編碼的字符串將圖片內嵌到網頁文本中。例以下面的inline image的顯示效果爲一個勾選的checkbox。
.sample-inline-png { padding-left: 20px; background: white url('data:image/png;base64,iVBORw0KGgoAA AANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0l EQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6 P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC') no-repeat scroll left top;}
Ajax能夠幫助咱們異步的下載網頁內容,可是有些網頁內容即便是異步的,用戶仍是在等待它的返回結果,例如ajax的返回是用戶聯繫人的下拉列表。因此咱們仍是要注意儘可能應用如下規則提升ajax的響應速度。
添加Expires 或 Cache-Control報文頭使回覆能夠被客戶端緩存
壓縮回復內容
減小dns查詢
精簡javascript
避免跳轉
配置Etags
這裏討論延遲加載須要咱們知道咱們的網頁最初加載須要的最小內容集是什麼。剩下的內容就能夠推到延遲加載的集合中。
Javascript是典型的能夠延遲加載內容。一個比較激進的作法是開發網頁時先確保網頁在沒有Javascript的時候也能夠基本工做,而後經過延遲加載腳原本完成一些高級的功能。
與延遲加載目的相反,提早加載的是爲了提早加載接下來網頁中訪問的資源,下面是提早加載的類型
無條件提早加載:當前網頁加載完成後,立刻去下載一些其餘的內容。例如google會在頁面加載成功以後立刻去下載一個全部結果中會用到的image sprite。
有條件加載:根據用戶的輸入推斷須要加載的內容,雅虎的示例是search.yahoo.com,
有預期的的加載:這種狀況通常發生在網頁從新設計時,因爲用戶常常訪問舊網頁,本地對舊的網頁內容緩存充分從而顯得舊網頁速度很快,而新的網頁內容卻沒有緩存,設計者能夠在舊網頁的內容中預先加載一些新網頁中可能用到的內容,這樣新的網頁就會生下來一些須要下載的資源。
網頁中元素過多對網頁的加載和腳本的執行都是沉重的負擔,500個元素和5000個元素在加載速度上會有很大差異。
想知道你的網頁中有多少元素,經過在瀏覽器中的一條簡單命令就能夠算出,
document.getElementsByTagName('*').length
多少算是多了呢?雅虎在寫這篇文章的時候號稱主頁只有700多元素,但如今接近多了一倍。咱們的網頁至少別比雅虎還多吧
瀏覽器通常對同一個域的下載鏈接數有所限制,按照域名劃分下載內容能夠瀏覽器增大並行下載鏈接,可是注意控制域名使用在2-4個之間,否則dns查詢也是個問題。
通常網站規劃會將靜態資源放在相似於static.example.com,動態內容放在www.example.com上。這樣作還有一個好處是能夠在靜態的域名上避免使用cookie。後面咱們會在cookie的規則中提到。
使用iframe要注意理解iframe的優缺點
優勢
能夠用來加載速度較慢的內容,例如廣告。
安全沙箱保護。瀏覽器會對iframe中的內容進行安全控制。
腳本能夠並行下載
缺點
即便iframe內容爲空也消耗加載時間
會阻止頁面加載
沒有語義
404咱們都不陌生,表明服務器沒有找到資源,咱們要特別要注意404的狀況不要在咱們提供的網頁資源上,客戶端發送一個請求可是服務器卻返回一個無用的結果,時間浪費掉了。
更糟糕的是咱們網頁中須要加載一個外部腳本,結果返回一個404,不只阻塞了其餘腳本下載,下載回來的內容(404)客戶端還會將其當成Javascript去解析。
前端性能篇:
再次強調第一條黃金定律,減小網頁內容的下載時間。提升下載速度還能夠經過CDN(內容分發網絡)來提高。CDN經過部署在不一樣地區的服務器來提升客戶的下載速度。若是你的網站上有大量的靜態內容,世界各地的用戶都在訪問,我說的是youtube麼?那CDN是必不可少的。事實上大多數互聯網中的巨頭們都有本身的CDN。咱們本身的網站能夠先經過免費的CDN供應商來分發網頁資源。
這條規則分爲兩個方面,
對於靜態內容添加Expires,將靜態內容設爲永不過時,或者很長時間之後。在IIS中設置Expires能夠看Configure the HTTP Expires Response Header (IIS 7)。
對於動態內容應用合適的Cache-Control,讓瀏覽器根據條件來發送請求。關於asp.net的caching,能夠看asp.net cache feature和asp.net caching best practices。
Gzip一般能夠減小70%網頁內容的大小,包括腳本、樣式表、圖片等文件。Gzip比deflate更高效,主流服務器都有相應的壓縮支持模塊。
IIS中內建了靜態壓縮和動態壓縮模塊,如何配製能夠參考Enable HTTP Compression of Static Content (IIS 7)和Enable HTTP Compression of Dynamic Content (IIS 7)。
值得注意的是pdf文件能夠從須要被壓縮的類型中剔除,由於pdf文件自己已經壓縮,gzip對其效果不大,並且會浪費CPU。
雖然標題叫配製ETags,可是這裏你要根據具體狀況進行一些判斷。首先Etag簡單來講是經過一個文件版本標識使得服務器能夠輕鬆判斷該請求的內容是否有所更新,若是沒有就回復304 (not modified),從而避免下載整個文件。
可是Etags的版本信息即便主流服務器未能很好地支持跨服務器的判斷,好比你從一個服務器集羣中一臺獲得Etags,而後發送到了另外一臺那麼校驗頗有可能會失敗。
若是你遇到這樣的問題,IIS 7中能夠經過以下方法將Etag去掉,使用URL Rewrite,而後在web.config中添加以下配製
<rewrite> <outboundRules> <rule name="Remove ETag"> <match serverVariable="RESPONSE_ETag" pattern=".+" /> <action type="Rewrite" value="" /> </rule> </outboundRules></rewrite>
IIS8裏提供了一個簡單配製來直接關閉Etag,
<element name="clientCache"> <attribute name="cacheControlMode" type="enum" defaultValue="NoControl"> <enum name="NoControl" value="0" /> <enum name="DisableCache" value="1" /> <enum name="UseMaxAge" value="2" /> <enum name="UseExpires" value="3" /> </attribute> <attribute name="cacheControlMaxAge" type="timeSpan" defaultValue="1.00:00:00" /> <attribute name="httpExpires" type="string" /> <attribute name="cacheControlCustom" type="string" />
<attribute name="setEtag" type="bool" defaultValue="false" />
</element>
網頁後臺程序中咱們知道有個方法叫Response.Flush(),通常咱們調用它都是在程序末尾,但注意這個方法能夠被調用屢次。目的是能夠將現有的緩存中的回覆內容先發給客戶端,讓客戶端「有活幹」。
那在何時調用這個方法比較好呢?通常狀況下咱們能夠在對於須要加載比較多外部腳本或者樣式表時能夠提早調用一次,客戶端收到了關於腳本或其餘外部資源的連接能夠並行的先發請求去下載,服務器接下來把後續的處理結果發給客戶端。
瀏覽器在實現XMLHttpRequest POST的時候分紅兩步,先發header,而後發送數據。而GET卻能夠用一個TCP報文完成請求。另外GET從語義上來說是去服務器取數據,而POST則是向服務器發送數據,因此咱們使用Ajax請求數據的時候儘可能經過GET來完成。
關於GET和POST的詳細對比能夠查看這裏。
空的圖片src仍然會使瀏覽器發送請求到服務器,這樣徹底是浪費時間,並且浪費服務器的資源。尤爲是你的網站天天被不少人訪問的時候,這種空請求形成的傷害不容忽略。
瀏覽器如此實現也是根據RFC 3986 - Uniform Resource Identifiers標準,空的src被定義爲當前頁面。
因此注意咱們的網頁中是否存在這樣的代碼
straight HTML
<img src="">
JavaScript
var img = new Image();
img.src = "";
前端性能篇: