報告老闆,個人頁面真的比競品快!

| 導語 《孫子兵法·謀攻》:「知彼知己,百戰不殆。」在和產品pk的時候,產品最常常的說一句話是,你看他們(競品)都能實現,你爲啥不能?你看他們(競品)的速度怎麼這麼快,你看看你,爲啥這麼慢?javascript

《孫子兵法·謀攻》:「知彼知己,百戰不殆。」在和產品pk的時候,產品最常常的說一句話是,你看他們(競品)都能實現,你爲啥不能?你看他們(競品)的速度怎麼這麼快,你看看你,爲啥這麼慢?往往遇到這樣的責難的時候,我每每都只能陷入到沉思,我只能告知產品,咱們的頁面很快,真的很快,你看,個人報表。產品老是在這個時候說,不聽不聽,我不聽。若是你不能拿出競品的客觀數據,那麼,在產品看來這樣的囈語只能是開發本身的寡婦心態。在每一個無人的夜晚,遇到這個問題的時候,我不得不得默默的打開了瀏覽器。php

因此,如何把監控作到客觀,獨立,第三方,就變得很重要了。html

如何客觀的監控頁面的體驗

首先,第一個來自靈魂的深思就是,如何客觀的對頁面體驗進行評價?你說你的頁面體驗牛逼,你的頁面體驗就牛逼了麼?你說競品的頁面不行,競品的頁面就真的不行麼?每晚思及如此,我都默默的打開了瀏覽器。前端

對於頁面的客觀評價體系,有不少不一樣的說法,基於速度,基於錯誤率,基於SEO…,這麼多的評價標準中,要怎麼樣,找到最能說明用戶體驗的指標?或者換句話來講,怎麼樣的指標是最可以表現用戶真實的用戶體驗的?java

從直覺上來講,一個頁面的體驗能夠分紅如下幾個部分:node

渲染體驗

這個體驗最直白,用戶打開頁面的耗時如何,用戶花了多長的時間來打開你的頁面。在頁面的打開過程當中,是一種什麼樣的體驗?是白屏,是漸進加載,是菊花圖,仍是骨架屏?不一樣的體驗體驗,給用戶的直覺感官是不一樣的,這些感官應該怎麼樣來客觀評價?python

交互體驗

頁面的各類交互是否可以及時?頁面上的各個交互針對不一樣的人羣是否兼顧?是否照顧了視覺障礙人羣,是否考慮到了鍵盤黨?各個交互是否符合瀏覽器預期?頁面上的腳本是否使用了有危險的API?是否加載了太多的資源?git

SEO

頁面是否對蜘蛛友好?頁面是否對於可以被正確的收入?github

固然,上面列的比較簡單,只涵蓋了頁面的一部分,可是,如上已經覆蓋了不少咱們平時須要關注的頁面信息了,那麼咱們要怎麼來獲取和評價這些信息呢?web

最簡單的方法是,咱們把瀏覽器的devtools打開,選中到performance tab,點擊record。而後,咱們就能夠看到全部咱們想要的數據了。那麼問題來了,performance tab是怎麼工做的呢?它是怎麼拿到咱們頁面的各類渲染數據的呢?

瀏覽器的performance tab是怎麼工做的?

一切的一切,都要以這個協議開始:chrome devTools protocol。 chrome會經過這個協議,把內核和瀏覽器的一些狀態暴露出來。咱們平時使用的performance tab的本質起始就是使用這個協議的一個美化了的查看器。performance裏面仍是有一些內容比較沒有被充分展現,若是你想了解更多,更詳細的內核信息,能夠進入到如下的頁面查看

chrome://tracing/
複製代碼

點擊record,你會看到以下的選擇框。

這裏將會容許你,更爲詳細的去定義,你想要監控和了解的內核內容。

嗯,這裏有一點比較好,也是比較不幸的一點,這個tracing tab將會監控當前chrome 全部tab的渲染信息。因此,使用的時候,請務必當心。還有一個須要注意的點事,這個tracing的日誌量多到爆炸,儘量的選擇較少的追蹤項,這樣,可讓你保護好你的內存條。:)
若是有時間好好研究一下,這個tracing出來的內容,你會發現,瀏覽器的運行,好像並非你想象那樣的。:)

