如何从 HAR 文件中获取总网页响应时间?

Posted

技术标签:

【中文标题】如何从 HAR 文件中获取总网页响应时间?【英文标题】:How to get total web page response time from a HAR file? 【发布时间】:2015-08-25 02:10:56 【问题描述】:

在下图中,我想要网页的总响应时间。我似乎无法在文件sample HAR file 中找到它,即在这种情况下为 38.79s。有谁知道如何获得这个?

我将使用 Selenium 以及 Firebug 和 NetExport 来导出 HAR 文件,但现在我正在尝试手动执行此操作。添加单个响应不会给出正确的数字。

在某个时候,我想要一个 Java 程序来查找并提取总响应时间。

【问题讨论】:

示例 HAR 文件的链接实际上是指屏幕截图,而不是 HAR 文件。 @SebastianZartner 抱歉,我更新了链接。 您仍然需要授予该文件的公共访问权限。 @SebastianZartner 好的,它现在应该已经准备好了。谢谢 【参考方案1】:

根据上面的输入

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");
         
     
 

【讨论】:

【参考方案2】:

这是一个返回页面加载时间的 Java 函数。此外,它还允许您解析缺少元素或其他违反规范的损坏的 HAR 文件。更多信息。在 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;

【讨论】:

【参考方案3】:

根据@Sebastian Zartner 的回答和Google sample,以下是Java 尝试:

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");
         
     

【讨论】:

要获得完整的答案,您还应该发布HarFileReader 课程。 HarFileReadder 是从 jar 中导入的:sourceforge【参考方案4】:

总加载时间不是通过汇总所有请求时间而是通过最近的请求结束时间来计算的。从图形上讲,它是在最右边结束的请求栏的右端。在您的示例屏幕截图中,它是最后一个、倒数第三个或倒数第四个请求。

请求结束时间由请求的startedDateTime 属性指示的请求开始时间加上响应所需的时间跨度计算得出,响应时间跨度可通过每个请求的time 属性获得。 要获取最大请求结束时间,您需要遍历所有请求并比较每个请求的结束时间。见以下代码:

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;

执行此代码,变量loadTimeSpan 将包含所需的时间跨度(以毫秒为单位)。

重要提示:

这样计算的时间跨度可能仍然与 Firebug 或在线 HAR Viewer 显示的时间不同,因为它们根据两个请求之间经过的时间将请求分为不同的阶段。然后他们计算每个阶段的第一个请求到最后一个请求的时间跨度,并在最后总结这些时间跨度。

【讨论】:

类似的逻辑能不能用在java中,还是直接用java来执行? 上面的代码是 javascript,因为你没有提到任何关于 Java 的内容。在 Java 中,代码看起来确实不同,但基本逻辑(循环所有请求并获取最新的请求结束时间)是相同的。 刚刚添加了我最终会做这个java的信息。 条目是否应该是 har 文件中的条目? 如果你说的是forEach()调用的回调函数中的entry参数,那么是的。在这种情况下,请参阅documentation for forEach()

以上是关于如何从 HAR 文件中获取总网页响应时间?的主要内容,如果未能解决你的问题,请参考以下文章

HAR 响应中没有标头

如何将请求响应对象序列化为 HAR

curl获取网站的响应时间

如何解析 HAR 文件以提取文本内容?

如何使用 capybara-webkit 获取响应头和时间

如何从 HTML 文件生成 HAR 文件?