前陣子在w3ctech的走進名企 - 百度前端 FEX 專場上曾「誇下海口」說聽完講座後七天就能夠打造本身的前端性能監控系統,既然說出去了也不能食言。從前一篇文章前端數據之美相信你們對前端數據有了必定的瞭解,下面就針對其中的性能數據及其監控進行詳細闡述。javascript
本文中的性能主要指web頁面加載性能,對性能還不瞭解?不用擔憂,接下來的「每一天」跟我一塊兒進入前端性能的世界。php
「If you cannot measure it, you cannot improve it」 ———— William Thomsoncss
這是一個最基本的問題,爲何要關注和監控前端性能?對於公司來講,性能在必定程度上與利益直接相關。國外有不少這方面的調研數據:html
性能 | 收益 |
---|---|
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的影響的調研有不少。html5
儘管性能很重要,開發迭代過程當中不免會有所忽視,性能會伴隨產品的迭代而有所衰減。特別在移動端,網絡一直是一個很大的瓶頸,而頁面卻愈來愈大,功能愈來愈複雜。並無簡單的幾條黃金規則就能夠搞定性能優化工做,咱們須要一套性能監控系統持續監控、評估、預警頁面性能情況、發現瓶頸,指導優化工做的進行。java
工欲善其事必先利其器git
頁面性能的評估與監控有不少成熟優秀的工具,合理利用已有工具能達到事半功倍的效果。下面簡單介紹幾個經常使用的工具:github
Page Speed是谷歌開發的分析和優化網頁的工具,能夠做爲瀏覽器插件使用。工具基於一系列優化規則對網站進行檢測,對於未經過的規則會給出詳細的建議。與此相似的工具還有Yslow等,推薦使用gtmetrix網站同時查看多個分析工具的結果,以下圖所示:web
WebPageTest是一款很是優秀的網頁前端性能測試工具,已開源。可使用在線版,也能夠本身搭建。國內也有利用WebPagetest搭建的性能測試平臺,推薦使用阿里測 (如下示例使用阿里測進行測試)。
使用WebPagetest,你能夠詳細掌握網站加載過程當中的瀑布流、性能得分、元素分佈、視圖分析等數據。其中比較直觀的視圖分析功能能夠直接看到頁面加載各個階段的截屏:
注: 整個測試結果請點擊此處
上圖直觀地展示了瀏覽類網站兩個重要的時間點:白屏時間和首屏時間,即用戶多久能在頁面中看到內容,以及多久首屏渲染完成(包含圖片等元素加載完成)。這兩個時間點直接決定了用戶須要等待多久才能看到本身想看到的信息。谷歌優化建議中也提到減小非首屏使用的css及JS,儘快讓首屏呈現。
PhantomJS輕鬆地將監控帶入了自動化的行列。Phantom JS是一個服務器端的 JavaScript API 的 WebKit,基於它能夠輕鬆實現web自動化測試。PhantomJS須要必定編程工做,但也更靈活。官方文檔中已經有一個完整的獲取網頁加載har文件的示例,具體說明能夠查看此文檔,國內也有很多關於此工具的介紹。另外新浪@貘吃饃香開發的相似工具berserkJS也挺不錯,還貼心的提供了首屏統計的功能,具體文章能夠查看此處。
取其所長,避其所短
到此確定有同窗問,既然有這麼多優秀的工具,爲何要監控線上用戶真實訪問性能呢?
咱們發現,工具模擬測試會在必定程度上與真實狀況偏離,有時沒法反映性能的波動狀況。另外除了白屏首屏之類的基礎指標,產品線一樣關注產品相關的指標,例如廣告可見、搜索可用、簽到可用等,這些功能直接與頁面JS加載相關,經過工具較難模擬。
爲了持續監控不一樣網絡環境下用戶訪問狀況與頁面各功能可用情況,咱們選擇在頁面中植入JS來監控線上真實用戶訪問性能,同時利用已有的分析工具做爲輔助,造成一套完整多元的數據監控體系,爲產品線的評估與優化提供可靠的數據。
關於不一樣監控方式的簡單對比能夠查看下錶:
類型 | 優勢 | 缺點 | 示例 |
---|---|---|---|
非侵入式 | 指標齊全、客戶端主動監測、競品監控 | 沒法知道性能影響用戶數、採樣少容易失真、沒法監控複雜應用與細分功能 | Pagespeed、PhantomJS、UAQ |
侵入式 | 真實海量用戶數據、能監控複雜應用與業務功能、用戶點擊與區域渲染 | 需插入腳本統計、網絡指標不全、沒法監控競品 | DP 、Google統計 |
監控用戶的痛點
線上監控哪些指標呢?如何更好地反映用戶感知?
對於用戶來講他感受到的爲何頁面打不開、爲何按鈕點擊不了、爲何圖片顯示這麼慢。而對於工程師來講,可能關注的是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事件 -> 頁面加載完後判斷圖片是否在首屏內,找出加載最慢的一張 -> 首屏時間
這是同步加載狀況下的簡單統計邏輯,另外須要注意的幾點:
用戶可操做默承認以統計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
讓數據會說話
而數據分析過程,如前一篇文章所述,能夠從多個維度去分析數據。大數據處理須要藉助hadoop、Hive等方式,而對於普通站點則任意一種後端語言處理便可。
均值與分佈
均值與分佈是數據處理中最多見的兩種方式。由於它能直觀的表示指標的趨勢與分佈情況,方便進行評估、瓶頸發現與告警。處理過程當中應去除異常值,例如明顯超過閾值的髒數據等。
耗時的評估中,有不少這方面的研究數據。例如有人提出三個基本的時間範圍:
咱們根據業界的一些調研,結合不一樣指標的特色,制定了指標的分佈評估區間。以下圖所示:
評估區間的制定方便咱們瞭解當前性能情況,同時對性能趨勢波動作出反應。
多維分析
爲了方便挖掘性能可能的瓶頸,須要從多維的角度對數據進行分析。例如移動端最重要的維度就是網絡,數據處理上除了整體數據,還須要根據網絡類型對數據進行分析。常見的維度還有系統、瀏覽器、地域運營商等。咱們還能夠根據自身產品的特色來肯定一些維度,例如頁面長度分佈、簡版炫版等。
須要注意的是維度並非越多越好,須要根據產品的特色及終端來肯定。維度是爲了方便查找性能瓶頸。
小插曲 :以前從微博中看到有人評價說想作監控可是公司沒有日誌服務器。並不須要單獨的日誌服務器,只要能把統計的這個請求訪問日誌保存下來便可。若是網站本身的獨立服務器都沒有還有解決辦法,在百度開發者中心新建一個應用,寫一個簡單的Web服務將接收到的統計數據解析存到百度雲免費的數據庫中,而後天天再用Mysql處理下當天的數據便可,對於普通站點的抽樣性能數據應該沒問題。請叫我雷鋒。
發現瓶頸,對症下藥
對於圖表製做,比較出名的有Highcharts,百度開發的Echarts也很不錯。無論使用什麼工具,最關鍵的一點就是讓報表能突出重點,直觀明瞭。
製做報表前多問幾個如何讓人直觀看到目前情況和可能存在的問題,哪些地方能夠增強,哪些能夠去掉,使用是否習慣等。
有了能反映用戶感知的真實世界、而且細分到各個業務功能,有詳細的網絡等輔助數據,咱們在解決前端性能上便更加駕輕就熟。監控系統已經對線上訪問情況有了連續的反饋,根據現有評估與瓶頸選擇對應方案進行優化,最後根據反饋進行調整,相信性能優化再也不是個難題。
如何選擇優化方案呢?這又是一個比較大的話題了,好在已經有不少經驗能夠借鑑。附錄中就整理了部分性能的學習資料,能夠根據須要閱讀學習。
經過以上「幾天」的努力,咱們能夠搭建一個小而美的前端性能監控系統。但這僅僅是開始,前端數據有不少挖掘的價值。性能優化也是一門須要認真學習的課程,爲了打造流暢的使用體驗,爲了讓用戶更加滿意,趕忙搭建起本身的前端數據平臺吧!
該文寫在w3ctech的走進名企 - 百度前端 FEX 專場以後,分享時的 PPT 在這裏,視頻在這裏。
華麗非分割線 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
入門
進階
入門
進階
通用
動畫與渲染
移動端開發