固然了,除了使用這樣的形式去使用chrome devtools protocol,咱們還可使用nodejs的來獲取。畢竟,Anything that can be Written in JavaScript, will Eventually be Written in JavaScript。比較常見的nodejs的庫有chrome-remote-interface(下文爲了方便,簡述爲cri),固然,若是你說我不要,我不要js,那也不是不能夠,在這裏,本身選一個本身喜歡的實踐吧。什麼typescript,go, python,ruby都有,固然,還有,咱們你們都喜歡的php。

好了,做爲一個前端工程師,咱們仍是老老實實用nodejs吧,雖然,typescript很好,可是我選擇js,咱們來康康,咱們要怎麼把各類各樣的工具,組合起來,使之成爲一個可以被工具化使用的頁面監控呢?

具體的cri使用,請參考這個wiki

工具化的頁面監控

一切的一切,咱們要有一個開啓了debugger端口的chrome。這個簡單,你能夠用shell腳本,本身起一個,固然,咱們還有更優雅的方式:chrome-launcher,有了它,在寂靜無人的夜,你就不再用本身寫shell腳原本啓動chrome了:)。

經過chrome-launcher,咱們把chrome拉起來,而後獲得了一個咱們須要須要調試端口,而後,咱們拿着這個端口,使用cri來獲取咱們須要chrome-debugger-Protocol,拿到了具體的Protocol以後,咱們來康康,拿到的都是些啥東西:

{"pid":8784,"tid":8728,"ts":4123614461,"ph":"X","cat":"ipc,toplevel","name":"ChannelMojo::OnMessageReceived","args":{"class":50,"line":101},"dur":2,"tdur":1,"tts":22268542},
{"pid":8784,"tid":8728,"ts":4123615131,"ph":"X","cat":"toplevel","name":"MessageLoop::RunTask","args":{"src_file":"../../content/browser/renderer_host/media/media_stream_manager.cc","src_func":"SendMessageToNativeLog"},"dur":4,"tdur":4,"tts":22268810},
{"pid":8784,"tid":8728,"ts":4123615138,"ph":"X","cat":"toplevel","name":"MessageLoop::RunTask","args":{"src_file":"../../ipc/ipc_channel_proxy.cc","src_func":"Send"},"dur":8,"tdur":8,"tts":22268817},
{"pid":8784,"tid":8788,"ts":4123551336,"ph":"X","cat":"toplevel","name":"MessageLoop::RunTask","args":{"src_file":"../../base/trace_event/trace_log.cc","src_func":"SetEnabled"},"dur":130,"tdur":130,"tts":64927429},
{"pid":8784,"tid":8788,"ts":4123551358,"ph":"I","cat":"disabled-by-default-devtools.timeline","name":"TracingStartedInBrowser","args":{"data":{"frameTreeNodeId":101,"persistentIds":true,"frames":[{"frame":"7CB62147F076D4C38B128F711003B9E9","url":"https://www.huya.com/badaozongcai","name":"201905171157120c93bb02c2ca5f727133a5547b2a8d4000016f6b3731c1440","processId":5368}]}},"tts":64927451,"s":"t"},
複製代碼

是否是以爲似曾相識,嗯,用chrome save下來的profile.json和上面的內容的格式如出一轍。那麼,這一大坨json究竟是啥意思呢?這個時候,我就要把我祖傳的chrome tracing event format的文檔給你掏出來了。我相信,等你看完以後,你必定會,大吼一聲,臥槽,這是什麼鬼!這麼詰屈聱牙的文檔,簡直了。瀏覽器的底層運行原理是很是複雜的,不一樣的類和組件的調用,使得追蹤瀏覽器事件變成了一個不是這麼容易的事情。固然,若是,想要圖文並茂的瞭解瀏覽器的運行原理,請參考《life of a pixel》

若是是咱們想要程序化,工具化的去監控和管理瀏覽器的底層渲染行爲,咱們只能從上面厚厚的trace event log裏,把咱們須要的內容剝離出來,進行統計分析。這時候,咱們會就想呀,有沒有大神把這個事情給作了呀,咱們這種小弟,觀摩學習一下就好?

答案是,固然有啦!google chrome團隊,本身就開源了一個基於typescript的分析工具Lighthouse,可以幫助咱們快速的進行頁面的質量分析。

Lighthouse是什麼

lighthouse 是這麼介紹本身的:

Lighthouse analyzes web apps and web pages, collecting modern performance metrics and insights on developer best practices.

