Skip to content

Commit 0cf1ae2

Browse files
committed
side-by-side-pageload.js example
1 parent 16631b2 commit 0cf1ae2

File tree

3 files changed

+266
-18
lines changed

3 files changed

+266
-18
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@
2525
"request-promise": "^4.2.2",
2626
"request-promise-native": "^1.0.5",
2727
"sharp": "^0.20.1",
28-
"ws": "^5.1.1"
28+
"yargs": "^11.0.0"
2929
}
3030
}

side-by-side-pageload.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/**
2+
* Copyright 2018 Google Inc. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* @author ebidel@ (Eric Bidelman)
17+
*/
18+
19+
/**
20+
* Launches one or more URLs in different browser windows to visually compare
21+
* the page loads side-by-side. Options to center the windows on screen,
22+
* emulate mobile devices, and toggle CPU/Network throttling.
23+
*
24+
* Usage:
25+
*
26+
* node side-by-side-pageload.js -h
27+
*/
28+
29+
const fs = require('fs');
30+
const puppeteer = require('puppeteer');
31+
const devices = require('puppeteer/DeviceDescriptors');
32+
const nexus5X = devices['Nexus 5X'];
33+
34+
const argv = require('yargs')
35+
.options({
36+
'mobile': {
37+
alias: 'm',
38+
describe: 'Emulate a mobile viewport',
39+
default: true,
40+
},
41+
'throttle': {
42+
describe: 'Throttles CPU by 4x and network to "Slow 3G"',
43+
default: true,
44+
},
45+
'center': {
46+
alias: 'c',
47+
describe: 'Centers the the windows on screen',
48+
default: true,
49+
},
50+
'url': {
51+
alias: 'u',
52+
describe: 'URL to load',
53+
demandOption: true,
54+
},
55+
'space': {
56+
alias: 's',
57+
describe: 'Spaces between windows (when emulating mobile)',
58+
default: 20,
59+
},
60+
'timeout': {
61+
alias: 't',
62+
describe: 'Timeout after page finish loading before closing the browers',
63+
default: 3000,
64+
},
65+
})
66+
.array('url')
67+
.help()
68+
.example('$0 --url https://devwebfeed.appspot.com https://devwebfeed.appspot.com/ssr')
69+
.example('$0 --no-throttle --no-mobile -u https://devwebfeed.appspot.com https://devwebfeed.appspot.com/ssr')
70+
.example('$0 -u https://www.bing.com/ https://www.google.com/ https://www.yahoo.com/')
71+
.wrap(null)
72+
.argv;
73+
74+
const urls = argv.url.length ? argv.url : [
75+
'https://devwebfeed.appspot.com/',
76+
'https://devwebfeed.appspot.com/ssr',
77+
];
78+
79+
const CENTER_WINDOWS_ON_SCREEN = argv.center;
80+
const SPACE_BETWEEN_WINDOWS = argv.space;
81+
const MOBILE = argv.mobile;
82+
const THROTTLE = argv.throttle;
83+
const TIMEOUT_AFTER_LOAD = argv.timeout;
84+
const DEFAULT_VIEWPORT = {width: 1000, height: 800, deviceScaleFactor: 2};
85+
86+
const sleep = (timeout) => new Promise(r => setTimeout(r, timeout));
87+
88+
async function launch(position, screen) {
89+
const totalSpacerWidthAddition = SPACE_BETWEEN_WINDOWS * (urls.length - 1);
90+
const totalWidthOfWindows = urls.length * DEFAULT_VIEWPORT.width;
91+
const totalWidthOfWindowsWithSpacers = totalWidthOfWindows + totalSpacerWidthAddition;
92+
93+
const centerScreenX = screen.width / 2;
94+
const centerScreenY = screen.height / 2;
95+
96+
let dx = DEFAULT_VIEWPORT.width * position;
97+
dx += SPACE_BETWEEN_WINDOWS * position;
98+
99+
const x = Math.floor(centerScreenX - (totalWidthOfWindowsWithSpacers / 2) + dx);
100+
const y = Math.floor(centerScreenY - (DEFAULT_VIEWPORT.height / 2));
101+
102+
const browser = await puppeteer.launch({
103+
headless: false,
104+
args: [
105+
`--window-size=${DEFAULT_VIEWPORT.width},${DEFAULT_VIEWPORT.height}`,
106+
CENTER_WINDOWS_ON_SCREEN ? `--window-position=${x},${y}` : `--window-position=${dx},0`,
107+
],
108+
});
109+
110+
const page = await browser.newPage();
111+
if (MOBILE) {
112+
await page.emulate(nexus5X);
113+
} else {
114+
await page.setViewport(DEFAULT_VIEWPORT);
115+
}
116+
117+
if (THROTTLE) {
118+
const client = await page.target().createCDPSession();
119+
// Emulate "Slow 3G" according to WebPageTest.
120+
await client.send('Network.emulateNetworkConditions', {
121+
offline: false,
122+
latency: 400,
123+
downloadThroughput: Math.floor(400 * 1024 / 8), // 400 Kbps
124+
uploadThroughput: Math.floor(400 * 1024 / 8) // 400 Kbps
125+
});
126+
await client.send('Emulation.setCPUThrottlingRate', {rate: 4});
127+
}
128+
129+
return page;
130+
}
131+
132+
(async () => {
133+
134+
const browser = await puppeteer.launch();
135+
const page = await browser.newPage();
136+
137+
const screen = await page.evaluate(() => {
138+
return {width: window.screen.availWidth, height: window.screen.availHeight};
139+
});
140+
await browser.close();
141+
142+
// Take up full desktop space or emulate mobile.
143+
DEFAULT_VIEWPORT.width = MOBILE ? nexus5X.viewport.width : Math.floor(screen.width / urls.length);
144+
DEFAULT_VIEWPORT.height = MOBILE ? nexus5X.viewport.height : screen.height;
145+
146+
const pages = await Promise.all(urls.map((url, i) => launch(i, screen)));
147+
148+
const start = Date.now();
149+
150+
const waitForPage = async pos => {
151+
const page = pages[pos];
152+
const url = urls[pos];
153+
return page.goto(url, {waitUntil: 'networkidle2'})
154+
.then(() => Date.now());
155+
};
156+
157+
const stopTimes = await Promise.all(urls.map((url, i) => waitForPage(i)));
158+
stopTimes.forEach((stopTime, i) => console.log(`Page ${i} took ${stopTime - start} ms to reach network idel`));
159+
160+
await sleep(TIMEOUT_AFTER_LOAD);
161+
162+
await Promise.all(pages.map(page => page.browser().close()));
163+
164+
})();

0 commit comments

Comments
 (0)