前端DevOps之PageSpeed Insights

PageSpeed Insights

使用 Google Cloud Scheduler, Pub/Sub, Functions , Storage 等雲服務,搭建 PageSpeed Insights 前端網站網頁的質量和性能 benchmark CI Job 工做流。html

1. PageSpeed Insights

1.1 簡介

PageSpeed Insights 是 Google 提供的一款網頁性能檢測優化工具,可以針對移動設備和桌面設備生成網頁的實際性能報告,並提供關於如何改進相應網頁的建議。它採用 Google Lighthouse 提供的各類最佳實踐做爲測試基準,使用 Blink 渲染工具(即 Google Chrome 的渲染引擎),模擬移動設備和桌面設備,抓取目標網站網頁,進行優化分析。
如下簡稱PSI。前端

1.2 版本歷史

版本 發佈時間 功能更新
V5 2018年Q4 當前最新版本。2019.05.08更新使用 Lighthouse 5.0 做爲其分析引擎。
V4 2018年1月 2019年Q3以前停用
V2 2015年1月 已停用
V1 更早期 已停用

1.3 分析報告組成

1.3.1 綜合速度得分

評分和等級:python

  • 快 90分以上
  • 中等 50-90分
  • 慢 50分如下

V5版本使用 Lighthouse 計算多項性能指標的綜合加權得分。
V4及以前版本結合 Chrome 用戶體驗報告數據庫中的真實用戶測速數據,計算評分和等級。主要參考如下兩項指標。git

  • FCP (First Contentful Paint)首次內容繪製,用於衡量用戶什麼時候看到來自相應網頁的可見響應。所用時間越短,留住用戶的可能性就越大。
  • DCL 文檔內容加載,用於衡量什麼時候完成 HTML 文檔的加載和解析。所用時間越短,跳出率越低。

1.3.2 實測數據

結合 Chrome 用戶體驗報告中的其餘網頁過去30天內的實測數據相比的得分。github

1.3.3 實驗室數據

給出如下幾項指標的耗時絕對值數據:web

  • First Contentful Paint 首次內容繪製時間
  • First Meaningful Paint 首次有效繪製時間
  • Speed Index 速度指數
  • First CPU Idle 首次 CPU 閒置時間
  • Time to Interactive 可交互前的耗時
  • Estimated Input Latency 最長的潛在FID

1.3.4 關於如何加快網頁加載速度的優化建議

1.3.5 關於Web開發最佳實踐的詳細診斷建議。

1.3.6 已經過的符合最佳實踐的審查項

1.4 實際案例

以攜程機票H5航班動態首頁的某線上版本爲例,直觀的查看分析報告:
m.ctrip.com/webapp/flig…
數據庫

綜合速度得分

實測數據

實驗室數據

優化建議

診斷建議

已經過

1.5 使用方法

PSI API是Google RESTful APIs之一, 僅需一次 HTTP 請求 ,應答返回一個 JSON Ojbect。使用極其簡便。npm

HTTP Request

GET www.googleapis.com/pagespeedon…json

必選參數1個:api

  • url: 目標分析網頁的連接

可選參數6個:

  • category:accessibilitybest-practicesperformancepwaseo。默認是performance
  • locale:返回結果文本的本地化語言版本。目前支持40種。默認英語en
  • strategy:desktop 針對桌面瀏覽器進行優化分析,mobile 針對移動設備瀏覽器進行優化分析。
  • utm_campaign:廣告系列名稱
  • utm_source:廣告系列來源
  • fields: 定製 Response 內容字段。

HTTP Response

返回一個 JSON Object ,字段內容較多,此處省略,詳見官網文檔。

最簡單命令行調用

curl www.googleapis.com/pagespeedon…

2. Google Cloude Platform (GCP)

2.1 系統流程圖

GCP Workflow

2.2 Cloud Scheduler

Cloud Scheduler 是 GCP 的一項全託管式企業級 cron 做業調度服務。支持 App Engine、Cloud Pub/Sub 和任意 HTTP 端點,容許做業觸發 Compute Engine、Google Kubernetes Engine 和本地資源。
使用 Google Cloud Console 建立Job。目標有3種:HTTP,Pub/Sub,App Engine HTTP。這裏選擇 Pub/Sub 。設置天天22:00自動觸發。

Cloud Scheduler Create

建立成功後查看部署狀態,部署成功後能夠直接「當即運行」,查看日誌,確認運行正常。

Cloud Scheduler List

2.3 Cloud Pub/Sub

Cloud Pub/Sub 是 GCP 的一項簡單、可靠、可伸縮,能夠用做數據流分析和事件驅動型計算系統的基礎。
這裏建立兩個主題,psi-job 用於 Cloude Scheduler Job 的事件數據中轉,psi-single 用於 Cloud Functions 的併發 HTTP 請求的事件數據中轉。

Cloud Pub/Sub

2.4 Cloud Functions

實現併發大量網頁的 PageSpeed Insights 檢查,有多種方式。可使用 Google App engine, Google Compute Engine。鑑於 PSI API 是上下文無關的簡單 HTTP RESTful API,Cloud Functions Serverless 是最佳最簡實現。
Cloud Functions 是 GCP 的一項事件驅動型無服務器計算平臺。經過構建多個分別專一於作好一件事的小型獨立功能單元,再將這些功能單元組合成一個系統,實現快速開發和部署。支持在單個函數(而不是整個應用、容器或虛擬機)級構建和部署服務。

2.4.1 編寫 Function

目前支持如下幾種方案:

