關于web性能一些特性匯總
DOMContentLoaded & load
load事件是window對象上的事件。指的是網頁資源已經加載完畢(包括但不限于DOM、圖片、音頻、腳本、插件資源以及CSS)。
DOMContentLoaded事件是document對象上的事件。指的是DOM已經加載完畢。IE中有個私有的事件onreadystatechange事件跟這個標準事件類似。
因此DOMContentLoaded事件都會比load事件提前觸發(jQuery重點ready event 就是兼容各種情況的DOMContentLoaded實現,感覺DOMContentLoaded時JS腳步也跑完了,畢竟放在body前)。
event.target & event.currentTarget & event.delegateTarget
在事件冒泡過程中的當前DOM元素。
觸發事件的DOM元素。
綁定了當前正在調用jQuery 事件處理器的元素。
async & defer (script TAG)
async 異步下載,下載后立即執行
defer 異步下載,按順序執行,執行區間大致在DOMContentLoaded 和window.load 之間
FPS(Frames Per Second):每秒傳輸幀數
正如Andrey Kosyakov Chromium 的博客中提到的,即使你的程序沒有很多動畫,幀的概念也是有用的,因為瀏覽器在處理輸入事件時會生成重復動作的序列。如果你在一幀中留有足夠的時間處理這些事件,就會使你的程序看上去有更好的響應性,這意味著更好的用戶體驗。
如果我們的目標是60fps, 那么最多有 16.66ms 去做所有的事情。這個時間并不多,所以盡可能從動畫中擠出時間來提高性能還是很重要的。
CSS阻塞與JS阻塞
- JS阻塞
所有瀏覽器在下載JS的時候,會阻止一切其他活動,比如其他資源的下載,內容的呈現等等。
直到JS下載、解析、執行完畢后才開始繼續并行下載其他資源并呈現內容。
為了提高用戶體驗,新一代瀏覽器都支持并行下載JS,但是JS下載仍然會阻塞其它資源的下載(例如.圖片,css文件等)。
由于瀏覽器為了防止出現JS修改DOM樹,需要重新構建DOM樹的情況,所以就會阻塞其他的下載和呈現。
嵌入JS會阻塞所有內容的呈現,而外部JS只會阻塞其后內容的顯示,
2種方式都會阻塞其后資源的下載。也就是說外部樣式不會阻塞外部腳本的加載,但會阻塞外部腳本的執行。
- CSS阻塞
CSS本來是可以并行下載的,在什么情況下會出現阻塞加載了(在測試觀察中,IE6下CSS都是阻塞加載)
當CSS后面跟著嵌入的JS的時候,該CSS就會出現阻塞后面資源下載的情況。而當把嵌入JS放到CSS前面,就不會出現阻塞的情況了。
根本原因:因為瀏覽器會維持html中css和js的順序,樣式表必須在嵌入的JS執行前先加載、解析完。而嵌入的JS會阻塞后面的資源加載,所以就會出現上面CSS阻塞下載的情況。
CSS匹配規則
- HTML 經過解析生成 DOM Tree(這個我們比較熟悉);而在 CSS 解析完畢后,需要將解析的結果與 DOM Tree 的內容一起進行分析建立一棵 Render Tree,最終用來進行繪圖。Render Tree 中的元素(WebKit 中稱為「renderers」,Firefox 下為「frames」)與 DOM 元素相對應,但非一一對應:一個 DOM 元素可能會對應多個 renderer,如文本折行后,不同的「行」會成為 render tree 種不同的 renderer。也有的 DOM 元素被 Render Tree 完全無視,比如 display:none 的元素。
- 在建立 Render Tree 時(WebKit 中的「Attachment」過程),瀏覽器就要為每個 DOM Tree 中的元素根據 CSS 的解析結果(Style Rules)來確定生成怎樣的 renderer。對于每個 DOM 元素,必須在所有 Style Rules 中找到符合的 selector 并將對應的規則進行合并。選擇器的「解析」實際是在這里執行的,在遍歷 DOM Tree 時,從 Style Rules 中去尋找對應的 selector。
- 因為所有樣式規則可能數量很大,而且絕大多數不會匹配到當前的 DOM 元素(因為數量很大所以一般會建立規則索引樹),所以有一個快速的方法來判斷「這個 selector 不匹配當前元素」就是極其重要的。
- 如果正向解析,例如「div div p em」,我們首先就要檢查當前元素到 html 的整條路徑,找到最上層的 div,再往下找,如果遇到不匹配就必須回到最上層那個 div,往下再去匹配選擇器中的第一個 div,回溯若干次才能確定匹配與否,效率很低。
- 逆向匹配則不同,如果當前的 DOM 元素是 div,而不是 selector 最后的 em,那只要一步就能排除。只有在匹配時,才會不斷向上找父節點進行驗證。
- 但因為匹配的情況遠遠低于不匹配的情況,所以逆向匹配帶來的優勢是巨大的。同時我們也能夠看出,在選擇器結尾加上「*」就大大降低了這種優勢,這也就是很多優化原則提到的盡量避免在選擇器末尾添加通配符的原因。
文檔說明
此文檔的所有資源都是來源網絡僅在此做了分類整理備忘持續更新,所有精華之處并非原創,所有原創之處并不優秀。
參考鏈接
- js中的window.onload和jquery中的load區別的講解
- CSS阻塞與JS阻塞
- script之defer&async
- 使用Chrome DevTools的Timeline和Profiles提高Web應用程序的性能
- Sizzle引擎
- markdown