0

I am writing some code to automate calculating certain page performance metrics. The results I am getting for page size are different by different methods:

What I want to achieve is to read these values shown in this screenshot: What I am hoping to achieve (example from Google.com)

Methods I am using:

Method giving different page load time and different transferred sizes: Totalbytes and NetData return very different numbers, both very far from what the screenshot would show

public void testing() throws HarReaderException {
    JavascriptExecutor js1=((JavascriptExecutor)driver);
    try {
        Thread.sleep(5000);
    }catch(Exception e) {e.printStackTrace();}
    String url=driver.getCurrentUrl();
    System.out.println("Current URL :"+url);
    long pageLoadTime= (Long)js1.executeScript("return (window.performance.timing.loadEventEnd-window.performance.timing.responseStart)");
    long TTFB= (Long)js1.executeScript("return (window.performance.timing.responseStart-window.performance.timing.navigationStart)");
    long endtoendRespTime= (Long)js1.executeScript("return (window.performance.timing.loadEventEnd-window.performance.timing.navigationStart)");

    Date date = new Date();
    //Timestamp ts=new Timestamp(date.getTime());

    System.out.println("PageLoadTime Time :"+pageLoadTime);
    System.out.println("TTFB :"+TTFB);
    System.out.println("Customer perceived Time :"+endtoendRespTime);
    System.out.println("timeStamp");
    String scriptToExecute = "var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {}; var network = performance.getEntries() || {}; return network;";
    String netData = ((JavascriptExecutor)driver).executeScript(scriptToExecute).toString();
    System.out.println("Net data: " + netData);
    String anotherScript = "return performance\n" +
            "  .getEntriesByType(\"resource\")\n" +
            "  .map((x) => x.transferSize)\n" +
            "  .reduce((a, b) => (a + b), 0);";    //I have tried encodedSize here as well, still gives different results
    System.out.println("THIS IS HOPEFULLY THE TOTAL TRANSFER SIZE " + js1.executeScript((anotherScript)).toString());
    int totalBytes = 0;
    for (LogEntry entry : driver.manage().logs().get(LogType.PERFORMANCE)) {
        if (entry.getMessage().contains("Network.dataReceived")) {
            Matcher dataLengthMatcher = Pattern.compile("dataLength\":(.*?),").matcher(entry.getMessage());  //I tried encodedLength and other methods but always get different results from the actual page
            dataLengthMatcher.find();
            totalBytes = totalBytes + Integer.parseInt(dataLengthMatcher.group(1));
            //Do whatever you want with the data here.
        }
    }
    System.out.println(totalBytes);
}

Setting up selenium Chrome driver, enabling performance logging and mobbrowser proxy:

@BeforeTest
public void setUp() {

    // start the proxy
    proxy = new BrowserMobProxyServer();
    proxy.start(0);

    //get the Selenium proxy object - org.openqa.selenium.Proxy;
    Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);

    // configure it as a desired capability
    DesiredCapabilities capabilities = new DesiredCapabilities().chrome();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    capabilities.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);

    capabilities.setCapability(CapabilityType.PROXY, seleniumProxy);
    ChromeOptions options = new ChromeOptions();
    options.addArguments("--incognito");
    capabilities.setCapability(ChromeOptions.CAPABILITY, options);
    //set chromedriver system property
    System.setProperty("webdriver.chrome.driver", driverPath);
    driver = new ChromeDriver(capabilities);
    // enable more detailed HAR capture, if desired (see CaptureType for the complete list)
    proxy.enableHarCaptureTypes(CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT);



}

Methods I am using to analyze the page: This method was supposed to show the Load Time in chrome inspector, but it is always showing a lesser number (I think it is showing the time of the last response received instead of DOMContentLoaded or Load Time)

public double calculatePageLoadTime(String filename) throws HarReaderException {
    HarReader harReader = new HarReader();
    de.sstoehr.harreader.model.Har har = harReader.readFromFile(new File(filename));

    HarLog log = har.getLog();
    // Access all pages elements as an object

    long startTime =   log.getPages().get(0).getStartedDateTime().getTime();

    // Access all entries elements as an object

    List<HarEntry> hentry = log.getEntries();

    long loadTime = 0;

    int entryIndex = 0;
    //Output "response" code of entries.
    for (HarEntry entry : hentry)
    {


        long entryLoadTime = entry.getStartedDateTime().getTime() + entry.getTime();

        if(entryLoadTime > loadTime){
            loadTime = entryLoadTime;
        }

        entryIndex++;
    }

    long loadTimeSpan = loadTime - startTime;

    Double webLoadTime = ((double)loadTimeSpan) / 1000;
    double webLoadTimeInSeconds = Math.round(webLoadTime * 100.0) / 100.0;

    return webLoadTimeInSeconds;
}

I am getting the total number of requests by reading the HAR file from the page, but for some reason it is always 10% less then the actual:

    public int getNumberRequests(String filename) throws HarReaderException {
    HarReader harReader = new HarReader();
    de.sstoehr.harreader.model.Har har = harReader.readFromFile(new File(filename));

    HarLog log = har.getLog();
    return log.getEntries().size();
}

Testing this on google gives very different results by each method, which are usually 10-200% off from correct numbers.

Why does this happen? Is there a simple way to get those metrics properly from Chrome or any library that makes this easier? My task is automate doing performance analysis on thousands of pages.

zalambura
  • 31
  • 4

1 Answers1

0

I personally analyzed this on my system over and over again and came up with this -

  1. The resource size which its showing currently is the amount of resource fetched till page load event is triggered.

  2. So to overcome this you need to capture the the resource size variable after the page load event also until it stabilizes.Then it will match the actual console values.

Tank
  • 19
  • 3