性能優化是前端領域一個亙古不變的熱點話題。本系列文章將分監控、加載性能優化和運行時性能優化三章從實踐角度來作具體分享
想要優化就必須得有度量。有了監控才能客觀、系統地進行分析性能瓶頸、驗證優化結果等。因此咱們先從如何完整地監控開始前端
前端性能又分爲加載性能和運行時性能git
加載性能就是用戶從進入到頁面到頁面真正可用的這個過程的耗時。咱們能夠用一道經典的面試題入手:用戶從鍵入url按下回車以後到看到頁面這其中發生了什麼?github
而咱們要作的就是記錄這些過程的耗時: 現代瀏覽器提供了 performance
對像供咱們方便地提取這些數據。並且兼容性在這。其中 timing
對象詳細記錄每一個節點的時間戳。 面試
將相關時間節點相減就能獲得相應過程的耗時。 做爲開發,咱們一般更關注從服務器讀取的時間,因此取 fetchStart
爲起點。 下面是一些經常使用的時間計算:算法
const { fetchStart, domainLookupStart, domainLookupEnd, domInteractive, domContentLoadedEventStart } = performance.timing // DNS查找時間 domainLookupEnd - domainLookupStart // 白屏時間 domInteractive - fetchStart // 首屏時間 domContentLoadedEventStart - fetchStart 複製代碼
以上計算時間更多用於SSR渲染,而現在前端現狀還有至關部分是SPA結構,由JS渲染在客戶端。爲了更好地知足監控指標與用戶體驗的契合。Google 提出 FP
/ FCP
/ FMP
/ TTI
等指標幫助咱們統計相關數據,咱們經常使用下面兩條chrome
FCP(First Contentful Paint) 首次繪製任何文本,圖像,非空白canvas或SVG的時間點。就是用戶第一次看到有意義的內容的時間。一般能夠看成這個時間爲白屏時長。獲取APIcanvas
window.performance.getEntriesByType('paint')
TTI(Time To Intercative) 可交互(可用時間), 用於標記應用已進行視覺渲染並能可靠響應用戶輸入的時間點。咱們一般用這個值做爲頁面的首屏時間。瀏覽器並無直接提供api去獲取。可是google提供 github.com/GoogleChrom… 去獲取。api
大部分業務並不須要運行時的監控。可是一些重業務場景,好比說文本編輯器、線上課堂、畫板。頓卡對用戶體驗的傷害巨大,也是用戶更沒法接受的。對於這類業務,咱們開發測試場景能夠用 chrome
的 perfermance
工具去測試、檢測、定位性能頓卡。可是咱們仍然須要用戶測的監控來掌握業務線上實際運行狀況。 requestAnimationFrame
一般用來實現動畫。可是這裏咱們也能夠用來做爲幀率的監控。大概簡單思路以下:瀏覽器
const everyFrameCostTime = [] let timestamp = Date.now() function detect() { const now = Date.now() const cost = now - timestamp timestamp = now everyFrameCostTime.push(cost) requestAnimationFrame(detect) }
當cost 連續幾回 高於一個 特意閾值,就能夠視爲頁面頓卡了。這裏能夠視具體業務場景而定。性能優化
這種也有侷限性,因爲倖存者誤差,當頁面卡死不動,監控代碼自己也不起做用的。
經常使用作法一般用向服務器發送一個img請求,而後將數據拼接成url參數一併發送過去。現代瀏覽器更提供了 navigator.sendBeacon(url, data)
方法來發送數據。在unload場景甚至不會阻塞下個頁面的加載。爲了保證基礎庫的健壯和不影響自己頁面性能。咱們要作好聚合和節流。
當用戶基數過大,或者統計不須要那麼多數據量,能夠對數據發送作隨機控制,來決定本次是否發送數據。或者將埋點數據加密存在本地,須要時在由用戶主動向開發者發送,用來排查問題和減小數據服務器壓力
說個題外話,我在一線互聯網企業工做十餘年裏,指導過很多同行後輩。幫助不少人獲得了學習和成長。
我意識到有不少經驗和知識值得分享給你們,也能夠經過咱們的能力和經驗解答你們在IT學習中的不少困惑,因此在工做繁忙的狀況下仍是堅持各類整理和分享。
我能夠將最近整理的前端面試題免費分享出來,其中包含HTML、CSS、JavaScript、服務端與網絡、Vue、瀏覽器、數據結構與算法等等,還在持續整理更新中,但願你們都能找到心儀的工做。
篇幅有限,僅展現部分截圖: