前端性能優化之性能測試

前端性能優化是一個很寬泛的概念,有很多教程都有前端性能優化的方法,這也是我們一直在關注的一件重要事情。配合各種方式、手段、輔助系統,前端優化的最終目的都是提升用戶體驗,改善頁面性能,我們常常竭盡全力進行前端頁面優化,但卻忽略了這樣做的效果和意義。先不急于探究前端優化具體可以怎樣去做,先看看什么是前端性能,應該怎樣去了解和評價前端頁面的性能。

通常前端性能可以認為是用戶獲取所需要頁面數據或執行某個頁面動作的一個實時性指標,一般以用戶希望獲取數據的操作到用戶實際獲得數據的時間間隔來衡量。例如用戶希望獲取數據的操作是打開某個頁面,那么這個操作的前端性能就可以用該用戶操作開始到屏幕展示頁面內容給用戶的這段時間間隔來評判。用戶的等待延時可以分成兩部分:可控 等待延時和 不可控 等待延時。可控 等待延時可以理解為能通過技術手段和優化來改進縮短時間的部分,例如減小圖片大小讓請求加載更快、減少 HTTP 請求數等。不可控 等待延時則是不能或很難通過前后端技術手段來改進優化的,例如鼠標點擊延時、CPU 計算時間延時、ISP(Internet Service Provider,互聯網服務提供商) 網絡傳輸延時等。所以要知道的是,前端中的所有優化都是針對 可控等待延時 這部分來進行的,下面來了解一下如何獲取和評價一個頁面的具體性能。

前端性能測試

獲取和衡量一個頁面的性能,主要可以通過以下幾個方面:Performance Timing APIPrpfile 工具、頁面埋點計時、資源加載時序圖分析。

Performance Timing API

Performance Timing API 是一個支持 Internet Explorer 9 以上版本及 WebKit 內核瀏覽器中用于記錄頁面加載和解析過程中關鍵時間點的機制,它可以詳細記錄每個頁面資源從開始加載到解析完成這一過程中具體操作發生的時間點,這樣根據開始和結束時間戳就可以計算出這個過程所花的時間了。

1-1W3C標準中 Performance Timing 資源加載和解析過程記錄各個關鍵點的示意圖,瀏覽器中加載和解析一個 HTML 文件的詳細過程先后經歷 unload、redirect、App Cache、DNS、TCP、Request、Response、Processing、onload 幾個階段,每個過程中開始和結束的關鍵時間戳瀏覽器已經使用 performance.timing 來記錄了,所以根據這個記錄并結合簡單的計算,我們就可以得到頁面中每個過程所消耗的時間。

???????????????????????????????????????????????????????????????????圖1-1????Performance Timing API 關鍵時間點記錄

function performanceTest(){let timing = performance.timing,readyStart = timing.fetchStart - timing.navigationStart,redirectTime = timing.redirectEnd - timing.redirectStart,appcacheTime = timing.domainLookupStart - timing.fetchStart,unloadEventTime = timing.unloadEventEnd - timing.unloadEventStart,lookupDomainTime = timing.domainLookupEnd - timing.domainLookupStart,connectTime = timing.connectEnd - timing.connectStart,requestTime = timing.responseEnd - timing.requestStart,initDomTreeTime = timing.domInteractive - timing.responseEnd,domReadyTime = timing.domComplete - timing.domInteractive,loadEventTime = timing.loadEventEnd - timing.loadEventStart,loadTime = timing.loadEventEnd - timing.navigationStart;console.log('準備新頁面時間耗時:'+readyStart);console.log('redirect 重定向耗時:'+redirectTime);console.log('Appcache 耗時'+appcacheTime);console.log('unload 前文檔耗時:'+unloadEventTime);console.log('DNS 查詢耗時:'+lookupDomainTime);console.log('TCP 連接耗時:'+connectTime);console.log('request 請求耗時:'+requestTime);console.log('請求完畢至DOM加載:'+initDomTreeTime);console.log('解析DOM樹耗時:'+domReadyTime);console.log('Load事件耗時:'+loadEventTime);console.log('加載時間耗時:'+loadTime);
}
復制代碼

通過上面的時間戳計算可以得到幾個關鍵步驟所消耗的時間,對前端有意義的幾個過程主要是解析 DOM 樹耗時、load 事件耗時和整個加載過程耗時等,不過在頁面性能獲取時我們可以盡量獲取更詳細的數據信息,以供后面分析。除了資源加載解析的關鍵點計時,preformance 還提供了一些其他方面的功能,我們可以根據具體需要進行選擇使用。

