Chrome:性能数据 API
Posted
技术标签:
【中文标题】Chrome:性能数据 API【英文标题】:Chrome: API for performance data 【发布时间】:2018-08-02 22:54:58 【问题描述】:问题描述
在使用 Selenium 时,如何从浏览器控制台或使用 Chrome 驱动程序方法访问 Chrome 性能工具中的数据?
特别是,我对获得页面加载时间感兴趣。在上面的图表中,我可以看到最后一个元素是在 1700-1800 毫秒 标记附近加载的。底部的事件日志显示,最后一个元素在页面重新加载后的 1720.1 毫秒处开始加载(并在几毫秒内完成)。
到目前为止我尝试了什么
我尝试像这样使用Performance Timing interface:
console.log(performance.timing.loadEventEnd -
performance.timing.navigationStart)
357
但我想它可以衡量其他一些性能。 loadEventEnd
和navigationStart
在timing
的属性中是最极端的,相差只有357(ms)。
我也尝试过像这样使用 Selenium 记录性能信息(从 here 获取一些想法并用 Python 重写):
import time
import json
import copy
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.chrome.options import Options
caps = copy.deepcopy(DesiredCapabilities.CHROME)
caps['loggingPrefs'] = 'performance': 'ALL'
chromedriver_options = Options()
chromedriver_options.add_argument("--headless")
chromedriver_options.add_argument("--window-size=1920,1080")
chromedriver_options.add_argument("--log-level=3") # suppress selenium logging to stdout
driver = webdriver.Chrome(chrome_options=chromedriver_options, executable_path='chromedriver.exe', desired_capabilities=caps)
driver.set_window_position(0, 0)
driver.implicitly_wait(8) # set timeout to 8 seconds
driver.get(my_url)
time.sleep(5) # wait for page to load for the first time
_ = driver.get_log('performance') # discard all previous logs
driver.refresh()
time.sleep(5) # make sure page loaded completely before writing log
with open('logs.txt', 'a') as f:
for entry in driver.get_log('performance'):
f.write(str(entry) + '\n')
driver.close()
生成的日志包含调用Page.frameStartedLoading
和Page.frameStoppedLoading
方法及其时间戳的条目,我想在刷新日志并调用@ 后测量第一个Page.frameStartedLoading
和最后一个Page.frameStoppedLoading
之间的时间987654334@。
不幸的是,生成的日志文件没有多大意义。性能记录不会停止(我认为它应该停止,因为网页在某个时候加载并且性能方面没有发生任何事情)。如果我在刷新后调用time.sleep(5)
,我会得到一些日志,其中每个Page.frameStartedLoading
和Page.frameStoppedLoading
调用5 次。如果我打电话给time.sleep(7)
,我将分别接到Page.frameStartedLoading
和Page.frameStoppedLoading
的7 个电话。最后一个Page.frameStoppedLoading
和第一个Page.frameStartedLoading
的时间戳之间的差异在最后一种情况下约为7 秒,这显然不是我想要的。
任何人都有捕获此页面加载性能信息的经验?
【问题讨论】:
【参考方案1】:如果您想使用 ChromeDriver 从 Chrome 开发者工具 访问 性能数据,您可以使用以下代码块:
Selenium-Python 片段
from selenium import webdriver
driver=webdriver.Chrome(executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("http://www.google.com")
performance_data = driver.execute_script("return window.performance.getEntries();")
print (performance_data)
提取的参数如下:
connectEnd Time when server connection is finished.
connectStart Time just before server connection begins.
domComplete Time just before document readiness completes.
domContentLoadedEventEnd Time after DOMContentLoaded event completes.
domContentLoadedEventStart Time just before DOMContentLoaded starts.
domInteractive Time just before readiness set to interactive.
domLoading Time just before readiness set to loading.
domainLookupEnd Time after domain name lookup.
domainLookupStart Time just before domain name lookup.
fetchStart Time when the resource starts being fetched.
loadEventEnd Time when the load event is complete.
loadEventStart Time just before the load event is fired.
navigationStart Time after the previous document begins unload.
redirectCount Number of redirects since the last non-redirect.
redirectEnd Time after last redirect response ends.
redirectStart Time of fetch that initiated a redirect.
requestStart Time just before a server request.
responseEnd Time after the end of a response or connection.
responseStart Time just before the start of a response.
timing Reference to a performance timing object.
navigation Reference to performance navigation object.
performance Reference to performance object for a window.
type Type of the last non-redirect navigation event.
unloadEventEnd Time after the previous document is unloaded.
unloadEventStart Time just before the unload event is fired.
控制台输出:
Page Title is : Google
['connectEnd': 2725.146514015987, 'connectStart': 1503.1734234800108, 'decodedBodySize': 204837, 'domComplete': 7603.4821342458235, 'domContentLoadedEventEnd': 4588.4400826362535, 'domContentLoadedEventStart': 4576.987229310746, 'domInteractive': 4559.208601432438, 'domainLookupEnd': 1503.1734234800108, 'domainLookupStart': 1503.1734234800108, 'duration': 7623.300733238722, 'encodedBodySize': 61075, 'entryType': 'navigation', 'fetchStart': 1503.1734234800108, 'initiatorType': 'navigation', 'loadEventEnd': 7623.300733238722, 'loadEventStart': 7603.516579526861, 'name': 'document', 'nextHopProtocol': 'h2', 'redirectCount': 0, 'redirectEnd': 1501.686197816412, 'redirectStart': 22.057947498907886, 'requestStart': 2725.729247123413, 'responseEnd': 3624.7713441197043, 'responseStart': 3349.3679493549, 'secureConnectionStart': 2049.7916668355165, 'startTime': 0, 'transferSize': 61926, 'type': 'navigate', 'unloadEventEnd': 0, 'unloadEventStart': 0, 'workerStart': 0, 'connectEnd': 3388.3040845619494, 'connectStart': 3388.3040845619494, 'decodedBodySize': 1730, 'domainLookupEnd': 3388.3040845619494, 'domainLookupStart': 3388.3040845619494, 'duration': 237.3373068328902, 'encodedBodySize': 1730, 'entryType': 'resource', 'fetchStart': 3388.3040845619494, 'initiatorType': 'img', 'name': 'https://www.google.co.in/logos/doodles/2018/doodle-snow-games-day-15-5907794870927360.4-s.png', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 3439.3892730100556, 'responseEnd': 3625.6413913948395, 'responseStart': 3625.271003314041, 'secureConnectionStart': 0, 'startTime': 3388.3040845619494, 'transferSize': 2242, 'workerStart': 0, 'connectEnd': 0, 'connectStart': 0, 'decodedBodySize': 0, 'domainLookupEnd': 0, 'domainLookupStart': 0, 'duration': 230.20794413542762, 'encodedBodySize': 0, 'entryType': 'resource', 'fetchStart': 3425.689371645131, 'initiatorType': 'css', 'name': 'https://ssl.gstatic.com/gb/images/i1_1967ca6a.png', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 0, 'responseEnd': 3655.8973157805594, 'responseStart': 0, 'secureConnectionStart': 0, 'startTime': 3425.689371645131, 'transferSize': 0, 'workerStart': 0, 'connectEnd': 0, 'connectStart': 0, 'decodedBodySize': 0, 'domainLookupEnd': 0, 'domainLookupStart': 0, 'duration': 969.9734406621285, 'encodedBodySize': 0, 'entryType': 'resource', 'fetchStart': 3502.3913129811713, 'initiatorType': 'script', 'name': 'https://www.gstatic.com/external_hosted/createjs/createjs-2015.11.26.min.js', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 0, 'responseEnd': 4472.364753643298, 'responseStart': 0, 'secureConnectionStart': 0, 'startTime': 3502.3913129811713, 'transferSize': 0, 'workerStart': 0, 'connectEnd': 3520.930168473896, 'connectStart': 3520.930168473896, 'decodedBodySize': 12232, 'domainLookupEnd': 3520.930168473896, 'domainLookupStart': 3520.930168473896, 'duration': 134.0411771046674, 'encodedBodySize': 12232, 'entryType': 'resource', 'fetchStart': 3520.930168473896, 'initiatorType': 'css', 'name': 'https://www.google.co.in/logos/2018/snowgames_bobsled/cta.png', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 3525.3821197382813, 'responseEnd': 3654.971345578564, 'responseStart': 3625.955856548778, 'secureConnectionStart': 0, 'startTime': 3520.930168473896, 'transferSize': 12745, 'workerStart': 0, 'connectEnd': 4527.024551785848, 'connectStart': 4527.024551785848, 'decodedBodySize': 842405, 'domainLookupEnd': 4527.024551785848, 'domainLookupStart': 4527.024551785848, 'duration': 2632.3253968704244, 'encodedBodySize': 265174, 'entryType': 'resource', 'fetchStart': 4527.024551785848, 'initiatorType': 'script', 'name': 'https://www.google.co.in/logos/2018/snowgames_bobsled/snowgames_bobsled18.2.js', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 4528.843667863202, 'responseEnd': 7159.3499486562705, 'responseStart': 4946.163646693538, 'secureConnectionStart': 0, 'startTime': 4527.024551785848, 'transferSize': 265741, 'workerStart': 0, 'connectEnd': 4558.896162471504, 'connectStart': 4558.896162471504, 'decodedBodySize': 0, 'domainLookupEnd': 4558.896162471504, 'domainLookupStart': 4558.896162471504, 'duration': 1005.3106518587082, 'encodedBodySize': 0, 'entryType': 'resource', 'fetchStart': 4558.896162471504, 'initiatorType': 'other', 'name': 'https://www.google.co.in/gen_204?s=webaft&atyp=csi&ei=N6mPWp6mC8H00ASJtoL4Ag&rt=wsrt.3384,aft.1175,prt.1175', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 4560.575876470308, 'responseEnd': 5564.206814330209, 'responseStart': 5564.1444075857435, 'secureConnectionStart': 0, 'startTime': 4558.896162471504, 'transferSize': 358, 'workerStart': 0, 'connectEnd': 4576.353841378264, 'connectStart': 4576.353841378264, 'decodedBodySize': 417606, 'domainLookupEnd': 4576.353841378264, 'domainLookupStart': 4576.353841378264, 'duration': 1903.6302084304214, 'encodedBodySize': 144417, 'entryType': 'resource', 'fetchStart': 4576.353841378264, 'initiatorType': 'script', 'name': 'https://www.google.co.in/xjs/_/js/k=xjs.s.en.smQ6-n1iGHA.O/m=sx,sb,cdos,cr,elog,hsm,jsa,r,d,csi/am=wCLkeMEAyP8JgogEKwgsQIpgGBA/rt=j/d=1/t=zcms/rs=ACT90oH8FZej9QmzW2qBqlOOQ7DASmnKAA', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 4578.110550711152, 'responseEnd': 6479.984049808687, 'responseStart': 5564.372556917789, 'secureConnectionStart': 0, 'startTime': 4576.353841378264, 'transferSize': 144999, 'workerStart': 0, 'connectEnd': 0, 'connectStart': 0, 'decodedBodySize': 0, 'domainLookupEnd': 0, 'domainLookupStart': 0, 'duration': 574.9679253647753, 'encodedBodySize': 0, 'entryType': 'resource', 'fetchStart': 4791.30009458269, 'initiatorType': 'script', 'name': 'https://www.gstatic.com/og/_/js/k=og.og2.en_US.SpCLDXmWlPM.O/rt=j/m=def/exm=in,fot/d=1/ed=1/rs=AA2YrTtMoJJMGQfOfYZyZ7reaiaiva99OQ', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 0, 'responseEnd': 5366.2680199474635, 'responseStart': 0, 'secureConnectionStart': 0, 'startTime': 4791.30009458269, 'transferSize': 0, 'workerStart': 0, 'connectEnd': 0, 'connectStart': 0, 'decodedBodySize': 0, 'domainLookupEnd': 0, 'domainLookupStart': 0, 'duration': 1586.0147296126488, 'encodedBodySize': 0, 'entryType': 'resource', 'fetchStart': 5417.5655534222005, 'initiatorType': 'script', 'name': 'https://apis.google.com/_/scs/abc-static/_/js/k=gapi.gapi.en.29tAKSAI8cc.O/m=gapi_iframes,googleapis_client,plusone/rt=j/sv=1/d=1/ed=1/am=IA/rs=AHpOoo82FxkTgGRAoVn-fgFU3zdQ5QIqEw/cb=gapi.loaded_0', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 0, 'responseEnd': 7003.580283034848, 'responseStart': 0, 'secureConnectionStart': 0, 'startTime': 5417.5655534222005, 'transferSize': 0, 'workerStart': 0, 'connectEnd': 6646.626267079796, 'connectStart': 6646.626267079796, 'decodedBodySize': 83168, 'domainLookupEnd': 6646.626267079796, 'domainLookupStart': 6646.626267079796, 'duration': 783.8056119062338, 'encodedBodySize': 27299, 'entryType': 'resource', 'fetchStart': 6646.626267079796, 'initiatorType': 'script', 'name': 'https://www.google.co.in/xjs/_/js/k=xjs.s.en.smQ6-n1iGHA.O/m=aa,abd,async,dvl,foot,fpe,ipv6,lu,m,mu,sf,sonic,d3l/am=wCLkeMEAyP8JgogEKwgsQIpgGBA/exm=sx,sb,cdos,cr,elog,hsm,jsa,r,d,csi/rt=j/d=1/ed=1/t=zcms/rs=ACT90oH8FZej9QmzW2qBqlOOQ7DASmnKAA?xjs=s1', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 6648.111871788991, 'responseEnd': 7430.431878986027, 'responseStart': 7159.731278179281, 'secureConnectionStart': 0, 'startTime': 6646.626267079796, 'transferSize': 27880, 'workerStart': 0, 'connectEnd': 0, 'connectStart': 0, 'decodedBodySize': 0, 'domainLookupEnd': 0, 'domainLookupStart': 0, 'duration': 930.0310980101976, 'encodedBodySize': 0, 'entryType': 'resource', 'fetchStart': 6668.677730761095, 'initiatorType': 'img', 'name': 'https://www.google.com/textinputassistant/tia.png', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 0, 'responseEnd': 7598.708828771292, 'responseStart': 0, 'secureConnectionStart': 0, 'startTime': 6668.677730761095, 'transferSize': 0, 'workerStart': 0, 'connectEnd': 7222.302954756732, 'connectStart': 7222.302954756732, 'decodedBodySize': 469, 'domainLookupEnd': 7222.302954756732, 'domainLookupStart': 7222.302954756732, 'duration': 208.68612730489625, 'encodedBodySize': 469, 'entryType': 'resource', 'fetchStart': 7222.302954756732, 'initiatorType': 'img', 'name': 'https://www.google.co.in/logos/2018/snowgames_bobsled/main-sprite.png', 'nextHopProtocol': 'h2', 'redirectEnd': 0, 'redirectStart': 0, 'requestStart': 7223.911346761861, 'responseEnd': 7430.989082061627, 'responseStart': 7430.7698479787905, 'secureConnectionStart': 0, 'startTime': 7222.302954756732, 'transferSize': 980, 'workerStart': 0]
从此输出中,您可以轻松地提取出您感兴趣的性能统计数据。
【讨论】:
这行不通;到目前为止,我在浏览器的几个页面上对其进行了测试。在调用console.log(window.performance.getEntries());
时,最后一个条目中的responseEnd
始终比性能图上最后一帧加载的时间至少低1000 ms(在帖子的屏幕截图中)。此外,将鼠标悬停在图表上时,我可以看到随着时间的推移页面的外观。在时间responseEnd
(从最后一个条目)我可以清楚地看到页面没有完全加载。
您问了一个关于如何从 Chrome 性能工具访问数据的问题,我已为您构建了一个答案。如果您发现行为有任何偏差,您应该向 Chromium 项目 提出,以确保对社区有所帮助。
我的问题是关于从 Chrome 性能工具访问数据并从中获取客观加载时间。在我的问题中,我实际上在这里访问了性能工具:console.log(performance.timing.loadEventEnd-performance.timing.navigationStart)
。我从性能工具中获得的时间没有意义,因此我问了这个问题。
@DebanjanB 我从未尝试过这样做,它非常有用,谢谢! Max,如果你想要客观的加载时间,你为什么要跳过这么多圈?只需跟踪导航到页面和最后一个元素加载之间的时间。完毕。此外,使用 WebdriverWait 将避免使用 time.sleep() 人为地夸大您的数字。
@Aphid 我尝试测量导航到页面和最后一个元素加载之间的时间。从浏览器控制台执行此操作时,它可以很好地近似实际加载时间。出于某种原因,当从 Selenium(禁用缓存)运行相同的 js 命令时,我的加载时间快得离谱(比我自己访问网站时看到的快 10-20 倍)。【参考方案2】:
右键单击演奏录音并选择保存配置文件。它会为您提供大量数据,但可能应该包含您需要的任何内容(我认为这是绩效记录报告可视化的源数据)。
DevTools 用于从浏览器获取数据的底层协议称为 Chrome DevTools 协议。其他客户端,例如 Selenium,可以启动与浏览器的会话(就像 DevTools 一样),并使用该协议来获取与 DevTools 获取的相同数据。底层协议方法称为Performance.getMetrics。我不熟悉 Selenium,但它应该可以以某种方式连接到 CDP。
您还可以使用 Puppeteer 自动执行此操作。我在Using DevTools Features Without Opening DevTools 中提供了一个使用 Puppeteer 访问 DevTools 功能的示例。
【讨论】:
以上是关于Chrome:性能数据 API的主要内容,如果未能解决你的问题,请参考以下文章
Chrome Developer Tools:Network Panel说明
Web Audio API:当使用媒体流时,Firefox 中的 FFT 数据与 chrome 中的不同?