基于Python Playwright進(jìn)行前端性能測(cè)試的腳本實(shí)現(xiàn)
引言
在當(dāng)今Web應(yīng)用開發(fā)中,性能優(yōu)化是提升用戶體驗(yàn)的關(guān)鍵因素之一。本文將介紹如何使用Playwright構(gòu)建一個(gè)自動(dòng)化性能測(cè)試工具,幫助開發(fā)者全面分析網(wǎng)頁性能瓶頸并獲取優(yōu)化建議。
工具概述
這個(gè)腳本主要功能包括:
- 自動(dòng)收集頁面加載性能指標(biāo)
- 分析資源加載情況
- 生成詳細(xì)的性能報(bào)告
- 提供優(yōu)化建議
整體架構(gòu)

核心實(shí)現(xiàn)解析
1. 瀏覽器初始化
def _initialize_browser(self):
"""初始化瀏覽器環(huán)境"""
self.playwright = sync_playwright().start() # 啟動(dòng)Playwright
self.browser = self.playwright.chromium.launch(headless=False) # 啟動(dòng)Chromium瀏覽器
self.context = self.browser.new_context(
ignore_https_errors=True, # 忽略HTTPS錯(cuò)誤
bypass_csp=True, # 繞過內(nèi)容安全策略
extra_http_headers={ # 設(shè)置HTTP頭禁用緩存
'Cache-Control': 'no-store, no-cache, must-revalidate',
'Pragma': 'no-cache'
}
)
self.page = self.context.new_page() # 創(chuàng)建新頁面
self.page.goto('about:blank') # 導(dǎo)航到空白頁
self.page.route('**', lambda route: route.continue_()) # 攔截所有請(qǐng)求并繼續(xù)
關(guān)鍵配置說明:
ignore_https_errors=True:忽略證書錯(cuò)誤,便于測(cè)試開發(fā)環(huán)境bypass_csp=True:繞過內(nèi)容安全策略限制- 禁用緩存:確保每次測(cè)試都從服務(wù)器獲取最新資源
2. 性能數(shù)據(jù)收集
def _collect_performance_metrics(self) -> Dict[str, Any]:
"""收集性能指標(biāo)數(shù)據(jù)"""
start_time = time.time() # 記錄開始時(shí)間
self.page.goto(self.test_url, wait_until="networkidle") # 導(dǎo)航到目標(biāo)URL
end_time = time.time() # 記錄結(jié)束時(shí)間
# 基礎(chǔ)指標(biāo):頁面加載總時(shí)間
self.metrics_data = {
'load_time_seconds': end_time - start_time,
}
# 通過瀏覽器API獲取詳細(xì)性能指標(biāo)
browser_metrics = self.page.evaluate('''() => {
try {
const navEntries = performance.getEntriesByType("navigation");
const resources = performance.getEntriesByType("resource") || [];
return {
navigation: navEntries.length > 0 ? navEntries[0].toJSON() : {},
resources: resources.map(r => r.toJSON())
};
} catch (e) {
return { navigation: {}, resources: [] };
}
}''')
數(shù)據(jù)收集策略:
- 使用高精度時(shí)間戳記錄頁面加載總時(shí)間
- 通過
performance.getEntriesByTypeAPI獲取Navigation Timing和Resource Timing數(shù)據(jù) - 捕獲異常確保測(cè)試不會(huì)因單個(gè)頁面錯(cuò)誤而中斷
3. 資源分析
def _analyze_resources(self, resources: List[Dict]) -> Dict[str, Any]:
"""分析資源加載情況"""
resource_types = defaultdict(list) # 按類型分類資源
slow_resources = [] # 存儲(chǔ)加載緩慢的資源
# 分類和分析資源
for res in resources:
res_type = res.get('initiatorType', 'other')
resource_types[res_type].append(res)
duration = res.get('duration')
if isinstance(duration, (int, float)) and duration > 500:
slow_resources.append({
'name': res.get('name', 'unknown'),
'type': res_type,
'duration': duration
})
# 計(jì)算統(tǒng)計(jì)信息
分析維度:
- 按資源類型(JS/CSS/圖片等)分類統(tǒng)計(jì)
- 識(shí)別加載時(shí)間超過500ms的慢資源
- 計(jì)算各類資源的平均加載時(shí)間和總耗時(shí)
4. 關(guān)鍵性能指標(biāo)計(jì)算
def _analyze_metrics(self):
"""分析關(guān)鍵性能指標(biāo)"""
nav_entry = self.metrics_data.get('navigation', {})
self.metrics_data['analysis'] = {
'dom_ready_time': nav_entry.get('domContentLoadedEventEnd'), # DOM準(zhǔn)備就緒時(shí)間
'full_load_time': nav_entry.get('loadEventEnd'), # 完整加載時(shí)間
'first_byte': nav_entry.get('responseStart', 0) - nav_entry.get('requestStart', 0)
if all(k in nav_entry for k in ['responseStart', 'requestStart'])
else None, # 首字節(jié)時(shí)間(TTFB)
'page_render_time': nav_entry.get('domComplete', 0) - nav_entry.get('domLoading', 0)
if all(k in nav_entry for k in ['domComplete', 'domLoading'])
else None, # 頁面渲染時(shí)間
'resource_count': self.resource_analysis.get('total_resources', 0), # 資源總數(shù)
'avg_resource_load_time': self.resource_analysis.get('avg_resource_load_time', 0)
}
核心指標(biāo)說明:
| 指標(biāo)名稱 | 說明 | 優(yōu)化意義 |
|---|---|---|
| 頁面加載時(shí)間 | 從開始導(dǎo)航到頁面完全加載的總時(shí)間 | 反映整體用戶體驗(yàn) |
| DOMContentLoaded | DOM樹構(gòu)建完成時(shí)間 | 用戶可開始與頁面部分交互的時(shí)間點(diǎn) |
| 完全加載時(shí)間 | 所有資源加載完成的時(shí)間 | 頁面完全就緒的時(shí)間點(diǎn) |
| 首字節(jié)時(shí)間(TTFB) | 服務(wù)器響應(yīng)第一個(gè)字節(jié)的時(shí)間 | 反映服務(wù)器響應(yīng)速度 |
| 頁面渲染時(shí)間 | DOM構(gòu)建到完成渲染的時(shí)間 | 反映瀏覽器渲染效率 |
| 資源數(shù)量 | 頁面加載的所有資源總數(shù) | 過多資源會(huì)顯著影響性能 |
| 平均資源加載時(shí)間 | 資源加載的平均耗時(shí) | 反映資源服務(wù)器/CDN性能 |
5. 智能優(yōu)化建議生成
def _generate_recommendations(self) -> List[str]:
"""根據(jù)分析結(jié)果生成優(yōu)化建議"""
recommendations = []
analysis = self.metrics_data.get('analysis', {})
resources = self.resource_analysis
# 資源數(shù)量過多建議
if analysis.get('resource_count', 0) > 50:
recommendations.append(
f"資源數(shù)量較多({analysis['resource_count']}個(gè)),建議合并CSS/JS文件,使用雪碧圖減少圖片資源"
)
# 慢資源優(yōu)化建議
slow_resources = [
r for r in resources.get('top_slowest', [])
if r.get('duration', 0) > 1000
]
建議生成邏輯基于以下規(guī)則:
- 資源數(shù)量 > 50 → 建議合并資源
- 平均資源加載時(shí)間 > 300ms → 檢查CDN或服務(wù)器
- 存在加載時(shí)間 > 1s的資源 → 提示優(yōu)化具體資源
使用示例
if __name__ == "__main__":
# 創(chuàng)建測(cè)試實(shí)例并運(yùn)行測(cè)試
tester = PerformanceTester(url="https://example.com")
tester.run_test()
輸出示例:
開始測(cè)試頁面: https://example.com
=== 核心性能指標(biāo) ===
1. 頁面加載時(shí)間: 2.34秒
2. DOMContentLoaded: 1245.23ms
3. 完全加載時(shí)間: 2340.56ms
4. 首字節(jié)時(shí)間(TTFB): 345.67ms
5. 頁面渲染時(shí)間: 895.32ms
6. 資源數(shù)量: 42
7. 平均資源加載時(shí)間: 215.43ms
=== 資源加載分析 ===
總資源數(shù)量: 42
平均資源加載時(shí)間: 215.43ms
按類型統(tǒng)計(jì):
SCRIPT: 12個(gè), 平均加載時(shí)間: 185.32ms
IMAGE: 20個(gè), 平均加載時(shí)間: 245.67ms
CSS: 5個(gè), 平均加載時(shí)間: 156.89ms
=== 優(yōu)化建議 ===
1. 資源數(shù)量較多(42個(gè)),建議合并CSS/JS文件,使用雪碧圖減少圖片資源
2. 發(fā)現(xiàn)加載緩慢的資源(2個(gè)),建議優(yōu)化: example.com/big-image.jpg(1245ms), example.com/main.js(1123ms)
到此這篇關(guān)于基于Python Playwright進(jìn)行前端性能測(cè)試的腳本實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python Playwright前端性能測(cè)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Python使用Playwright進(jìn)行API接口測(cè)試
- Node.js使用Playwright自動(dòng)化測(cè)試頁面性能
- Playwright中Web自動(dòng)化測(cè)試的實(shí)現(xiàn)
- Python中Playwright模塊進(jìn)行自動(dòng)化測(cè)試的實(shí)現(xiàn)
- 使用Python中的Playwright制作測(cè)試視頻的實(shí)現(xiàn)步驟
- 一款強(qiáng)大的端到端測(cè)試工具Playwright介紹
- 如何使用Playwright對(duì)Java API實(shí)現(xiàn)自動(dòng)視覺測(cè)試
- 使用Playwright進(jìn)行移動(dòng)端模擬測(cè)試的實(shí)現(xiàn)
相關(guān)文章
python實(shí)現(xiàn)隨機(jī)梯度下降(SGD)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)隨機(jī)梯度下降SGD,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Python數(shù)據(jù)分析?Numpy?的使用方法
這篇文章主要介紹了Python數(shù)據(jù)分析?Numpy?的使用方法,Numpy?是一個(gè)Python擴(kuò)展庫,專門做科學(xué)計(jì)算,也是大部分Python科學(xué)計(jì)算庫的基礎(chǔ),關(guān)于其的使用方法,需要的小伙伴可以參考下面文章內(nèi)容2022-05-05
Ubuntu手動(dòng)編譯源碼安裝Python的詳細(xì)過程
這篇文章主要介紹了Ubuntu手動(dòng)編譯源碼安裝Python的詳細(xì)過程,在python官網(wǎng)找到所需版本的python安裝包,下載到Ubuntu系統(tǒng)中,需要的朋友可以參考下2006-08-08
Python讀取和處理文件后綴為.sqlite的數(shù)據(jù)文件(實(shí)例講解)
下面小編就為大家?guī)硪黄狿ython讀取和處理文件后綴為.sqlite的數(shù)據(jù)文件(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
Python定義函數(shù)時(shí)參數(shù)有默認(rèn)值問題解決
這篇文章主要介紹了Python定義函數(shù)時(shí)參數(shù)有默認(rèn)值問題解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
Python使用Selenium爬取淘寶異步加載的數(shù)據(jù)方法
今天小編就為大家分享一篇Python使用Selenium爬取淘寶異步加載的數(shù)據(jù)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-12-12
pyqt4教程之實(shí)現(xiàn)windows窗口小示例分享
這篇文章主要介紹了pyqt4實(shí)現(xiàn)windows窗口小示例,需要的朋友可以參考下2014-03-03