performance.memory      //內存占用的具體數據
performance.now()       //performance.now()方法返回當前網頁自performance.timing到現在的時間,可以精確到微秒,用于更加精確的計數。但實際上,目前網頁性能通過毫秒來計算就足夠了
performance.getEntries()        //獲取頁面所有加載資源的performance timing 情況。瀏覽器獲取網頁時,會對網頁中每一個對象(腳本文件、樣式表、圖片文件等)發出一個HTTP請求。performance.getEntries 方法以數組形式返回所有請求的時間統計信息
performance.navigation      //performance 還可以提供用戶行為信息,例如網絡請求的類型和重定向次數等,一般都存放在performance.navigation對象里面
performance.navigation.redirectCount        //記錄當前網頁重定向跳轉的次數
復制代碼

Profile 工具

Performance Timing API 描述了頁面資源從加載到解析各個階段的執行關鍵點時間記錄,但是無法統計 JavaScript 執行過程中系統資源的占用情況。ProfileChromeFirefox 等標準瀏覽器提供的一種用于測試頁面腳本運行時系統內存和 CPU 資源占用情況的 API,以 Chrome 瀏覽器為例,結合 Profile,可以實現以下幾個功能。

??????1.分析頁面腳本執行過程中最耗資源的操作

??????2.記錄頁面腳本執行過程中 JavaScript 對象消耗的內存與堆棧的使用情況

??????3.檢測頁面腳本執行過程中 CPU 占用情況

使用 console.profile()console.profileEnd() 就可以分析中間一段代碼執行時系統的內存或 CPU 資源的消耗情況,然后配合瀏覽器的 Profile 查看比較消耗系統內存或 CPU 資源的操作,這樣就可以有針對性的進行優化了。

console.profile();
//TODOS,需要測試的頁面邏輯動作
for(let i = 0; i < 100000; i ++){console.log(i * i);
}
console.profileEnd();
復制代碼

頁面埋點計時

使用Profile可以在一定程度上幫助我們分析頁面的性能,但缺點是不夠靈活。實際項目中,我們不會多關注頁面的內存或CPU資源的消耗情況,因為JavaScript有自動內存回收機制。我們關注更多的是頁面腳本邏輯執行的時間。除了Performance Timing 的關鍵過程耗時計算,我們還希望檢測代碼的具體解析或執行時間,這就不能寫很多的console.profile()console.profileEnd()來逐段實現,為了更加簡單地處理這種情況,往往選擇通過腳本埋點計時的方式來統計沒部分代碼的運行時間。

頁面 JavaScript 埋點計時比較容易實現,和 Performance Timing 記錄時間戳有點類似,我們可以記錄 JavaScript 代碼開始執行的時間戳,后面在需要記錄的地方埋點記錄結束時的時間戳,最后通過差值來計算一段 HTML 解析或 JavaScript 解析執行的時間。為了方便操作,可以將某個操作開始和結束的時間戳記錄到一個數組中,然后分析數組之間的間隔就得到每個步驟的執行時間,下面來看一個時間點記錄和分析的例子。

let timeList = [];
function addTime(tag) {timeList.push({"tag":tag,"time":+new Date()});}addTime("loading");timeList.push({"tag":"load","time":+new Date()});
//TODOS,load加載時的操作
timeList.push({"tag":"load","time":+new Date()});timeList.push({"tag":"process","time":+new Date()});
//TODOS,process處理時的操作
timeList.push({"tag":"process","time":+new Date()});console.log(parseTime(timeList));	//輸出{load:時間毫秒數,process: 時間毫秒數}function parseTime(time) {let timeStep={},endTime;for(let i = 0,len = time.length; i < len; i ++){if(!time[i]) continue;endTime = {};for(let j = i+1; j < len; j++){if(time[j] && time[i].tag == time[j].tag){endTime.tag = time[j].tag;endTime.time = time[j].time;time[j] = null;}}if(endTime.time >= 0 && endTime.tag){timeStep[endTime.tag] = endTime.time - time[i].time;}}return timeStep;
}
復制代碼

這種方式常常在移動端頁面中使用,因為移動端瀏覽器 HTML 解析和 JavaScript 執行相對較慢,通常為了性能優化,我們需要找到頁面中執行 JavaScript 耗時的操作,如果將關鍵 JavaScript 的執行過程進行埋點計時并上報,就可以輕松找出 JavaScript 執行慢的地方,并有針對性地進行優化。

資源加載時序圖

我們還可以借助瀏覽器或其他工具的資源加載時序圖來幫助分析頁面資源加載過程中的性能問題。這種方法可以粗粒度地宏觀分析瀏覽器的所有資源文件請求耗時和文件加載順序情況,如保證 CSS 和數據請求等關鍵資源優先加載,JavaScript 文件和頁面中非關鍵性圖片等內容延后加載。如果因為某個資源的加載十分耗時而阻塞了頁面的內容展示,那就要著重考慮。所以,我們需要通過資源加載時序圖來輔助分析頁面上資源加載順序的問題。

