javascript - How I can calculate page fully load time with Pupppeteer? - Stack Overflow

I'm trying to get the page fully load time in seconds with puppeteer in Node, for this I do some r

I'm trying to get the page fully load time in seconds with puppeteer in Node, for this I do some research on the API and other questions and create the following code:

/* First Configuration */
    puppeteer.launch({
            defaultViewport: { width: 1600, height: 800 }
      }).then(async browser => {
        const page = await browser.newPage();
    await page.setCacheEnabled(false);
        await page.goto('', {waitUntil: 'networkidle0'});

        /* Get Page Metrics */

        const perf = await page.metrics();
        console.log(JSON.stringify(perf));

        /* Get Page Evaluate */

        const timing = await page.evaluate(() => {
            const result = {};
            for (const key of Object.keys(window.performance.timing.__proto__))
                result[key] = window.performance.timing[key];
            return result;
        });
        console.log(JSON.stringify(timing));

        /* Show Results on Browser Close */

        await browser.close().then(() => {

    var fullyLoadEvaluate = (timing.loadEventEnd - timing.navigationStart);
        console.log('Fully Load Time (Page Evaluate): ' + fullyLoadEvaluate);

        var fullyLoadMetrics = (perf.LayoutDuration + perf.RecalcStyleDuration + perf.ScriptDuration + perf.TaskDuration);
        console.log('Fully Load Time (Page Metrics): ' + fullyLoadMetrics);

        /* Send Response to Server */
        res.send('Check The Console');
        });

      });

Basically I use two codes to return metrics, One of them is page.metrics() that return the following data:

{"Timestamp":961736.600171,"Documents":8,"Frames":4,"JSEventListeners":375,"Nodes":8654,"LayoutCount":27,"RecalcStyleCount":31,"LayoutDuration":0.705517,"RecalcStyleDuration":0.144379,"ScriptDuration":0.527385,"TaskDuration":1.812213,"JSHeapUsedSize":11082496,"JSHeapTotalSize":20344832}

And the last one page.evaluate(), return the following:

{"navigationStart":1556722407938,"unloadEventStart":0,"unloadEventEnd":0,"redirectStart":0,"redirectEnd":0,"fetchStart":1556722407938,"domainLookupStart":1556722408247,"domainLookupEnd":1556722408548,"connectStart":1556722408548,"connectEnd":1556722408737,"secureConnectionStart":1556722408574,"requestStart":1556722408738,"responseStart":1556722408940,"responseEnd":1556722409087,"domLoading":1556722408957,"domInteractive":1556722409995,"domContentLoadedEventStart":1556722409995,"domContentLoadedEventEnd":1556722410190,"domComplete":1556722412584,"loadEventStart":1556722412584,"loadEventEnd":1556722412589,"toJSON":{}}

In my example I'm testing the site . Like webpagetest and getmetrix, I'm trying to get Page Fully Load Time.

I know this kind of value is inconsistent, but I wonder if the values ​​I'm calculating are right, and which of the two results seems to be more correct ? Fully Load Time (Page Evaluate) or Fully Load Time (Page Metrics) ?

I'm trying to get the page fully load time in seconds with puppeteer in Node, for this I do some research on the API and other questions and create the following code:

/* First Configuration */
    puppeteer.launch({
            defaultViewport: { width: 1600, height: 800 }
      }).then(async browser => {
        const page = await browser.newPage();
    await page.setCacheEnabled(false);
        await page.goto('https://stackoverflow.', {waitUntil: 'networkidle0'});

        /* Get Page Metrics */

        const perf = await page.metrics();
        console.log(JSON.stringify(perf));

        /* Get Page Evaluate */

        const timing = await page.evaluate(() => {
            const result = {};
            for (const key of Object.keys(window.performance.timing.__proto__))
                result[key] = window.performance.timing[key];
            return result;
        });
        console.log(JSON.stringify(timing));

        /* Show Results on Browser Close */

        await browser.close().then(() => {

    var fullyLoadEvaluate = (timing.loadEventEnd - timing.navigationStart);
        console.log('Fully Load Time (Page Evaluate): ' + fullyLoadEvaluate);

        var fullyLoadMetrics = (perf.LayoutDuration + perf.RecalcStyleDuration + perf.ScriptDuration + perf.TaskDuration);
        console.log('Fully Load Time (Page Metrics): ' + fullyLoadMetrics);

        /* Send Response to Server */
        res.send('Check The Console');
        });

      });

Basically I use two codes to return metrics, One of them is page.metrics() that return the following data:

{"Timestamp":961736.600171,"Documents":8,"Frames":4,"JSEventListeners":375,"Nodes":8654,"LayoutCount":27,"RecalcStyleCount":31,"LayoutDuration":0.705517,"RecalcStyleDuration":0.144379,"ScriptDuration":0.527385,"TaskDuration":1.812213,"JSHeapUsedSize":11082496,"JSHeapTotalSize":20344832}

And the last one page.evaluate(), return the following:

{"navigationStart":1556722407938,"unloadEventStart":0,"unloadEventEnd":0,"redirectStart":0,"redirectEnd":0,"fetchStart":1556722407938,"domainLookupStart":1556722408247,"domainLookupEnd":1556722408548,"connectStart":1556722408548,"connectEnd":1556722408737,"secureConnectionStart":1556722408574,"requestStart":1556722408738,"responseStart":1556722408940,"responseEnd":1556722409087,"domLoading":1556722408957,"domInteractive":1556722409995,"domContentLoadedEventStart":1556722409995,"domContentLoadedEventEnd":1556722410190,"domComplete":1556722412584,"loadEventStart":1556722412584,"loadEventEnd":1556722412589,"toJSON":{}}

In my example I'm testing the site https://stackoverflow.. Like webpagetest and getmetrix., I'm trying to get Page Fully Load Time.

I know this kind of value is inconsistent, but I wonder if the values ​​I'm calculating are right, and which of the two results seems to be more correct ? Fully Load Time (Page Evaluate) or Fully Load Time (Page Metrics) ?

Share Improve this question edited Dec 19, 2022 at 1:32 ggorlen 58k8 gold badges114 silver badges157 bronze badges asked May 1, 2019 at 15:02 Sudo SurSudo Sur 6117 silver badges22 bronze badges 4
  • 3 What are you considering a "Page Load"? Time until ''Load" even is fired? Time until "DOMContentLoaded" event is fired? Time until all resources (like images) inside the document are loaded? Time until all resources are loaded? Time until there are no more network requests? – Thomas Dondorf Commented May 1, 2019 at 15:10
  • @ThomasDondorf I think that WebpageTest and GetMetrix calculate the Time until all resources are loaded and no more network requests include css, javascript, images, texts and so on... – Sudo Sur Commented May 1, 2019 at 15:27
  • Might be a good idea to use the page.goto('..', { waitUntil: 'networkidle0' }) approach then. I added an answer for more details :) – Thomas Dondorf Commented May 1, 2019 at 16:24
  • See also Using page.getMetrics() to get page load time in puppeteer – ggorlen Commented Dec 19, 2022 at 1:33
Add a ment  | 

1 Answer 1

Reset to default 10

You can use page.metrics() to pare two points in time (e.g. before and after page.goto). The page.evaluate approach to read the data from the performance API is also a good alternative. As I already pointed out in the ment, it is not defined what should be considered a "full page load". Both approaches are valid.

It's even more plex

There are a number of thing which people might consider a page to be loaded:

  • DOMContentLoaded event fired
  • Load event fired
  • Time it takes from navigation start until all resources embedded in the document (like images are loaded)
  • Time it takes from navigation start until all resources are loaded
  • Time until there are not more ongoing network requests.
  • ...

You also have to consider whether whether you want network related phases (like DNS) to be part of the measurement. Here is an example request (generated with the Chrome DevTools Network tab) showing how plex a single request might be:

There is also a document explaining each of these phases.

Simple approach

The simplest way to measure the load time would just to start measuring when the navigaiton starts and stop measuring after the page is loaded. This could be done like this:

const t1 = Date.now();
await page.goto('https://example.');
const diff1 = Date.now() - t1;
console.log(`Time: ${diff1}ms`);

Note that there are also other APIs (page.metrics, process.hrtime, perf_hooks) to get more precise timestamps.

You can also pass options to the page.goto function to change the resolving of the promise to something like this (quoted from the docs):

Consider navigation to be finished when there are no more than 0 network connections for at least 500ms

For that, you would have to use the setting networkidle0:

await page.goto('https://example.', { waitUntil: 'networkidle0' });

There are also other events in the docs linked above you could use.

More plex: Use the Performance API

To get more precise results, you can use the Performance API as you already did in your code. Instead of going through the prototype of window.performance you can also use the functions performance.getEntries() or performance.toJSON() like this:

const perfData = await page.evaluate(() =>
    JSON.stringify(performance.toJSON(), null, 2)
);

That way, you get data that looks like this:

{
  "timeOrigin": 1556727036740.113,
  "timing": {
    "navigationStart": 1556727036740,
    "unloadEventStart": 0,
    "unloadEventEnd": 0,
    "redirectStart": 0,
    "redirectEnd": 0,
    "fetchStart": 1556727037227,
    "domainLookupStart": 1556727037230,
    "domainLookupEnd": 1556727037280,
    "connectStart": 1556727037280,
    "connectEnd": 1556727037348,
    "secureConnectionStart": 1556727037295,
    "requestStart": 1556727037349,
    "responseStart": 1556727037548,
    "responseEnd": 1556727037805,
    "domLoading": 1556727037566,
    "domInteractive": 1556727038555,
    "domContentLoadedEventStart": 1556727038555,
    "domContentLoadedEventEnd": 1556727038570,
    "domComplete": 1556727039073,
    "loadEventStart": 1556727039073,
    "loadEventEnd": 1556727039085
  },
  "navigation": {
    "type": 0,
    "redirectCount": 0
  }
}

So if you want to know how long it took from navigationStart to loadEventStart you subtract one value from the other one (e.g. 1556727039073 - 1556727036740 = 2333 ms).

So which one to take?

This is up to your decision. In general, it is a good idea to use the Load event as a starting point. Waiting until all requests are finished might actually never happen because there are constantly resources being loaded in the background. Using networkidle2 as waitUntil option might be an alternative in case you don't want to use the load event.

In the end, however, it es down to your use case which metric to use.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744349383a4569882.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信