在我看來,Lighthouse更像是一個google推行標準的衡量器。讓廣大的開發同窗知道什麼是好,什麼是很差,在茫茫的人海中,找到對的那我的。

Lighthouse的工做原理

與其讓我重複一遍上面的內容,還不如康康Lighthouse本身是怎麼說本身的工做原理的:

依照上圖和前文,我相信你們已經對於Lighthouse是怎麼執行的,有了很是深入的理解了,經過github上Lighthouse的readme,我相信,你們也可以很是容易的把Lighthouse跑起來了。這裏就不贅述了。無非就是npm install, npx lighthouse 諸如此類。

等咱們把lighthouse跑起來以後,咱們就能夠獲得下面這樣的一個報告:

咱們除了會使用到Lighthouse提供的這些評價標準和評價體系,更多的時候,會使用到屬於咱們本身的評價標準和評價體系。這個時候問題就來了,咱們要怎麼對Lighthouse進行二次開發?咱們怎麼基於Lighthouse作一個屬於咱們本身的標準衡量器?

Lighthouse的二次開發指南

在開發以前,咱們先了解基本流程,從上圖,咱們能夠清楚的得知Lighthouse的工做流程以下:

+--------------+      +-------------+        +------------+       +-------------------+
|              |      |             |        |            |       |                   |
|  connecting  +----->+  collecting +------->+  auditing  +------>+ report generation |
|              |      |             |        |            |       |                   |
+--------------+      +-------------+        +------------+       +-------------------+
    創建鏈接             收集日誌              分析,審計               生成報告
複製代碼

瞭解了流程,咱們再來了解一些基本概念,在Lighthouse裏面,有以下幾個特別重要的概念:

  • Driver: 鏈接器,是前文說道的cri。用來連接和獲取chrome devtools Protocol
  • gatherers:採集器,對trace event log進行分類收集
  • audits:對收集到的日誌進行審計,最後給出出分數。
  • metic:對日誌內容進行分析和計算。通常是被audts調用的工具類

好了,知道了,以上這些內容,你就能夠本身來搞一個Lighthouse了,正常來講,一個優秀的框架設計,都是會留有插件機制的,可以讓咱們很是優雅的,無侵入的把咱們的邏輯添加到框架的邏輯體系中去。Lighthouse也不例外。固然,若是你說,不要,我不要,我要硬核魔改,讓它變成我本身的崽,下文也會給出一些指南。

插件化的開發方式

在開發插件以前,咱們須要知道,咱們這個插件的結構是怎麼樣的。先倆簡單的看一下:

-
|-your_audit.js
|-plugin.js
|-package.json
複製代碼

只須要三個文件,就能夠自行實現一個lighthouse的插件了,是否是很簡單!!!

package.json是一個npm包的必備文件,咱們須要把package.json中的main指向,咱們的plugin.js。

做爲一個plugin,你只是須要暴露如下一個對象便可:

//plugin.js
module.exports = {
  audits: [{
    path: 'path/to/your/aduit',
  }],
  category: {
    title: 'My Plugin',
    description: 'my plugin.',
    auditRefs: [
      {id: 'your_audit', weight: 1}, //這裏須要注意,id和文件名一直
      {id: 'meta-description', weight: 1}, // lighthourse的默認審計項目
    ],
  },
};
複製代碼

而後,在audit文件裏,你能夠本身定義你本身的審計規則,就像下面這樣:

//my-audit.js
const Audit = require('lighthouse').Audit;

class myAudit extends Audit {
  static get meta() {
    return {
      id: 'my-aduit',
      title: '展現的title',
      failureTitle: '未經過的時候,展現的文案',
      description: '補充的一點的描述內容',

      // 你所須要的收集內容
      requiredArtifacts: ['LinkElements'],
    };
  }

  static audit(artifacts) { // 上面指定的內容,將會被傳遞到這個函數中
   // 處理你的邏輯
    return {
      score: 0, // 外顯的分數以及決定是否算經過
      displayValue: '顯示的內容',
    };
  }
}

module.exports = myAudit;
複製代碼

在執行lighthouse命令的時候,咱們須要這樣來明文指示咱們要用的plugin:

npx lighthouse https://example.com --plugins=my-plugin --view
複製代碼

而後,lighthouse就會去node_modules裏面去尋找,你要使用到的lighthouse plugin。

lighthouse官方本身給了一個插件的demo,你們能夠自行參考一下。裏面還有plugin的效果圖。