1-2 為使用 Fiddler 抓取瀏覽器訪問地址時的資源加載時序圖,圖 1-3Chrome 瀏覽器訪問貓眼電影官網時的資源加載時序圖.根據資源加載時序圖我們可以很直觀地看到頁面上各個資源加載過程所需要的時間和先后順序,有利于找出加載過程中比較耗時的文件資源,幫助我們有針對性地進行優化。

???????????????????????????????????????????????????????????????????圖1-2????Fiddler 頁面加載文件資源時序圖

????????????????????????????????????????????????????????圖1-3????Chrome瀏覽器 貓眼電影官網頁面加載文件資源時序圖

總結

通過上文介紹的利用Performance Timing APIPrpfile工具、頁面埋點計時、資源加載時序圖分析幾個方面來獲取和衡量一個頁面的性能,找出加載過程中比較耗時的文件資源,幫助我們有針對性地進行優化。醫病必須診斷找到病因,前端性能測試在前端性能優化中屬于診斷工作,只有找到病因,才能進行針對性治療優化。在此歡迎大家加入QQ前端技術交流群 544587175 ,在后續我會從桌面瀏覽器和移動端瀏覽器兩個方面詳細講解不同終端的優化策略,敬請關注......

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/453255.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/453255.shtml
英文地址,請注明出處:http://en.pswp.cn/news/453255.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

模擬傳輸和數字傳輸的優缺點

與模擬數據通信相比較&#xff0c;數字數據通信具有下列優點&#xff1a; a. 來自聲音、視頻和其他數據源的各類數據均可統一為數字信號的形式&#xff0c;并通過數字通信系統傳輸 b. 以數據幀為單位傳輸數據&#xff0c;并通過檢錯編碼和重發數據幀來發現與糾正通信錯誤&am…

android瀏覽SD卡的文件,簡單實現瀏覽Android SD卡中的文件

