Actor picture

Measure Downloaded Bytes

jaroslavhejlek/measure-downloaded-bytes

Example of how to measure downloaded data from network requests made by a webpage.

No credit card required

Author's avatarJaroslav Hejlek
  • Modified
  • Users6
  • Runs30
Actor picture

Measure Downloaded Bytes

Based on the apify/actor-node-chrome:v0.21.10 Docker image (see docs).

const Apify = require('apify');
const prettyBytes = require('pretty-bytes');

async function saveScreen(page, key = 'debug-screen.png') {
    const screenshotBuffer = await page.screenshot({ fullPage: true });
    await Apify.setValue(key, screenshotBuffer, { contentType: 'image/png' });
};

Apify.main(async() => {
    try {
        const input = await Apify.getValue('INPUT');
        const browser = await Apify.launchPuppeteer({
            // useApifyProxy: true,
            // apifyProxyGroups: ['SHADER'],
            headless: true,
        });
        const page = await browser.newPage();
        if (input.abortRequests) {
            await page.setRequestInterception(true);
            page.on('request', (request) => {
                const url = request.url();
                const filters = [
                    'livefyre',
                    'moatad',
                    'analytics',
                    'controltag',
                    'chartbeat',
                ];
                const shouldAbort = filters.some((urlPart) => url.includes(urlPart));
                if (shouldAbort) request.abort();
                else request.continue();
            });
        }
        const responses = [];
        page.on('response', async(response) => {
            const url = response.url();
            let size = 0;
            try {
                const buffer = await response.buffer();
                size = buffer.byteLength;
            } catch (e) {
                // Ignore error here, response can be empty
            }
            responses.push({
                url: url,
                type: response.request().resourceType(),
                size,
            });
        });
        const startedAt = Date.now();
        await page.goto(input.url, { timeout: 5 * 60 * 1000, waitUntil: 'networkidle2' });
        await saveScreen(page);

        let totalSize = 0;
        const byResourceType = {};
        responses.forEach(({ type, size }) => {
            if (!byResourceType[type]) byResourceType[type] = { count: 0, size: 0 };
            byResourceType[type].count++;
            byResourceType[type].size += size;
            totalSize += size;
        });

        console.log('Page finished loading after', Date.now() - startedAt, 'ms');
        console.log(`Responses: ${responses.length} (${prettyBytes(totalSize)})`);
        console.log('----------------');
        console.log('By resource type');
        Object.keys(byResourceType).forEach(type => {
            const data = byResourceType[type];
            console.log(`${type}: ${data.count} (${prettyBytes(data.size)})`);
        });

        await page.close();
        await browser.close();
    } catch (error) {
        console.error(error.message);
    }
});