Skip to content

collects page performance metrics through javascript methods supported by chome and firefox

License

Notifications You must be signed in to change notification settings

sergueik/chrome_page_performance_sqlite_java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Info

The Java Chrome Page Element Load Timing Collector project is based on Szada30/Java-Selenium-LoadTime project and .Net version of the Chrome Page Element Load Timing Collector.

Selenium driver is used to launch the Chrome browser (alternatively Chome Devkit Protocol driver may be used) and load the target page then collects the page performance timings offered by Chrome browser:

var performance = window.performance;
var timings = performance.timing;
return timings;

Alternatively the more advanced timing.js script from Addy Osmani's repository is called, and the results are deserialized into a Map<String, Double> either implicitly by deserializing the string value produced by JSON.stringify() method with one of many available JSON parsing libraries or by extracting the object via home-brewed parser of the value returned by Javascript API, as shown below.

data.db

See https://github.com/addyosmani/timing.js/blob/master/timing.js for details of how the timings.loadTime,timings.domReadyTime etc. are calculated):

(function(window) {
    'use strict';
    window.timing = window.timing ||
        {
            getTimes: function(opt) {
                var performance = window.performance ||
                    window.webkitPerformance || window.msPerformance ||
                    window.mozPerformance;
                if (performance === undefined) {
                    return '';
                }
                var timings = performance.timing || {};
                NOTE: legacy conversion
                if (opt && opt['stringify']){
                    return JSON.stringify(timings);
                } else {
                	return timings;
                }
            },
            getNetwork: function(opt) {
                var network = performance.getEntries() || {};
                if (opt && opt['stringify']){
                	return JSON.stringify(network);
                } else {
                	return network;
                }
            }
        }
})(typeof window !== 'undefined' ? window : {});
return window.timing.getTimes();
return window.timing.getNetwork({stringify:true});

Running this Javascript in the browser will return

{
  unloadEventEnd = 1512339255280,
  responseEnd = 1512339255305,
  responseStart = 1512339255277,
  domInteractive = 1512339256932,
  domainLookupEnd = 1512339255033,
  unloadEventStart = 1512339255279,
  domComplete = 1512339263380,
  domContentLoadedEventStart = 1512339256932,
  domainLookupStart = 1512339255033,
  redirectEnd = 0,
  redirectStart = 0,
  connectEnd = 1512339255033,
  toJSON = {},
  connectStart = 1512339255033,
  loadEventStart = 1512339263380,
  navigationStart = 1512339255032,
  requestStart = 1512339255035,
  secureConnectionStart = 0,
  fetchStart = 1512339255033,
  domContentLoadedEventEnd = 1512339256934,
  domLoading = 1512339255302,
  loadEventEnd = 1512339263471
}

of (when opt[stringify] is set):

{
  "navigationStart": 1512338852987,
  "unloadEventStart": 1512338855099,
  "unloadEventEnd": 1512338855100,
  "redirectStart": 0,
  "redirectEnd": 0,
  "fetchStart": 1512338852988,
  "domainLookupStart": 1512338852988,
  "domainLookupEnd": 1512338852988,
  "connectStart": 1512338852988,
  "connectEnd": 1512338852988,
  "secureConnectionStart": 0,
  "requestStart": 1512338852990,
  "responseStart": 1512338855090,
  "responseEnd": 1512338855130,
  "domLoading": 1512338855135,
  "domInteractive": 1512338856653,
  "domContentLoadedEventStart": 1512338856655,
  "domContentLoadedEventEnd": 1512338856658,
  "domComplete": 1512338862728,
  "loadEventStart": 1512338862728,
  "loadEventEnd": 1512338862864
}

The Java application subsequently dumps the results ino SQLite database using JDBC

This is a lot easier to process than the full SeleniumDriver log:

ChromeOptions options = new ChromeOptions();
LoggingPreferences loggingPreferences = new LoggingPreferences();
loggingPreferences.enable(LogType.PERFORMANCE, Level.ALL);
capabilities.setCapability(CapabilityType.LOGGING_PREFS,
    loggingPreferences);
  driver = new ChromeDriver(capabilities);

LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);

which looks like

