3

In the following image, I want the total response time from the webpage. I can't seem to find it in the file sample HAR file, i.e. 38.79s in this case. Does anyone know how to get this?

I am going to use Selenium along with Firebug and NetExport to export the HAR file, but right now I am trying to do it manually. Adding the individual responses does not give correct numbers.

enter image description here

At some point I would like a Java program to find and extract the total response time.

Neo84
  • 187
  • 2
  • 16

4 Answers4

6

The total load time is not calculated by summarizing all request times but by the latest request end time. Graphically spoken it is the right end of the request bar ending at the far right. In your example screenshot it's either the last, third to last or fourth to last request.

The request end time is calculated by the request start time indicated by the startedDateTime property of a request plus the time span needed for the response, which is available through the time property of each request. To get the maximum request end time, you need to loop over all requests and compare the end time of each request. See the following code:

var startTime = new Date(har.log.pages[0].startedDateTime);
var loadTime = 0;

// Loop over all entries to determine the latest request end time
// The variable 'har' contains the JSON of the HAR file
har.log.entries.forEach(function(entry) {
  var entryLoadTime = new Date(entry.startedDateTime);
  // Calculate the current request's end time by adding the time it needed to load to its start time
  entryLoadTime.setMilliseconds(entryLoadTime.getMilliseconds() + entry.time);
  // If the current request's end time is greater than the current latest request end time, then save it as new latest request end time
  if (entryLoadTime > loadTime) {
    loadTime = entryLoadTime;
  }
});

var loadTimeSpan = loadTime - startTime;

Executing this code the variable loadTimeSpan will contain the wanted time span in milliseconds.

Important note:

The so calculated time span may still differ from the time displayed by Firebug or the online HAR Viewer, because they split the requests into different phases depending on the time elapsed between two requests. They then calculate the time span from the first to the last request of each phase and summarize those time spans in the end.

