使用 Google Cloud Scheduler, Pub/Sub, Functions , Storage 等雲服務,搭建 PageSpeed Insights 前端網站網頁的質量和性能 benchmark CI Job 工做流。html
PageSpeed Insights 是 Google 提供的一款網頁性能檢測優化工具,可以針對移動設備和桌面設備生成網頁的實際性能報告,並提供關於如何改進相應網頁的建議。它採用 Google Lighthouse 提供的各類最佳實踐做爲測試基準,使用 Blink 渲染工具(即 Google Chrome 的渲染引擎),模擬移動設備和桌面設備,抓取目標網站網頁,進行優化分析。
如下簡稱PSI。前端
版本 | 發佈時間 | 功能更新 |
---|---|---|
V5 | 2018年Q4 | 當前最新版本。2019.05.08更新使用 Lighthouse 5.0 做爲其分析引擎。 |
V4 | 2018年1月 | 2019年Q3以前停用 |
V2 | 2015年1月 | 已停用 |
V1 | 更早期 | 已停用 |
評分和等級:python
V5版本使用 Lighthouse 計算多項性能指標的綜合加權得分。
V4及以前版本結合 Chrome 用戶體驗報告數據庫中的真實用戶測速數據,計算評分和等級。主要參考如下兩項指標。git
結合 Chrome 用戶體驗報告中的其餘網頁過去30天內的實測數據相比的得分。github
給出如下幾項指標的耗時絕對值數據:web
以攜程機票H5航班動態首頁的某線上版本爲例,直觀的查看分析報告:
m.ctrip.com/webapp/flig…
數據庫
PSI API是Google RESTful APIs之一, 僅需一次 HTTP 請求 ,應答返回一個 JSON Ojbect。使用極其簡便。npm
GET www.googleapis.com/pagespeedon…json
必選參數1個:api
url
: 目標分析網頁的連接可選參數6個:
accessibility
,best-practices
,performance
,pwa
,seo
。默認是performance
。en
。desktop
針對桌面瀏覽器進行優化分析,mobile
針對移動設備瀏覽器進行優化分析。返回一個 JSON Object ,字段內容較多,此處省略,詳見官網文檔。
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 Pub/Sub 是 GCP 的一項簡單、可靠、可伸縮,能夠用做數據流分析和事件驅動型計算系統的基礎。
這裏建立兩個主題,psi-job
用於 Cloude Scheduler Job 的事件數據中轉,psi-single
用於 Cloud Functions 的併發 HTTP 請求的事件數據中轉。
實現併發大量網頁的 PageSpeed Insights 檢查,有多種方式。可使用 Google App engine, Google Compute Engine。鑑於 PSI API 是上下文無關的簡單 HTTP RESTful API,Cloud Functions Serverless 是最佳最簡實現。
Cloud Functions 是 GCP 的一項事件驅動型無服務器計算平臺。經過構建多個分別專一於作好一件事的小型獨立功能單元,再將這些功能單元組合成一個系統,實現快速開發和部署。支持在單個函數(而不是整個應用、容器或虛擬機)級構建和部署服務。
目前支持如下幾種方案:
語言 | 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 |
目前支持如下幾種方式:
使用 gcloud 命令行工具。
使用 Google Cloud Source Repositories ,經過 OAuth 關聯源代碼倉庫(如 GitHub 或 Bitbucket)。
直接在線編寫函數代碼。
文件夾目錄結構與上述依賴性管理的源碼工程結構一致。
同上。
使用 Cloud Build 搭建持續集成和部署系統。
Google Stackdriver 提供了服務監控工具,包括 Debugger,Monitoring,Trace,Logging, Error Reporting,Profiler
。
建立好一個 Scheduler Job 和兩個 Pub/Sub 主題後,接下來實現兩個對應的 Functions 。
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)
複製代碼
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'
複製代碼
爲了不安全敏感信息泄漏,能夠將關鍵信息寫入 Functions 環境變量和本地環境變量(本地開發調試使用)。
上述代碼中 API_KEY, PROJECT_ID
等數據經過 os.getenv()
獲取。
Cloude Functions 已內置經常使用依賴庫,詳見官網文檔。如需增長依賴項,配置各語言對應的工程文件。上述代碼引用了兩個依賴庫。
# requirements.txt
# Function dependencies
requests==2.21.0
google-cloud-pubsub==0.40.0
複製代碼
上述代碼中的 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
複製代碼