(轉)7 天打造前端性能監控系統
引言
前陣子在w3ctech的走進名企 - 百度前端 FEX 專場上曾“誇下海口”說聽完講座後七天就可以打造自己的前端性能監控系統,既然說出去了也不能食言。從前一篇文章前端數據之美相信大家對前端數據有了一定的了解,下面就針對其中的性能數據及其監控進行詳細闡述。
開始行動
本文中的性能主要指 web 頁面加載性能,對性能還不了解?不用擔心,接下來的“每一天”跟我一起進入前端性能的世界。
Day 1 為什麽要監控性能?
“If you cannot measure it, you cannot improve it” ———— William Thomson
這是一個最基本的問題,為什麽要關註和監控前端性能?對於公司來說,性能在一定程度上與利益直接相關。國外有很多這方面的調研數據:
性能 | 收益 |
---|---|
Google 延遲 400ms | 搜索量下降 0.59% |
Bing 延遲 2s | 收入下降 4.3% |
Yahoo 延遲 400ms | 流量下降 5-9% |
Mozilla 頁面打開減少 2.2s | 下載量提升 15.4% |
Netflix 開啟 Gzip | 性能提升 13.25% 帶寬減少50% |
數據來源:http://www.slideshare.net/bitcurrent/impact-of-web-latency-on-conversion-rates http://stevesouders.com/docs/jsdayit-20110511.pptx
為什麽性能會影響公司的收益呢?根本原因還是在於性能影響了用戶體驗。加載的延遲、操作的卡頓等都會影響用戶的使用體驗。尤其是移動端,用戶對頁面響應延遲和連接中斷的容忍度很低。想象一下你拿著手機打開一個網頁想看到某個信息卻加載半天的心情,你很可能選擇直接離開換一個網頁。谷歌也將頁面加載速度作為 SEO 的一個權重,頁面加載速度對用戶體驗和 SEO 的影響的調研有很多。
盡管性能很重要,開發叠代過程中難免會有所忽視,性能會伴隨產品的叠代而有所衰減。特別在移動端,網絡一直是一個很大的瓶頸,而頁面卻越來越大,功能越來越復雜。並沒有簡單的幾條黃金規則就可以搞定性能優化工作,我們需要一套性能監控系統持續監控、評估、預警頁面性能狀況、發現瓶頸,指導優化工作的進行。
Day 2 有什麽可用的工具?
工欲善其事必先利其器
頁面性能的評估與監控有很多成熟優秀的工具,合理利用已有工具能達到事半功倍的效果。下面簡單介紹幾個常用的工具:
Page Speed
Page Speed 是谷歌開發的分析和優化網頁的工具,可以作為瀏覽器插件使用。工具基於一系列優化規則對網站進行檢測,對於未通過的規則會給出詳細的建議。與此類似的工具還有 Yslow 等,推薦使用gtmetrix網站同時查看多個分析工具的結果,如下圖所示:
WebPagetest
WebPageTest 是一款非常優秀的網頁前端性能測試工具,已開源。可以使用在線版,也可以自己搭建。國內也有利用 WebPagetest 搭建的性能測試平臺,推薦使用阿裏測 (以下示例使用阿裏測進行測試)。
使用 WebPagetest,你可以詳細掌握網站加載過程中的瀑布流、性能得分、元素分布、視圖分析等數據。其中比較直觀的視圖分析功能可以直接看到頁面加載各個階段的截屏:
註
: 整個測試結果請點擊此處
上圖直觀地展現了瀏覽類網站兩個重要的時間點:白屏時間和首屏時間,即用戶多久能在頁面中看到內容,以及多久首屏渲染完成(包含圖片等元素加載完成)。這兩個時間點直接決定了用戶需要等待多久才能看到自己想看到的信息。谷歌優化建議中也提到減少非首屏使用的 css 及 JS,盡快讓首屏呈現。
PhantomJS
PhantomJS輕松地將監控帶入了自動化的行列。Phantom JS 是一個服務器端的 JavaScript API 的 WebKit,基於它可以輕松實現 web 自動化測試。PhantomJS 需要一定編程工作,但也更靈活。官方文檔中已經有一個完整的獲取網頁加載 har 文件的示例,具體說明可以查看此文檔,國內也有不少關於此工具的介紹。另外新浪@貘吃饃香開發的類似工具berserkJS也挺不錯,還貼心的提供了首屏統計的功能,具體文章可以查看此處。
Day 3 開始線上真實用戶性能監控
取其所長,避其所短
到此肯定有同學問,既然有這麽多優秀的工具,為什麽要監控線上用戶真實訪問性能呢?
我們發現,工具模擬測試會在一定程度上與真實情況偏離,有時無法反映性能的波動情況。另外除了白屏首屏之類的基礎指標,產品線同樣關註產品相關的指標,例如廣告可見、搜索可用、簽到可用等,這些功能直接與頁面 JS 加載相關,通過工具較難模擬。
為了持續監控不同網絡環境下用戶訪問情況與頁面各功能可用狀況,我們選擇在頁面中植入 JS 來監控線上真實用戶訪問性能,同時利用已有的分析工具作為輔助,形成一套完整多元的數據監控體系,為產品線的評估與優化提供可靠的數據。
關於不同監控方式的簡單對比可以查看下表:
類型 | 優點 | 缺點 | 示例 |
---|---|---|---|
非侵入式 | 指標齊全、客戶端主動監測、競品監控 | 無法知道性能影響用戶數、采樣少容易失真、無法監控復雜應用與細分功能 | Pagespeed、PhantomJS、UAQ |
侵入式 | 真實海量用戶數據、能監控復雜應用與業務功能、用戶點擊與區域渲染 | 需插入腳本統計、網絡指標不全、無法監控競品 | DP 、Google 統計 |
Day 4 如何采集性能數據?
監控用戶的痛點
線上監控哪些指標呢?如何更好地反映用戶感知?
對於用戶來說他感覺到的為什麽頁面打不開、為什麽按鈕點擊不了、為什麽圖片顯示這麽慢。而對於工程師來說,可能關註的是 DNS 查詢、TCP 連接、服務響應等瀏覽器加載過程指標。我們根據用戶的痛點,將瀏覽器加載過程抽取出四個關鍵指標,即白屏時間、首屏時間、用戶可操作、總下載時間(定義可見上篇文章)。這些指標是如何統計的呢?
確定統計起點
我們需要在用戶輸入 URL 或者點擊鏈接的時候就開始統計,因為這樣才能衡量用戶的等待時間。如果你的用戶高端瀏覽器占比很高,那麽可以直接使用Navigation Timing接口來獲取統計起點以及加載過程中的各個階段耗時。另外也可以通過 cookie 記錄時間戳的方式來統計,需要註意的是 Cookie 方式只能統計到站內跳轉的數據。
統計白屏時間
白屏時間是用戶首次看到內容的時間,也叫做首次渲染時間,chrome 高版本有 firstPaintTime 接口來獲取這個耗時,但大部分瀏覽器並不支持,必須想其他辦法來監測。仔細觀察 WebPagetest 視圖分析發現,白屏時間出現在頭部外鏈資源加載完附近,因為瀏覽器只有加載並解析完頭部資源才會真正渲染頁面。基於此我們可以通過獲取頭部資源加載完的時刻來近似統計白屏時間。盡管並不精確,但卻考慮了影響白屏的主要因素:首字節時間和頭部資源加載時間。
如何統計頭部資源加載呢?我們發現頭部內嵌的 JS 通常需等待前面的 JS\CSS 加載完才會執行,是不是可以在瀏覽器 head 內底部加一句 JS 統計頭部資源加載結束點呢?可以通過一個簡單的示例進行測試:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8"/>
<script>
var start_time = +new Date; //測試時間起點,實際統計起點為 DNS 查詢
</script>
<!-- 3s 後這個 js 才會返回 -->
<script src="script.php"></script>
<script>
var end_time = +new Date; //時間終點
var headtime = end_time - start_time; //頭部資源加載時間
console.log(headtime);
</script>
</head>
<body>
<p>在頭部資源加載完之前頁面將是白屏</p>
<p>script.php 被模擬設置 3s 後返回,head 底部內嵌 JS 等待前面 js 返回後才執行</p>
<p>script.php 替換成一個執行長時間循環的 js 效果也一樣</p>
</body>
</html>
經測試發現,統計的頭部加載時間正好跟頭部資源下載時間相近,而且換成一個執行時間很長的 JS 也會等到 JS 執行完才統計。說明此方法是可行的(具體原因可查看瀏覽器渲染原理及 JS 單線程相關介紹)。
統計首屏時間
首屏時間的統計比較復雜,因為涉及圖片等多種元素及異步渲染等方式。觀察加載視圖可發現,影響首屏的主要因素的圖片的加載。通過統計首屏內圖片的加載時間便可以獲取首屏渲染完成的時間。統計流程如下:
首屏位置調用 API 開始統計 -> 綁定首屏內所有圖片的 load 事件 -> 頁面加載完後判斷圖片是否在首屏內,找出加載最慢的一張 -> 首屏時間
這是同步加載情況下的簡單統計邏輯,另外需要註意的幾點:
- 頁面存在 iframe 的情況下也需要判斷加載時間
- gif 圖片在 IE 上可能重復觸發 load 事件需排除
- 異步渲染的情況下應在異步獲取數據插入之後再計算首屏
- css 重要背景圖片可以通過 JS 請求圖片 url 來統計(瀏覽器不會重復加載)
- 沒有圖片則以統計 JS 執行時間為首屏,即認為文字出現時間
統計用戶可操作和總下載
用戶可操作默認可以統計domready時間,因為通常會在這時候綁定事件操作。對於使用了模塊化異步加載的 JS 可以在代碼中去主動標記重要 JS 的加載時間,這也是產品指標的統計方式。
總下載時間默認可以統計onload時間,這樣可以統計同步加載的資源全部加載完的耗時。如果頁面中存在很多異步渲染,可以將異步渲染全部完成的時間作為總下載時間。
網絡指標
網絡類型判斷
對於移動端來說,網絡是頁面加載速度最大的影響因素,需要根據不同的網絡來采取相應的優化措施,例如對於 2G 用戶采用簡版等。但 web 上沒有接口獲取用戶的網絡類型。為了獲取用戶網絡類型,可以通過測速的方式來判斷不同 IP 段對應的網絡。測速例如比較經典的有 facebook 的方案。經過測速後的分析,用戶的加載速率有明顯的分布區間,如下圖所示:
各個分布區間正好對應不同的網絡類型,經過與客戶端的輔助測試,成功率可以在 95%以上。有了這個 IP 庫對應的速率數據,就可以在分析用戶數據時根據 IP 來判斷用戶網絡類型。
網絡耗時統計
網絡耗時數據可以借助前面提到 Navigation Timing 接口獲取,與之類似的還有Resource Timing,可以獲取頁面所有靜態資源的加載耗時。通過此接口可以輕松獲取 DNS、TCP、首字節、html 傳輸等耗時,Navigation Timing 的接口示意圖如下所示:
以上重點介紹了數據采集部分,這也是系統中最關鍵的一部分,只有保證數據能真實反映用戶感知,才能對癥下藥提升用戶體驗。數據采集完之後我們可以在頁面加載完之後統一上報,如示例:
http://xxx.baidu.com/tj.gif?dns=100&ct=210&st=300&tt=703&c_dnslookup=0&c_connecting=0&c_waiting=296&c_receiving=403&c_fetch_dns=0&c_nav_dns=75&c_nav_fetch=75&drt=1423&drt_end=1436<=3410&c_nfpt=619&nav_type=0&redirect_count=0&_screen=1366*768|1366*728&product_id=10&page_id=200&_t=1399822334414
### Day 5 如何分析性能數據?
讓數據會說話
而數據分析過程,如前一篇文章所述,可以從多個維度去分析數據。大數據處理需要借助 hadoop、Hive 等方式,而對於普通站點則任意一種後端語言處理即可。
均值與分布
均值與分布是數據處理中最常見的兩種方式。因為它能直觀的表示指標的趨勢與分布狀況,方便進行評估、瓶頸發現與告警。處理過程中應去除異常值,例如明顯超過閾值的臟數據等。
耗時的評估中,有很多這方面的研究數據。例如有人提出三個基本的時間範圍:
- 0.1秒 : 0.1 秒是用戶感知的最小粒度,在這個時間範圍內完成的操作被認為是流暢沒有延遲的
- 1.0秒 : 1.0 秒內完成的響應認為不會幹擾用戶的思維流。盡管用戶能感覺到延遲,但 0.1 秒 -1.0 秒內完成的操作並不需要給出明顯 loading 提示
- 10秒 : 達到 10 秒用戶將無法保持註意力,很可能選擇離開做其他事情
我們根據業界的一些調研,結合不同指標的特點,制定了指標的分布評估區間。如下圖所示:
評估區間的制定方便我們了解當前性能狀況,同時對性能趨勢波動做出反應。
多維分析
為了方便挖掘性能可能的瓶頸,需要從多維的角度對數據進行分析。例如移動端最重要的維度就是網絡,數據處理上除了總體數據,還需要根據網絡類型對數據進行分析。常見的維度還有系統、瀏覽器、地域運營商等。我們還可以根據自身產品的特點來確定一些維度,例如頁面長度分布、簡版炫版等。
需要註意的是維度並不是越多越好,需要根據產品的特點及終端來確定。維度是為了方便查找性能瓶頸。
小插曲 :之前從微博中看到有人評價說想做監控但是公司沒有日誌服務器。並不需要單獨的日誌服務器,只要能把統計的這個請求訪問日誌保存下來即可。如果網站自己的獨立服務器都沒有還有解決辦法,在百度開發者中心新建一個應用,寫一個簡單的 Web 服務將接收到的統計數據解析存到百度雲免費的數據庫中,然後每天再用 Mysql 處理下當天的數據即可,對於普通站點的抽樣性能數據應該沒問題。請叫我雷鋒。
Day 6 如何利用監控數據解決問題?
發現瓶頸,對癥下藥
對於圖表制作,比較出名的有Highcharts,百度開發的Echarts也很不錯。不管使用什麽工具,最關鍵的一點就是讓報表能突出重點,直觀明了。
制作報表前多問幾個如何讓人直觀看到目前狀況和可能存在的問題,哪些地方可以加強,哪些可以去掉,使用是否習慣等。
有了能反映用戶感知的真實世界、並且細分到各個業務功能,有詳細的網絡等輔助數據,我們在解決前端性能上便更加得心應手。監控系統已經對線上訪問狀況有了連續的反饋,根據現有評估與瓶頸選擇對應方案進行優化,最後根據反饋進行調整,相信性能優化不再是個難題。
如何選擇優化方案呢?這又是一個比較大的話題了,好在已經有很多經驗可以借鑒。附錄中就整理了部分性能的學習資料,可以根據需要閱讀學習。
Day 7 總結
通過以上“幾天”的努力,我們可以搭建一個小而美的前端性能監控系統。但這僅僅是開始,前端數據有很多挖掘的價值。性能優化也是一門需要認真學習的課程,為了打造流暢的使用體驗,為了讓用戶更加滿意,趕緊搭建起自己的前端數據平臺吧!
該文寫在w3ctech的走進名企 - 百度前端 FEX 專場之後,分享時的 PPT 在這裏,視頻在這裏。
華麗非分割線 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
福利——前端性能學習資料整理
性能準則 ★★★★★
- 雅虎性能軍規、中文文章
- 谷歌性能優化文章 推薦
分析工具 ★★★
入門
- pageSpeed 基於谷歌性能準則的檢測,可瀏覽器安裝插件運行
- Yslow 基於雅虎性能準則的檢測工具,可瀏覽器安裝插件運行
- pageCheck 百度內部開發,指標齊全,支持自動運行
進階
- webPageTest 查看頁面加載瀑布流等數據,進階必備工具
- Chrome 開發者工具 功能強大,值得學習
- PhantomJS 功能強大的分析工具,高手必備瑞士軍刀
- JsPerf JS 執行性能分析網站,誰用誰知道
瀏覽器與 Html 標準 ★★
入門
- 瀏覽器緩存機制
- Navigation Timing、Resource Timing 相關文章請谷歌,必備知識
- DNS 解析過程原理
- 高性能瀏覽器網絡翻譯系列
進階
- SPDY 協議 基於此的 Http2.0 協議即將發布
- 瀏覽器渲染原理 比較難懂,但是非常經典
- Chrome 實現原理學習指南 多益大牛的總結
開發實戰 ★★★★
通用
- 高性能 JavaScript
- writing-fast-memory-efficient-javascript
- Understanding and Solving Internet Explorer Leak Patterns
- 模塊化加載 FIS、SeaJS。FIS 有完善的靜態資源管理和優化方案,推薦。
- 前端性能優化最佳實踐
動畫與渲染
- requestAnimationFrame
- 16ms 的優化
- css、JS不要引起 Repaint & Reflow
移動端開發
- Improving the Performance of your HTML5 App
- Steve Souders
- Creating High-Performance Mobile Websites
- HTML5 Techniques for Optimizing Mobile Performance
- 移動 web 站點優化指南
性能監控 ★★★★
- 監控指標選取
- Complete Web Monitoring - Web Performance at eMetrics
- berserkJS 建立前端性能監控平臺
- NY Web Perf Meetup: Peeling the Web Performance Onion
相關會議 ★★★
- velocity 業內最出名的國際會議之一
- Google I/O
- Qcon
推薦博客 ` ★★★`
- web performance today
- perfplanet
- stevesouders.com
- site-performance-and-optimization
出處:http://fex.baidu.com/blog/2014/05/build-performance-monitor-in-7-days/
(轉)7 天打造前端性能監控系統