上面能夠看到,開發一個plugin是很簡單的。可是呢,咱們也很明顯的發現一個問題,這個plugin的機制有點弱,好像只能就已經收集到的信息進行審計級別的重寫,並不能捕獲更多的數據,而後來定義本身想要的內容。

其實吧,若是,只是想本身定義一個屬於本身的評價體系,作到這一步,已經夠了,畢竟lighthouse的articles給的也挺多。基本上,你能想到的經常使用的內容,都有。若是想知道全部的articles都有啥,請看這裏。若是你想更多的瞭解插件的開發內容,能夠參考這裏

對於咱們這種,向來都不喜歡被約束的人而言,這麼點東西,就想打發我,不行!做爲一個成年人,做爲一個半夜打開瀏覽器的男人,我都要!ok,那麼咱們來看看,咱們怎麼硬核的二次開發,把lighthouse變成咱們本身的崽。

魔改源碼

Lighthouse的源碼寫的很規整,加上typescript的加持,很是好讀,同時大量的註釋,更是若有神助。

在對lighthouse進行二次開發以前,咱們須要知道lighthouse的源碼結構是怎麼樣的。以下所示(爲了避免浪費篇幅,把一些和魔改無關的邏輯去掉了):

——
├─assets
├─build
├─clients // 瀏覽器中的展現邏輯
│  └─extension // 擴展
├─docs // 文檔
├─lighthouse-cli // 命令行工具
│  ├─commands // 命令
│  └─test 
├─lighthouse-core // 核心邏輯
│  ├─audits
│  ├─computed
│  │  └─metrics
│  ├─config
│  ├─gather
│  │  ├─connections
│  │  └─gatherers
│  ├─lib // 工具庫
│  ├─report // 報告生成器
│  │  └─html
│  │      └─renderer
│  └─test // 測試用例
├─lighthouse-logger // 日誌收集
├─lighthouse-viewer // 報告渲染工具
└─types // 類型文件
複製代碼

從上文所描述的內容中,咱們已經知道了lighthouse的一些基本的內容和結構,因此咱們能夠很容易的從目錄結構中,看出咱們須要修改的內容,通常是圍繞在Lighthouse-core的邏輯中。總體文件看起來好像比較多,可是呢,其實核心邏輯,其實仍是比較集中。在Lighthouse-core。
總體的調用關係以下圖

好像很複雜,從新整理了一下以下:

從調用鏈,咱們能夠很清楚看到前文提到的connecting->collecting->auditing->report generation的過程,其實基本上根據函數名,你們都可以分析出函數的內容。你們按照本身的須要,切進去魔改就行了,想改啥都行。

說實話,Lighthouse的總體設計仍是很不錯的,加上typescript的加持,整個代碼的可讀性仍是很強的。其實基於plugin的機制,基本上已經能夠知足你們的各類需求了。若是真的有一天,已經到了,必需要修改源碼的地步了,但願上述內容能幫助到你們。

如何作到更加客觀?

好了,基於上文的魔改,咱們已經獲得了一個屬於咱們本身的lighthouse和咱們本身的審計規則。可是,在你電腦上跑出來的數據,並不真實,並不能表明廣大的人民羣衆。因此,咱們須要作如下的工做:

  • 雲端部署

把咱們的服務部署在雲端的機器,直接接受外部網絡環境的洗禮。同時限制硬件素質,保持一個比較貼近現實的機器水平。

  • 多地部署

在天津,上海,廣州等多個節點進行部署,看看地理位置因素,到底會給頁面帶來多大的影響。

  • 多時運行

一天在不一樣的時間段內執行,看看不一樣的時間裏,隨着網絡流量的週期變化,你的頁面在哪一個時間最糟糕?固然,這裏還有一個更爲重要的做用,就是,抽查頁面的可訪問性,頁面是否是掛了?讓你成爲最先知道頁面完整信息的人。

  • 屢次運行

屢次執行取平均值咯,去除單一緩存的影響。

基於這種考慮,咱們開發了leadership,能夠同時對比多份報告,雲端運行。

完成了如此種種,我終於纔可以在寂靜無人的夜,比較客觀公正的對產品說,個人頁面真的比競品的頁面快!你看,這是個人報告!


關注【IVWEB社區】公衆號獲取每週最新文章,通往人生之巔!

相關文章
相關標籤/搜索