Sebastian Zartner
  • 16,477
  • 8
  • 74
  • 116
  • Would similar logic be able to be applied in java, or would I just use java to execute that? – Neo84 Jun 10 '15 at 20:38
  • The code above is JavaScript as you didn't mention anything about Java. In Java the code surely looks a different, but the basic logic (looping over all requests and get the latest request end time) is the same. – Sebastian Zartner Jun 10 '15 at 21:12
  • Just added info that I would eventually do this java. – Neo84 Jun 11 '15 at 00:15
  • Is entry supposed to be entries from har file? – Neo84 Jun 11 '15 at 01:51
  • If you are talking about the `entry` parameter within the callback function of the `forEach()` call, then yes. See the [documentation for `forEach()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach) in this case. – Sebastian Zartner Jun 11 '15 at 05:21
  • So they are comparing the time difference between one request and the previous request? – Neo84 Jun 11 '15 at 19:46
  • The loop is used to determine the latest end time by comparing each request with the current latest request end time. I added comments to the code to clarify that. – Sebastian Zartner Jun 11 '15 at 20:32
  • I added a java version, but I think it will have problems if there is more than one startTime for the pages. In that case, I am not sure if I go through each one and find the lowest or earliest time. – Neo84 Jun 16 '15 at 03:57
  • If there is more than one entry in the `pages` array, this means that multiple pages were visited, e.g. through a redirect. In that case the first one, i.e. `pages[0]`, is the first one visited. – Sebastian Zartner Jun 16 '15 at 05:28
  • ahhh ok. Makes sense. But ok, so my java code give me the correct results for the simple google har file example, but for the original gametrailers har file, it is suppose to be about 37s but I am getting 173s. That is a big difference. Not sure if something is off. – Neo84 Jun 16 '15 at 17:29
  • Regarding the time difference please see the important note I added lately to my answer. – Sebastian Zartner Jun 16 '15 at 19:49
  • ok, I re-did the example, and from my java code, its only about 4-5s off. Thanks. I will continue to do some more testing. – Neo84 Jun 16 '15 at 22:34
3

Based on @Sebastian Zartner's answer and the Google sample, the following is an Java attempt:

public class ParseHarFile {

     public static void main(String[] args) {
         String fileName = "www.google.com.har";

         ReadHarFile(fileName);
    }

    public static void ReadHarFile(String fileName){

         File f = new File("C:\\Users\\Administrator\\Desktop\\test_files\\" + fileName);
         HarFileReader r = new HarFileReader();

         try
         {
             System.out.println("Reading " + fileName);
             HarLog log = r.readHarFile(f);

             // Access all pages elements as an object
              HarPages pages = log.getPages();

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

              System.out.println("page start time: " + startTime);

             // Access all entries elements as an object
             HarEntries entries = log.getEntries();

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

             long loadTime = 0;

             int entryIndex = 0;
             //Output "response" code of entries.
             for (HarEntry entry : hentry)
             {
                 System.out.println("entry: " + entryIndex);
                 System.out.println("request code: " + entry.getRequest().getMethod()); //Output request type
                 System.out.println("    start time: " + entry.getStartedDateTime().getTime()); // Output start time
                 System.out.println("    time: " + entry.getTime()); // Output start time

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

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

                 System.out.println();
                 entryIndex++;
             }

             long loadTimeSpan = loadTime - startTime;
             System.out.println("loadTimeSpan: " + loadTimeSpan);

             Double webLoadTime = ((double)loadTimeSpan) / 1000;
             double webLoadTimeInSeconds = Math.round(webLoadTime * 100.0) / 100.0; 
             System.out.println("Web Load Time: " + webLoadTimeInSeconds) ;

         }
         catch (JsonParseException e)
         {
             e.printStackTrace();
             System.out.println("Parsing error during test");
         }
         catch (IOException e)
         {
             e.printStackTrace();
             System.out.println("IO exception during test");
         }
     }

}

Sebastian Zartner
  • 16,477
  • 8
  • 74
  • 116
Neo84
  • 187
  • 2
  • 16
0

Here's a Java function that returns page load time. In addition, it allows you to parse corrupted HAR files that have missing elements or other violations to the specification. More info. on HarLib here.

public long calculatePageLoadTime(String filename) {
    File file = new File("c:\\" + filename);
    HarFileReader fileReader = new HarFileReader();
    long pageLoadTime = 0;
    try {
        //Catch missing elements or other violations to HAR specification.
        //You can still read most of a file even if some parts are corrupted.
        List<HarWarning> warnings = new ArrayList<HarWarning>();
        HarLog log = fileReader.readHarFile(file, warnings);
        for (HarWarning warning : warnings)
            System.out.println("File:" + filename + " - Warning:" + warning);

        //Get page load start time
        HarPages pages = log.getPages();
        HarPage page = pages.getPages().get(0);
        long startTime = page.getStartedDateTime().getTime();

        //Traverse entries and determine the latest request end time
        long loadTime = 0;            
        HarEntries entries = log.getEntries();
        List<HarEntry> entryList = entries.getEntries();
        for (HarEntry entry : entryList)
        {
            long entryLoadTime = entry.getStartedDateTime().getTime() + entry.getTime();
            if(entryLoadTime > loadTime){
                loadTime = entryLoadTime;
            }
        }

        pageLoadTime = loadTime - startTime;
    }
    catch (JsonParseException e)
    {
      e.printStackTrace();
      System.out.println("Parsing error during test");
    }
    catch (IOException e)
    {
      e.printStackTrace();
      System.out.println("IO exception during test");
    }

    return pageLoadTime;
}
Darren Cole
  • 317
  • 3
  • 6
0

Based on input from above

import edu.umass.cs.benchlab.har.*;
import edu.umass.cs.benchlab.har.tools.*;

import java.io.File;
import java.io.*;
import java.util.List;
import org.codehaus.jackson.JsonParseException;

public class ParseHarFile {

     public static void main(String[] args) {
         String fileName = "test.har";
         ReadHarFile(fileName);
    }

    public static void ReadHarFile(String fileName){

         File f = new File(fileName);
         HarFileReader r = new HarFileReader();

         try
         {
             System.out.println("Reading " + fileName);
             HarLog log = r.readHarFile(f);

             // Access all pages elements as an object
              HarPages pages = log.getPages();

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

              System.out.println("page start time: " + startTime);

             // Access all entries elements as an object
             HarEntries entries = log.getEntries();

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

             long loadTime = 0;
             long responseSize=0;


             int entryIndex = 0;
             //Output "response" code of entries.
             for (HarEntry entry : hentry)
             {
                 System.out.println("entry: " + entryIndex);
                 System.out.println("request code: " + entry.getRequest().getMethod()); //Output request type
                 System.out.println("request url: "
                     + entry.getRequest().getUrl()); //Output request Url
                 System.out.println("    start time: " + entry.getStartedDateTime().getTime()); // Output start time
                 System.out.println("    time: " + entry.getTime()); // Output start time
                 System.out.println("response code: "
                     + entry.getResponse().getStatus()); //Output response code
                 responseSize=entry.getResponse().getHeadersSize()+entry.getResponse().getBodySize();


                 System.out.println("response size: "
                     + responseSize); //Output response size

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

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

                 System.out.println();
                 entryIndex++;
             }

             long loadTimeSpan = loadTime - startTime;
             System.out.println("loadTimeSpan: " + loadTimeSpan);

             Double webLoadTime = ((double)loadTimeSpan) / 1000;
             double webLoadTimeInSeconds = Math.round(webLoadTime * 100.0) / 100.0; 
             System.out.println("Web Load Time: " + webLoadTimeInSeconds) ;

         }
         catch (JsonParseException e)
         {
             e.printStackTrace();
             System.out.println("Parsing error during test");
         }
         catch (IOException e)
         {
             e.printStackTrace();
             System.out.println("IO exception during test");
         }
     }
 }
Timir
  • 141
  • 2
  • 8