...
{
    "message": {
        "method": "Page.loadEventFired",
        "params": {
            "timestamp": 534304.116728
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Page.frameStoppedLoading",
        "params": {
            "frameId": "2C55735DE539FCE8BEA1A6CA827A511"
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Page.domContentEventFired",
        "params": {
            "timestamp": 534304.117791
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Page.frameStartedLoading",
        "params": {
            "frameId": "2C55735DE539FCE8BEA1A6CA827A511"
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Network.requestWillBeSent",
        "params": {
            "documentURL": "https://www.priceline.com/",
            "frameId": "2C55735DE539FCE8BEA1A6CA827A511",
            "initiator": {
                "type": "other"
            },
            "loaderId": "14DFFA25E9B5979541C96D5481B309AA",
            "request": {
                "headers": {
                    "Upgrade-Insecure-Requests": "1",
                    "User-Agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/65.0.3325.181 Safari/537.36"
                },
                "initialPriority": "VeryHigh",
                "method": "GET",
                "mixedContentType": "none",
                "referrerPolicy": "no-referrer-when-downgrade",
                "url": "https://www.priceline.com/"
            },
            "requestId": "14DFFA25E9B5979541C96D5481B309AA",
            "timestamp": 534305.113269,
            "type": "Document",
            "wallTime": 1523124859.15939
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Network.responseReceived",
        "params": {
            "frameId": "2C55735DE539FCE8BEA1A6CA827A511",
            "loaderId": "14DFFA25E9B5979541C96D5481B309AA",
            "requestId": "14DFFA25E9B5979541C96D5481B309AA",
            "response": {
                "connectionId": 9,
                "connectionReused": false,
                "encodedDataLength": 711,
                "fromDiskCache": false,
                "fromServiceWorker": false,
                "headers": {
                    "accept-ranges": "bytes\nbytes",
                    "content-encoding": "gzip",
                    "content-type": "text/html; charset=utf-8",
                    "date": "Sat, 07 Apr 2018 18:14:21 GMT",
                    "etag": "W/\"4f6f6-OEvAhjqSi26QYORsGBqJx8NiXSI\"",
                    "server": "nginx",
                    "set-cookie": "SITESERVER=ID=2201b110990e4a5e879513e0bd7a5b1b; Domain=.priceline.com; Path=/; Expires=Mon, 30 Mar 2048 18:14:20 GMT; Secure\nvid=v2018040718142064586c21; Domain=.priceline.com; Path=/; HttpOnly; Secure\nReferral=CLICKID=&WEBENTRYTIME=4%2F7%2F2018%2014%3A14%3A20&ID=DIRECT&PRODUCTID=&SOURCEID=DT; Domain=.priceline.com; Path=/; Expires=Mon, 07 May 2018 18:14:20 GMT; HttpOnly; Secure\npclnguidse=52a268c6b2019fe7ab28a88500e6e1968b93f219;Path=/;Domain=.priceline.com\npclnguidpe=52a268c6b2019fe7ab28a88500e6e1968b93f219;Path=/;Domain=.priceline.com;Expires=Tue, 04-Apr-2028 18:14:21 GMT",
                    "status": "200",
                    "vary": "Accept-Encoding",
                    "via": "1.1 varnish\n1.1 varnish",
                    "wsheader": "ws=fMIA/fIAD/ny-home001 D=0.437 NT=448",
                    "x-cache": "MISS, MISS",
                    "x-cache-hits": "0, 0",
                    "x-served-by": "cache-iad2127-IAD, cache-mia17629-MIA",
                    "x-timer": "S1523124861.619507,VS0,VE484"
                },
                "mimeType": "text/html",
                "protocol": "h2",
                "remoteIPAddress": "151.101.2.186",
                "remotePort": 443,
                "requestHeaders": {
                    ":authority": "www.priceline.com",
                    ":method": "GET",
                    ":path": "/",
                    ":scheme": "https",
                    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
                    "accept-encoding": "gzip, deflate",
                    "upgrade-insecure-requests": "1",
                    "user-agent": "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/65.0.3325.181 Safari/537.36"
                },
                "securityDetails": {
                    "certificateId": 0,
                    "cipher": "AES_128_GCM",
                    "issuer": "GlobalSign CloudSSL CA - SHA256 - G3",
                    "keyExchange": "ECDHE_RSA",
                    "keyExchangeGroup": "X25519",
                    "protocol": "TLS 1.2",
                    "sanList": ["priceline.map.fastly.net", "*.pclncdn.com", "*.priceline.com", "mobileimg.priceline.com", "pclncdn.com", "tickets.priceline.com", "travel.priceline.com", "www.priceline.com"],
                    "signedCertificateTimestampList": [{
                        "hashAlgorithm": "SHA-256",
                        "logDescription": "Symantec log",
                        "logId": "DDEB1D2B7A0D4FA6208B81AD8168707E2E8E9D01D55C888D3D11C4CDB6ECBECC",
                        "origin": "Embedded in certificate",
                        "signatureAlgorithm": "ECDSA",
                        "signatureData": "3046022100EF2C99BC7629C684FDF08D939F2AD190D767DA05308DD170FC5F9543BDD7A28D0221009DC0CAC7EF21919E7D3F699961E51D4312E8022FAB904959FF8BE973EFC6F578",
                        "status": "Verified",
                        "timestamp": 1516741627217.0
                    }, {
                        "hashAlgorithm": "SHA-256",
                        "logDescription": "Google 'Skydiver' log",
                        "logId": "BBD9DFBC1F8A71B593942397AA927B473857950AAB52E81A909664368E1ED185",
                        "origin": "Embedded in certificate",
                        "signatureAlgorithm": "ECDSA",
                        "signatureData": "304402205B7043E321863ABDC7CDCA3828E36E3CE7D25661E3E508B3A67C499A6F32A6FA022037E03E4F8A57A3E71E8F5ABB0043EDD8502AAF67845B7BB4054BD7526CC99C18",
                        "status": "Verified",
                        "timestamp": 1516741627363.0
                    }, {
                        "hashAlgorithm": "SHA-256",
                        "logDescription": "DigiCert Log Server",
                        "logId": "5614069A2FD7C2ECD3F5E1BD44B23EC74676B9BC99115CC0EF949855D689D0DD",
                        "origin": "Embedded in certificate",
                        "signatureAlgorithm": "ECDSA",
                        "signatureData": "3046022100D5B55C035E35C5DC9EC5BBD954F5C985799F31861D0E20E837412BCAE186BB1C0221008393F5E08D549877235006A5F276A9CD326AEE37EA67937E6162B2560CFE8B94",
                        "status": "Verified",
                        "timestamp": 1516741627307.0
                    }, {
                        "hashAlgorithm": "SHA-256",
                        "logDescription": "Google 'Rocketeer' log",
                        "logId": "EE4BBDB775CE60BAE142691FABE19E66A30F7E5FB072D88300C47B897AA8FDCB",
                        "origin": "Embedded in certificate",
                        "signatureAlgorithm": "ECDSA",
                        "signatureData": "304402203B3F86F6E547BF5F6E14E218A7EFBD09DDA0F617BBA2B3CE0A8B1F1198236083022048F02E2079AEF019969E54D47E954E09F960A655AC5FA967C5805288C71374AD",
                        "status": "Verified",
                        "timestamp": 1516741627937.0
                    }],
                    "subjectName": "priceline.map.fastly.net",
                    "validFrom": 1516741624,
                    "validTo": 1536238759
                },
                "securityState": "secure",
                "status": 200,
                "statusText": "",
                "timing": {
                    "connectEnd": 307.547000003979,
                    "connectStart": 138.16199998837,
                    "dnsEnd": 138.16199998837,
                    "dnsStart": 129.266000003554,
                    "proxyEnd": 126.842000056058,
                    "proxyStart": 114.427000051364,
                    "pushEnd": 0,
                    "pushStart": 0,
                    "receiveHeadersEnd": 812.544999993406,
                    "requestTime": 534304.292439,
                    "sendEnd": 309.232000028715,
                    "sendStart": 308.51000000257,
                    "sslEnd": 307.429000036791,
                    "sslStart": 176.882000057958,
                    "workerReady": -1,
                    "workerStart": -1
                },
                "url": "https://www.priceline.com/"
            },
            "timestamp": 534305.117249,
            "type": "Document"
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Network.dataReceived",
        "params": {
            "dataLength": 16862,
            "encodedDataLength": 0,
            "requestId": "14DFFA25E9B5979541C96D5481B309AA",
            "timestamp": 534305.117938
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Page.frameNavigated",
        "params": {
            "frame": {
                "id": "2C55735DE539FCE8BEA1A6CA827A511",
                "loaderId": "14DFFA25E9B5979541C96D5481B309AA",
                "mimeType": "text/html",
                "securityOrigin": "https://www.priceline.com",
                "url": "https://www.priceline.com/"
            }
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Network.dataReceived",
        "params": {
            "dataLength": 48674,
            "encodedDataLength": 0,
            "requestId": "14DFFA25E9B5979541C96D5481B309AA",
            "timestamp": 534305.151364
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
}, {
    "message": {
        "method": "Network.dataReceived",
        "params": {
            "dataLength": 65536,
            "encodedDataLength": 0,
            "requestId": "14DFFA25E9B5979541C96D5481B309AA",
            "timestamp": 534305.176181
        }
    },
    "webview": "2C55735DE539FCE8BEA1A6CA827A511"
},
...

Loading results into ELK is a work in progress. Some tests work successfully only when the browser is visible , and fail with timeout exception when headless. It is not related to the main objective of this project.

See Also

Note

The project was earlier develped inside a repository sergueik/selenium_java - check the old past histories there.

License

This project is licensed under the terms of the MIT license.

Author

Serguei Kouzmine

About

collects page performance metrics through javascript methods supported by chome and firefox

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published