隨着網頁的加載,每一個HTTP請求都會是瀑布流中的一條。第一條都是文件document的加載,當文件被解析,隨後一般是CSS文件的加載。和寫在HTML文件中的標籤中的順序是同樣的。但瀏覽器會作一些優化,好比會下降圖片的優先度,提高CSS文件的優先度等。web
在瀑布流下方的表格中,咱們能夠看到請求的Name,Status,Type等信息。Initiator列的意思是,什麼文件需求加載了這一行的文件。按住Shift點擊表格的一行,調用該行文件的相應文件會變綠(who called it?),該行文件調用的相應行會變紅(who does it called?)。chrome
若是咱們點擊Capture Screenshot按鈕,從新加載頁面, 就能夠看到網頁的每次repaint,也就是網頁是如何加載的。瀏覽器
使用這個功能,咱們能夠知道在慢速網絡下,網頁是如何呈現出來的。服務器
Network面板中,咱們能夠點擊文件類型來查看特定類型的文件。左側有個輸入框也能夠輸入特定條件。好比larger-than:200px,就能夠觀察大於200px的圖片請求。網絡
Disable Cache,Offline,Preserve Log三個按鈕的功能是顯而易見的。chrome-devtools
開發者性能測試是在開發環境中作性能測試,可是用戶端是在真實用戶使用的狀況下記錄測試數據。之前是這麼作的:函數
const start = new Date().getTime(); const end = new Date().getTime(); const time = end - start;
這樣咱們就能夠記錄下用戶做出一個操做的時間,而後將數據post回來。工具
後來有了Performance API:oop
performance.mark('start') performance.mark('end); performance.measure('Our Measurement,'start','end'); performance.getEntriesByType('measure')
通常圖片過大的解決方法:佈局
還有一個HTML API要知道,srcset
能夠在不一樣窗口大小的時候加載指定的圖片。
<img srcset="small.jpg 300w, medium.jpg 800w, large.jpg 1200w">
可是爲了瀏覽器兼容性,咱們老是應該給默認的src attribute留一個URL。
現代大多數屏幕刷新率都是60幀每秒。1秒/60 = 16.66毫秒。因此咱們的一個畫面更新的處理時間若是超過了16毫秒,就感受卡。
有一種卡的緣由是由於,解析Javascript的時間過長。V8引擎渲染頁面的時候,須要編譯Javascript,生成AST(Abstract Syntax Tree)。當客戶端的處理性能不好的時候,就要等好久。
還有一種卡的緣由是由於,Layout thrashing,反覆佈局,又稱佈局抖動。
//Read const h1 = element.clientHeight; //Write element1.style.height = (h1 * 2) + 'px'; //Read const h2 = element2.clientHeight; //Write element2.sytle.height = (h2 * 2) + 'px';
當咱們反覆進行這種DOM讀寫操做的時候,就會形成佈局抖動。
若是咱們能夠將讀和寫徹底分開,一次性操做全部讀,一次性操做全部寫,就不會有這種狀況,可是這是不現實的。這就是使用window.requestAnimationFrame()的緣由。
簡單說requestAnimationFrame將讀寫操做和屏幕刷新率匹配起來,當瀏覽器準備好更新下一幀時,作想作的操做,減小性能浪費,避免跳幀。關於這個話題有不少寫Event Loop的文章裏也有寫,這裏很少寫。
在開發者工具中,咱們在更多工具中能夠找到Rendering的選項。
打開這個選項,頁面每次repaint的地方都會變成綠色,幫助開發者觀察是否一些不必重繪的地方在不停的被重繪,浪費性能。
咱們點擊錄製按鈕,在頁面上作一些操做,好比Scroll。Performance面板中就會有一些數據。
最下方有一個餅狀圖是一個歸納總結。
展開Main行,X軸表明處理時間,Y軸是Call Stack。Y軸高不要緊,只是函數之間不斷的調用,可是若是有色塊很寬的話就說明處理時間很長。
咱們可使用WASD來操做。按W Zoom In能夠看到具體信息。
找到一個很寬的色塊,看以前是哪一個色塊調用了這個色塊,而後咱們就能夠在下方Summary面板中找到具體文件名,點擊去Sources面板看代碼。
當一些內存沒有按開發者的意願被釋放的時候,就出現了內存泄漏。
function foo() { bar = "Hi" }
當foo被調用的時候,由於bar沒有變量聲明關鍵詞const, var, let。JS就會一直向上找這個變量到全局做用域,而後會爲你建立一個全局變量bar。當這個函數結束的時候,你覺得這個bar會被回收,但其實它一直留在全局。設想若是這個bar不是「Hi」而是一個擁有不少元素的array,它留在了全局做用域,這並非咱們想要的狀況。
顧名思義,計時器沒有被取消或移除。
const button = document.getElementById('button); document.body.removeChild( document.getElementById('button) ); }
這裏咱們在DOM中移除了這個button,可是以前指向這個元素的reference還在,就是變量button。因此這個reference就留在了內存中。
打開Chrome的任務管理器,確保Javascript Memory列有顯示。咱們能夠看到每一個標籤頁的內存使用狀況。若是有一個標籤頁的內存使用不穩定,一直在上升,說明出現了內存泄漏。
在Performance面板記錄下的數據中,若是咱們打勾Memory選項,咱們就能夠看到Memory行。若是線圖不停的上升,就說明出現了內存泄漏。
在開發者工具的Memory面板中,咱們能夠選擇Heap Snapshot,記錄一個當前頁面具體內存使用狀況的快照。注意Shallow Size列和Retained Size列。
Shallow Size是對象自身佔用內存的大小,而Retained Size是指咱們移除Object後能得到多少空間,也就是將對象自己和連同的相關對象一塊兒刪除後釋放的內存大小。好比一個變量指向一個很大的Object,這個變量自己是個reference很小(Shallow Size很小),可是移除這個變量之後,咱們就能夠得到很大的空間(Retained Size很大)。
咱們能夠根據Shallow Size給Heap Snapshot排序,找到佔用內存最多的對象,若是不確認是不是內存泄漏,能夠再記錄一個Heap Snapshot作對比。若是該對象的Shallow Size增加了,說明確實出現了內存泄漏。咱們能夠根據工具給的提示信息,找到開發代碼片斷作修改。
如今的Audit面板整合了谷歌的Lighthouse服務。網上還有一些其餘不錯的第三方服務如webpagetest, sonarwhal。