前些時間主要學習了前端的性能優化的基礎知識,總結筆記,準備進階!javascript
² 白屏時間:在head頭部和底部分別嵌入腳本能夠得到head頭部的加載時間,這個時間事後頁面開始程序內容,能夠大體認爲是白屏時間php
² 用戶可操做時間:默承認以統計domready時間,由於一般會在這時候綁定事件操做css
² 頁面總下載時間:能夠統計onload時間html
² 首屏時間:這個較爲複雜,統計首屏全部內容呈現出來的時間,主要因素是圖片的加載,異步渲染,iframe等前端
window.performance的navigation和timing接口提供了豐富的信息java
² navigation提供的信息:用戶訪問頁面的形式和關於訪問重定向的一些相關信息web
ü timing提供的信息:文檔解析各個步驟的耗時chrome
ü .navigationStart 準備加載頁面的起始時間api
ü .unloadEventStart 若是前一個文檔和當前文檔同源,返回前一個文檔開始unload的時間跨域
ü .unloadEventEnd 若是前一個文檔和當前文檔同源,返回前一個文檔開始unload結束的時間
ü .redirectStart 若是有重定向,這裏是重定向開始的時間.
ü .redirectEnd 若是有重定向,這裏是重定向結束的時間.
ü .fetchStart 開始檢查緩存或開始獲取資源的時間
ü .domainLookupStart 開始進行dns查詢的時間
ü .domainLookupEnd dns查詢結束的時間
ü .connectStart 開始創建鏈接請求資源的時間
ü .connectEnd 創建鏈接成功的時間.
ü .secureConnectionStart 若是是https請求.返回ssl握手的時間
ü .requestStart 開始請求文檔時間(包括從服務器,本地緩存請求)
ü .responseStart 接收到第一個字節的時間
ü .responseEnd 接收到最後一個字節的時間.
ü .domLoading ‘current document readiness’ 設置爲 loading的時間 (這個時候還木有開始解析文檔)
ü .domInteractive 文檔解析結束的時間
ü .domContentLoadedEventStart DOMContentLoaded事件開始的時間
ü .domContentLoadedEventEnd DOMContentLoaded事件結束的時間
ü .domComplete current document readiness被設置 complete的時間
ü .loadEventStart 觸發onload事件的時間
ü .loadEventEnd onload事件結束的時間
http://yslow.org/ 提供相應的chrome插件,並聽從yahu的優化法則提供優化的建議。
以上是一些業界作的比較好的工具,主要是對頁面的白屏時間,首屏時間等指標,頁面重繪次數,dom數,頁面大小,總下載時間等。
Pagespeed和yslow都根據雅虎的優化法則提供一些優化的建議。
一、 儘可能減小HTTP請求次數
http比較耗時,應儘量減小請求。
貼吧實踐:combo js/css ,css sprit
二、減小DNS查找次數
減小主機名的數量也會減小頁面中並行下載的數量。減小DNS查找次數能夠節省響應時間,可是減小並行下載卻會增長響應時間。指導原則是把這些頁面中的內容分割成至少兩部分但不超過四部分。這種結果就是在減小DNS查找次數和保持較高程度並行下載二者之間的權衡了。
貼吧實踐:靜態文件再也不不一樣的域下的靜態服務器。
三、 避免跳轉
當URL本該有斜槓(/)卻被忽略掉時。例如,當咱們要訪問http://astrology.yahoo.com/astrology 時,實際上返回的是一個包含301代碼的跳轉,它指向的是http://astrology.yahoo.com/astrology/ (注意末尾的斜槓)。在Apache服務器中可使用Alias 或者 mod_rewrite或者the DirectorySlash來避免
四、 可緩存的AJAX
五、 推遲加載內容
哪些內容是頁面呈現時所必需首先加載的。
預加載是在瀏覽器空閒時請求未來可能會用到的頁面內容(如圖像、樣式表和腳本)。使用這種方法,當用戶要訪問下一個頁面時,頁面中的內容大部分已經加載到緩存中了,所以能夠大大改善訪問速度。
貼吧實踐:滾動加載,把內容數據存儲在不可見元素裏(textarea)
六、 減小DOM元素數量(減小頁面體積)
貼吧實踐:縮減頁面體積,減小pageData的重量
七、 根據域名劃分頁面內容
因爲DNS查找帶來的影響你首先要確保你使用的域名數量在2個到4個之間。
貼吧實踐:靜態文件再也不不一樣的域下的靜態服務器。
八、 使iframe的數量最小
<iframe>優勢:
解決加載緩慢的第三方內容如圖標和廣告等的加載問題
Security sandbox
並行加載腳本
<iframe>的缺點:即時內容爲空,加載也須要時間
會阻止頁面加載
沒有語意
九、 不要出現404錯誤
十、 使用內容分發網絡(Content Delivery Network,CDN)
貼吧實踐:cdn
十一、 爲文件頭指定Expires或Cache-Control
這條守則包括兩方面的內容:
對於靜態內容:設置文件頭過時時間Expires的值爲「Never expire」(永不過時)
對於動態內容:使用恰當的Cache-Control文件頭來幫助瀏覽器進行有條件的請求
貼吧實踐:緩存靜態文件
十二、 Gzip壓縮文件內容
服務器根據文件類型來選擇須要進行gzip壓縮的文件,可是這過於限制了可壓縮的文件。大多數web服務器會壓縮HTML文檔。對腳本和樣式表進行壓縮一樣也是值得作的事情,可是不少web服務器都沒有這個功能。實際上,壓縮任何一個文本類型的響應,包括XML和JSON,都值得的。圖像和PDF文件因爲已經壓縮過了因此不能再進行gzip壓縮。若是試圖gizp壓縮這些文件的話不但會浪費CPU資源還會增長文件的大小。
Gzip壓縮全部可能的文件類型是減小文件體積增長用戶體驗的簡單方法。
貼吧實踐:開啓gzip壓縮
1三、 配置ETag
1四、 Entity tags(ETags)(實體標籤)是web服務器和瀏覽器用於判斷瀏覽器緩存中的內容和服務器中的原始內容是否匹配的一種機制(「實體」就是所說的「內容」,包括圖片、腳本、樣式表等)。增長ETag爲實體的驗證提供了一個比使用「last-modified date(上次編輯時間)」更加靈活的機制。Etag是一個識別內容版本號的惟一字符串。惟一的格式限制就是它必須包含在雙引號內
貼吧實踐:配置etag緩存靜態文件,方法同爲文件頭指定Expires或Cache-Control ,主要是觸發瀏覽器的緩存
1五、 儘早刷新輸出緩衝
貼吧實踐:東偉正在作的事情,bigpipe依賴的原理
1六、 使用GET來完成AJAX請求
Yahoo!Mail團隊發現,當使用XMLHttpRequest時,瀏覽器中的POST方法是一個「兩步走」的過程:首先發送文件頭,而後才發送數據。所以使用GET最爲恰當,由於它只需發送一個TCP包(除非你有不少cookie)
1七、 把樣式表置於頂部
在研究Yahoo!的性能表現時,咱們發現把樣式表放到文檔的<head />內部彷佛會加快頁面的下載速度。這是由於把樣式表放到<head />內會使頁面有步驟的加載顯示。
避免頁面渲染過程當中的閃爍
1八、 避免使用CSS表達式(Expression)
表達式的問題就在於它的計算頻率要比咱們想象的多。不只僅是在頁面顯示和縮放時,就是在頁面滾動、乃至移動鼠標時都會要從新計算一次。給CSS表達式增長一個計數器能夠跟蹤表達式的計算頻率。在頁面中隨便移動鼠標均可以輕鬆達到10000次以上的計算量
css表達式在渲染過程當中特別耗性能,
1九、 使用外部JavaScript和CSS
在實際應用中使用外部文件能夠提升頁面速度,由於JavaScript和CSS文件都能在瀏覽器中產生緩存。內置在HTML文檔中的JavaScript和CSS則會在每次請求中隨HTML文檔從新下載。這雖然減小了HTTP請求的次數,卻增長了HTML文檔的大小。從另外一方面來講,若是外部文件中的JavaScript和CSS被瀏覽器緩存,在沒有增長HTTP請求次數的同時能夠減小HTML文檔的大小。
外置css ,js主要是緩存,主要考慮外置和內置的優缺點及兩者之間的平衡
20、 削減JavaScript和CSS
精簡是指從去除代碼沒必要要的字符減小文件大小從而節省下載時間。消減代碼時,全部的註釋、不須要的空白字符(空格、換行、tab縮進)等都要去掉
代碼壓縮
2一、用<link>代替@import
前面的最佳實現中提到CSS應該放置在頂端以利於有序加載呈現。
在IE中,頁面底部@import和使用<link>做用是同樣的,所以最好不要使用它。
@import 是頁面加載以後纔會引入css,會引發閃爍,關於link和import的區別還有別的方面
2二、避免使用濾鏡
IE獨有屬性AlphaImageLoader用於修正7.0如下版本中顯示PNG圖片的半透明效果。這個濾鏡的問題在於瀏覽器加載圖片時它會終止內容的呈現而且凍結瀏覽器。在每個元素(不只僅是圖片)它都會運算一次,增長了內存開支,所以它的問題是多方面的。
徹底避免使用AlphaImageLoader的最好方法就是使用PNG8格式來代替,這種格式能在IE中很好地工做。若是你確實須要使用AlphaImageLoader,請使用下劃線_filter又使之對IE7以上版本的用戶無效
在ie中應避免使用濾鏡,增長內存開支,耗性能
2三、把腳本置於頁面底部
腳本帶來的問題就是它阻止了頁面的平行下載。HTTP/1.1 規範建議,瀏覽器每一個主機名的並行下載內容不超過兩個。若是你的圖片放在多個主機名上,你能夠在每一個並行下載中同時下載2個以上的文件。可是當下載腳本時,瀏覽器就不會同時下載其它文件了,即使是主機名不相同。
避免阻塞頁面渲染和其餘文件的並行加載
2四、剔除重複腳本
一個避免偶爾發生的兩次引用同一腳本的方法是在模板中使用腳本管理模塊引用腳本。在HTML頁面中使用<script />標籤引用腳本的最多見方法就是:
<script type="text/javascript" src="menu_1.0.17.js"></script>
在PHP中能夠經過建立名爲insertScript的方法來替代:
<?php insertScript("menu.js") ?>
爲了防止屢次重複引用腳本,這個方法中還應該使用其它機制來處理腳本,如檢查所屬目錄和爲腳本文件名中增長版本號以用於Expire文件頭等。
貼吧採用html::script的方式引入腳本文件
2五、減小DOM訪問
使用JavaScript訪問DOM元素比較慢,所以爲了得到更多的應該頁面,應該作到:
緩存已經訪問過的有關元素
線下更新完節點以後再將它們添加到文檔樹中
避免使用JavaScript來修改頁面佈局
減小dom訪問,緩存dom節點
2六、開發智能事件處理程序
有時候咱們會感受到頁面反應遲鈍,這是由於DOM樹元素中附加了過多的事件句柄而且些事件句病被頻繁地觸發。這就是爲何說使用event delegation(事件代理)是一種好方法了。
27、減少Cookie體積
HTTP coockie能夠用於權限驗證和個性化身份等多種用途。coockie內的有關信息是經過HTTP文件頭來在web服務器和瀏覽器之間進行交流的。所以保持coockie儘量的小以減小用戶的響應時間十分重要。
有關更多信息能夠查看Tenni Theurer和Patty Chi的文章「When the Cookie Crumbles」。這們研究中主要包括:
去除沒必要要的coockie
使coockie體積儘可能小以減小對用戶響應的影響
注意在適應級別的域名上設置coockie以便使子域名不受影響
設置合理的過時時間。較早地Expire時間和不要過早去清除coockie,都會改善用戶的響應時間。
Cookie會每次在http中進行傳輸,靜態文件放在不一樣於主域名的域名,tb1.bdstatic.com這個域下不會攜帶cookie,利用locatstorage
2八、對於頁面內容使用無coockie域名
當瀏覽器在請求中同時請求一張靜態的圖片和發送coockie時,服務器對於這些coockie不會作任何地使用。所以他們只是由於某些負面因素而建立的網絡傳輸。全部你應該肯定對於靜態內容的請求是無coockie的請求。建立一個子域名並用他來存放全部靜態內容。imgsrc.baidu.com域下的靜態圖片有cookie
Tb1,tb2.bdstatic.com/這個域下的靜態請求是沒有cookie的
30、優化CSS Spirite
在Spirite中水平排列你的圖片,垂直排列會稍稍增長文件大小;
Spirite中把顏色較近的組合在一塊兒能夠下降顏色數,理想情況是低於256色以便適用PNG8格式;
便於移動,不要在Spirite的圖像中間留有較大空隙。這雖然不大會增長文件大小但對於用戶代理來講它須要更少的內存來把圖片解壓爲像素地圖。100x100的圖片爲1萬像素,而1000x1000就是100萬像素。
Spirite中水平排列你的圖片,垂直排列會稍稍增長文件大小
3一、不要在HTML中縮放圖像
不要爲了在HTML中設置長寬而使用比實際須要大的圖片。若是你須要:
<img width="100" height="100" src="mycat.jpg" alt="My Cat" />
那麼你的圖片(mycat.jpg)就應該是100x100像素而不是把一個500x500像素的圖片縮小使用。
3二、favicon.ico要小並且可緩存
3三、保持單個內容小於25K
這條限制主要是由於iPhone不能緩存大於25K的文件。注意這裏指的是解壓縮後的大小。因爲單純gizp壓縮可能達不要求,所以精簡文件就顯得十分重要。
3四、打包組件成複合文本
針對上述優化法則中幾個法則學習的技術點
爲何要外置css/js? Expire,cache-control和etag的區別是啥?瀏覽器怎樣緩存?
瀏覽器緩存行爲還有用戶的行爲有關!!!用戶行爲決定了瀏覽器是否啓用緩存,是直接走緩存仍是間接走緩存。
用戶操做 |
Expires/Cache-Control |
Last-Modified/Etag |
地址欄回車 |
有效 |
有效 |
頁面連接跳轉 |
有效 |
有效 |
新開窗口 |
有效 |
有效 |
前進、後退 |
有效 |
有效 |
F5刷新 |
無效 |
有效 |
Ctrl+F5刷新 |
無效 |
無效 |
若是是初次無緩存瀏覽的話:
流程
瀏覽器請求 => 無緩存 è 發送請求向服務器 è 緩存協商 è 呈現
瀏覽器請求
è有緩存
è 緩存沒有過時 è 直接讀取瀏覽器緩存
è緩存過時,發送http 請求給服務器,請求投中帶有if-modified-since或者if-none-match,於服務器端last-modify 和etag進行比較,若是爲修改,返回304,讀取瀏覽器渲染,若是發現修改,返回200,返回內容包裝在消息體中,緩存協商,渲染
Expires cache-control last-modify etag的區別
Expires 是http1.0,目前已過時,爲了兼容還帶有expires
Cache-control 取代expires,帶有更多的規則,max-age publice等
Last-modify 和etag 都是用來的標示文件是否被修改過,多用etag,若是同時出現,etag的優先級大於last-modify
各類方式各有優缺點,好比可否跨域、是否會阻塞其它資源的下載(可否並行下載)、可否管理控制執行順序、耗費的資源、是否兼容各大瀏覽器等。
方法 |
說明 |
XHR Eval |
經過 Ajax 方式獲取代碼,並經過 eval 方式執行代碼。 |
XHR Injection |
經過 Ajax 方式獲取代碼,並在頁面上建立一個 script 元素,將 Ajax 取得的代碼注入。 |
Script in Iframe |
經過 iframe 加載 js。 |
Script DOM Element |
使用 JavaScript 動態建立 script DOM 元素並設置其 src 屬性。 |
Script Defer/Async |
嚴格來講,這一條不算是動態加載外部腳本的方法,但不少動態加載外部腳本的方法裏都會用到 sctipt 的 defer 或 async 屬性,因此也把它單獨列在這兒。這個方法利用 script 的 defer 屬性,讓腳本「推遲」執行,不阻塞頁面加載,或者設置 async 屬性,讓腳本異步執行。遺憾的是這兩個屬性不是全部瀏覽器都支持。 |
document.write Script Tag |
經過 document.write 把 HTML 標籤 script 寫入到頁面中。 |
cache trick |
先使用自定義的 script 的 type 屬性(如 <script type=」text/cache」 …),甚至使用 Image、Object 等 HTML 對象將 js 「預下載」(下載到瀏覽器緩存裏),等真正須要執行對應代碼時再將它真正地插入頁面中。 |
Web Worker |
部分瀏覽器支持 web worker 功能,能夠建立一個 worker 在後臺工做,包括加載外部腳本。 |
Bagpipe還正在學習中,bigpipe聽從的優化原則是儘早刷新輸出緩衝 。瀏覽器和服務器能夠並行同時工做。
看到高性能網站建設那本書,關於css選擇器的性能,發現以前我對css選擇器的選擇過程的認識是徹底錯誤的,css選擇器是從右向左匹配的,而不是從左向右匹配。