----Main.javapublic class Main extends Activity {private TextView textView;private Button button;private ListView listView;public File currentParentFile;public File[] currentFiles;public static String sdcardDir ;static {try {//sd卡的路徑sdcardDir Environ…

Java線程狀態Jstack線程狀態BLOCKED/TIMED_WAITING/WAITING解釋

一、線程5種狀態 新建狀態&#xff08;New&#xff09; 新創建了一個線程對象。 就緒狀態&#xff08;Runnable&#xff09; 線程對象創建后&#xff0c;其他線程調用了該對象的start()方法。該狀態的線程位于可運行線程池中&#xff0c;變得可運行&#xff0c;等待獲取CPU的使…

彩票相關知識

很多人做夢都想中得彩票頭獎&#xff0c;很多人希望天上能掉下餡餅來砸中自己&#xff0c;很多人在作白日夢……彩票是一種風險投資&#xff0c;是一種四兩撥千斤的氣勢&#xff0c;更是一種眾人拾柴火焰高的真實寫照&#xff0c;沒買過彩票的人是很難體會那種美好的期望及期望…

(模擬信號/數字信號)分別以(模擬信號/數字信號)中傳輸方式

1、基本概念、基本術語和數據通信系統 1.基本概念和基本術語 數據&#xff1a;能夠由計算機處理的數字、字母和符號等具有一定意義的實體。 分類&#xff1a;模擬數據可以在一定的數據區域中取連續的值&#xff0c;如聲音和圖像&#xff1b;數字數據只能取離散的數值&#xff0…

C# 獲取文件名及擴展名

C#通過文件路徑獲取文件名 string fullPath "/WebSite1/Default.aspx";string filename System.IO.Path.GetFileName(fullPath);//文件名 “Default.aspx” string extension System.IO.Path.GetExtension(fullPath);//擴展名 “.aspx” string fileNameWithoutEx…

android11 rom,小米打造基于安卓11的ROM來了:米10嘗鮮

原標題&#xff1a;小米打造基于安卓11的ROM來了&#xff1a;米10嘗鮮據XDA報道&#xff0c;距離Android 11正式版發布還有幾天時間&#xff0c;9月8日正式面向Pixel 2、Pixel 3、Pixel 4和Pixel 3a等機型推送Android 11正式版。另一方面&#xff0c;各大手機品牌已經緊鑼密鼓開…

基于 HTML5 WebGL 的 3D 服務器與客戶端的通信

這個例子的初衷是模擬服務器與客戶端的通信&#xff0c;我把整個需求簡化變成了今天的這個例子。3D 機房方面的模擬一般都是需要鷹眼來輔助的&#xff0c;這樣找產品以及整個空間的概括會比較明確&#xff0c;在這個例子中我也加了&#xff0c;這篇文章就算是我對這次項目的一個…

什么是順序執行以及其特點

順序執行是程序的一種執行方式。是把一個具有獨立功能的程序獨占處理機直至最終結束的過程稱為程序的順序執行 順序執行的特點&#xff1a;順序性&#xff1a;程序順序執行時&#xff0c;其執行過程可看作一系列嚴格按程序規定的狀態轉移過程&#xff0c;也即是每執行一條指令&…

一年成為Emacs高手(像神一樣使用編輯器)

作者: 陳斌(redguardtoo) 更新時間: 2012-02-10 五 原創時間: 2012-01-31 周二 15:08 很容易.一年多前我還在Vi陣營,偶爾使用Emacs還總是忘記退出(C-x C-c)的快捷鍵,但是一年后我跨入高手行列. 現在網上很多中文文章都是和你強調Emacs有多牛,以激發你的興趣.最有名的大概是王垠…

七種常見的核酸序列蛋白編碼能力預測工具 | ncRNAs | lncRNA

注&#xff1a;這些工具的應用都是受限的&#xff0c;有些本來就是只能用于預測動物&#xff0c;在使用之前務必用ground truth數據來測試一些。我想預測某一個植物的轉錄本&#xff0c;所以可以拿已經注釋得比較好的擬南芥來測試一下。&#xff08;測試的結果還是比較驚人的&a…

android預覽界面編譯出錯,Android O預覽findViewById編譯錯誤

我試圖測試Android O Developer Preview的第二階段。 項目創建后&#xff0c;我只是點擊了構建并運行但我沒有任何成功。Android默認生成的代碼如下&#xff1a;Toolbar toolbar (Toolbar) findViewById(R.id.toolbar);發生編譯錯誤。Error:(18, 37) error: reference to find…

中斷與異常的區別

中斷&#xff1a; 中斷是CPU&#xff08;硬件&#xff09;所具備的功能 &#xff0c;它是指系統停止當前正在運行的程序而轉向其他服務&#xff0c;可能是因 為優先級高的請求服務了&#xff0c;或者是因為人為安排中斷。中斷是屬于正常現象。主要由CPU以外的事件引起的 中斷…

寒武紀找到了引領中國AI芯片走向世界的路

大約6億年前在地質學上被稱作“寒武紀”的時代&#xff0c;大量無脊椎動物在短時間內出現“生命大爆發”。如今&#xff0c;“寒武紀”這個名字再次被人們提及&#xff0c;它源自中科院計算所研發的人工智能芯片處理器的命名&#xff0c;意喻人工智能即將迎來大爆發的時代。“寒…

淺談PPM (Project Portfolio Management)

前言&#xff1a; 本文以純理論性的PPM講解為主&#xff0c;不會涉及到具體如何實施&#xff0c;我會在以后介紹詳細的PPM實施方案介紹。 PPM&#xff0c;可能很多人并不清楚甚至可能沒聽說過&#xff0c;這是一個近些年才流行起來的概念&#xff0c;是Project Portfolio Mana…

poj 3071 Football

http://poj.org/problem?id3071 2^n 支足球隊比賽&#xff0c;共比n場&#xff0c;第一場1號與2號比&#xff0c;3號與4號比…… 每場勝出者進入下一場&#xff0c;輸者淘汰 每一場都是相鄰的兩個隊伍比拼 已知任意兩個隊伍比拼獲勝的概率 求最后哪只隊伍獲勝的概率最大 dp[i]…

進程調度與作業調度

進程調度是真正讓某個就緒狀態的進程到處理機上運行&#xff0c;而作業調度只是使作業具有了競爭處理機的機會。進程調度&#xff08;又稱微觀調度、低級調度、短程調度&#xff09;&#xff1a; 是按照某種調度算法從就緒狀態的進程中選擇一個進程到處理機上運行。負責進程調…

tensorflow源碼安裝

主要參考&#xff1a;https://www.tensorflow.org/install/install_sources#ConfigureInstallation卸載tensorflow sudo pip uninstall tensorflow 安裝git 安裝git時記得先安裝&#xff0c;后更新系統 sudo apt install git安裝jdk8: myubuntu:~$ java myubun…

Makefile學習之通配符和自動變量

規則中的通配符 “*” &#xff0c;“&#xff1f;” &#xff0c;“ [...]”, " % " , " wildcard " 1.“*” *.c表示所有后綴為.C的文件&#xff1b; 如果文件中用到通配符&#xff0c;使用“\*”; 2.通配符在變量中的使用&#xff1b; objects*.c 注意…

英語中十二個月名稱的由來

轉自網絡&#xff0c;原出處不詳。 公歷一年有12個月&#xff0c;但不少人并不知道12 個月的英語名稱的來歷。公歷起源于古羅馬歷法。羅馬的英語原來只有10 個月&#xff0c;古羅馬皇帝決定增加兩個月放在年尾&#xff0c;后來朱里斯*凱撒大帝把這兩個月移到年初&#xff0c;…