語言 JavaScript
運行時 Node.js 6(已棄用)、八、10(測試版)
HTTP 框架 Express
HTTP 函數 Express Request & Response Context
後臺函數 (data, context, callback)
依賴項管理 npm/yarn + package.json
語言 Python
運行時 3.7.1
HTTP 框架 Flask
HTTP 函數 入參:Flask Request Object。返回值:符合 Flask.make_response() 的任意對象。
後臺函數 (data, context)
依賴項管理 pip + requirements.txt
語言 Go
運行時 Go 1.11
HTTP 框架 http.HandlerFunc 標準接口
HTTP 函數 request: *http.Request. response: http.ResponseWriter.
後臺函數 (ctx, Event)
依賴項管理 go.mod/vendor

2.4.2 部署 Function

目前支持如下幾種方式:

  • 從本地機器部署。使用 gcloud 命令行工具。
  • 經過源代碼控制系統部署。使用 Google Cloud Source Repositories ,經過 OAuth 關聯源代碼倉庫(如 GitHub 或 Bitbucket)。
  • 經過 GCP Console 部署。
    • 網頁內嵌編輯器.直接在線編寫函數代碼。
    • 上傳本地ZIP文件。文件夾目錄結構與上述依賴性管理的源碼工程結構一致。
    • 導入 Cloud Storage 中的 ZIP 文件。同上。
    • 引用 Google Cloud Source Repositories的源代碼工程。
  • 經過CI/CD部署。使用 Cloud Build 搭建持續集成和部署系統。

2.4.3 監控 Function

Google Stackdriver 提供了服務監控工具,包括 Debugger,Monitoring,Trace,Logging, Error Reporting,Profiler

3. PSI Functions 實現

建立好一個 Scheduler Job 和兩個 Pub/Sub 主題後,接下來實現兩個對應的 Functions 。

3.1 psi-single function

psi-single() 負責針對具體單一 URL ,調用 PSI API 獲取 JSON 結果的功能。
Google APIs 支持多種調用方式。

3.1.1 使用 google api client
經過 Discovery API ,得到已經封裝好的 Service ,再調用具體接口。

from googleapiclient.discovery import build

def run(url):
    pagespeedonline = build(
        serviceName = 'pagespeedonline',
        version = 'v5',
        developerKey = API_KEY
    )
    response = pagespeedonline.pagespeedapi().runpagespeed(url = url).execute()
    print(response)
    return 'OK'
複製代碼

3.1.2 針對簡單接口,直接調用 HTTP RESTful API

import requests
GAPI_PSI = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed"

def run(url):
    try:
        payload = {"url": url,
                   "key": API_KEY
                   }
        with requests.Session() as session:
            response = session.get(url=GAPI_PSI, params=payload)
            print(response.status_code)
            print(response.json())
    except requests.RequestException as _e:
        print(_e)
    return 'OK'
複製代碼

3.1.3 實現 Pub/Sub 主題的訂閱
訂閱消息 event 的格式詳見官網文檔,其中 data 屬性是一段 base64 編碼的 ByteArray ,承載了實際的數據內容。

import base64

def run_pubsub(event, context):
    pubsub_message = base64.urlsafe_b64decode(event['data']).decode('utf-8')
    return run(pubsub_message)
複製代碼

3.2 psi-job function

psi-job() 由 Scheduler Job 觸發,將全部需審查的 URL 以 Pub/Sub 事件形式,並行分發給 psi-single() 。

from google.cloud import pubsub_v1

def run(event, context):
    publisher = pubsub_v1.PublisherClient()
    topic = publisher.topic_path(PROJECT_ID, TOPIC_NAME)
    for url in URL_DICT:
        data = url.encode('utf-8')
        publisher.publish(topic, data)
    return 'OK'
複製代碼

3.3 環境變量和依賴項

爲了不安全敏感信息泄漏,能夠將關鍵信息寫入 Functions 環境變量和本地環境變量(本地開發調試使用)。
上述代碼中 API_KEY, PROJECT_ID 等數據經過 os.getenv() 獲取。
Cloude Functions 已內置經常使用依賴庫,詳見官網文檔。如需增長依賴項,配置各語言對應的工程文件。上述代碼引用了兩個依賴庫。

# requirements.txt
# Function dependencies
requests==2.21.0
google-cloud-pubsub==0.40.0
複製代碼

4. Storage

上述代碼中的 print() 會寫入 StackDriver 日誌庫,供後續過濾分析。鑑於每個 URL 的審查結果是一個 JSON Object 字符串,能夠進一步寫入 BigTable , 使用 BigQuery 進行查詢分析,再進一步導入 Google Data Studio , 進行可視化報表展現。
這裏使用 Cloud Storage 存儲 JSON 字符串爲單一文件。

from urllib import parse
from google.cloud import storage
from google.cloud.storage import Blob

def save(url, report):
    '''Save to https://console.cloud.google.com/storage/browser/[bucket-id]/'''
    client = storage.Client()
    bucket = client.get_bucket("psi-report")
    blob = Blob(f"${parse.quote_plus(url)}.json", bucket)
    blob.upload_from_string(report, "application/json")
複製代碼

添加依賴項。

# requirements.txt
# Function dependencies
google-cloud-storage==1.15.0
複製代碼

5. 源代碼

github.com/9468305/pyt…

6. 文檔連接

  1. PageSpeed Insights
    developers.google.com/speed/pages…
  2. Google Lighthouse
    developers.google.com/web/tools/l…
  3. Google Cloud Scheduler
    cloud.google.com/scheduler/
  4. Google Cloud Pub/Sub
    cloud.google.com/pubsub/
  5. Google Cloud Functions
    cloud.google.com/functions/
  6. Google Cloud Storage
    cloud.google.com/storage/
  7. Google Cloud Build
    cloud.google.com/cloud-build…
  8. Google Stackdriver
    cloud.google.com/stackdriver…
相關文章
相關標籤/搜索