Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: request block stylesheets and images on redirect pass #2168

Merged
merged 4 commits into from
May 9, 2017

Conversation

patrickhulce
Copy link
Collaborator

shaves off ~10s on certain sites like theverge.com

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice cleanup on the test. :)
oh and fixing the fact that addBlockedUrls hasn't worked for a few months now. :)

we're not explicitly clearing our blocked urls at the end of a pass, but instead relying on a subsequent pass doing Network.setBlockedUrls({ urls: [] }) to clear things out. Can you add a comment on the blockUrlPatterns method that mentions this trick?
(it seems fine but it gave me a doubletake)

@@ -27,6 +27,18 @@ module.exports = {
{
"passName": "redirectPass",
"useThrottling": false,
// Speed up the redirect pass by blocking stylesheets, fonts, and images
"blockedUrlPatterns": [
"*.css",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting nit: this is pretty low signal info, compared to the rest of config.
can these all share a line?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, done

@@ -45,7 +45,8 @@ let GathererResults; // eslint-disable-line no-unused-vars
* 2. For each pass in the config:
* A. GatherRunner.beforePass()
* i. navigate to about:blank
* ii. all gatherers' beforePass()
* ii. Enable network request blocking for specified patterns
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set patterns for network request blocking

and you can remove "vii. blockUrlPatterns" from above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

blockUrlPatterns(urlPatterns) {
const promiseArr = urlPatterns.map(url => this.sendCommand('Network.addBlockedURL', {url}));
return Promise.all(promiseArr);
blockUrlPatterns(urls) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jsdoc?

{!Array<string>} yeah?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, done

@paulirish paulirish mentioned this pull request May 6, 2017
40 tasks
@patrickhulce
Copy link
Collaborator Author

Can you add a comment on the blockUrlPatterns method that mentions this trick?

Yeah good call done, blocking will cease when we disconnect, right?

Copy link
Member

@paulirish paulirish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one this is done we'll be good

* @return {!Promise}
*/
blockUrlPatterns(urls) {
return this.sendCommand('Network.setBlockedURLs', {urls});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfortunately this command was renamed/added recently..

commit: https://chromium.googlesource.com/chromium/src/+/01c043f5f744262981becd3d45a79981ad3f6b67

m58 (base rev 454471 ) which shipped to stable 2 weeks ago doesn't have this method. It has the add/remove pair instead.

IMO this is optional, and our other use of requestblocking is unused so i think we can ignore the failure. let's catch and exclude errors?

doublecheck this works with a stable m58 build

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's going to be our policy going forward about handling stable chrome and protocol changes? it seems like it's mostly taken a backseat and we emphasize canary, should we add a stable config to travis if we want to support it (#1480)?

confirmed working now (with an error log) in 58

Copy link
Member

@brendankenny brendankenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice clean perf improvement. LGTM with comment location shuffling

return Promise.all(promiseArr);
/**
* This method sets the URL patterns to be blocked and is called at the beginning of each pass.
* No "clearing" is done at the end of the pass since the next pass will set to [] if necessary.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since some future gatherers or other consumers of lighthouse (e.g. performanceExperiment) may want to use this method, probably makes more sense to move the bulk of this comment into beforePass where it's used like this

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

/**
* This method sets the URL patterns to be blocked and is called at the beginning of each pass.
* No "clearing" is done at the end of the pass since the next pass will set to [] if necessary.
* @param {!Array<string>} urls
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe worth adding param doc similar to what the protocol docs has? ("URL patterns to block. Wildcards ('*') are allowed.")

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -171,9 +170,12 @@ class GatherRunner {
* @return {!Promise}
*/
static beforePass(options, gathererResults) {
const blockedUrls = (options.config.blockedUrlPatterns || [])
.concat(options.flags.blockedUrlPatterns || []);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do unions of url patterns work? Last one wins? (just curious)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aside: we really need to get the overloaded naming of options under control here :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do unions of url patterns work? Last one wins?

oh, is ! not supported? I guess in that case it doesn't matter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

! isnt supported, correct.

@@ -27,6 +27,8 @@ module.exports = {
{
"passName": "redirectPass",
"useThrottling": false,
// Speed up the redirect pass by blocking stylesheets, fonts, and images
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love having this in the default config as an example for custom configs

@@ -27,6 +27,8 @@ module.exports = {
{
"passName": "redirectPass",
"useThrottling": false,
// Speed up the redirect pass by blocking stylesheets, fonts, and images
"blockedUrlPatterns": ["*.css", "*.jpg", "*.jpeg", "*.png", "*.gif", "*.svg", "*.ttf", "*.woff", "*.woff2"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure about this one, but does it make sense to have these apply across beforePass, pass, and afterPass? Maybe it would make more sense/be less surprising to have them blocked only during pass, analogous to recordTrace, useThrottling, etc cc/ @paulirish

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah few random thoughts here

  1. we don't have any gatherers that load new content that wasn't already requested by the page
  2. we should probably discourage that behavior as something outside of Lighthouse realm anyway, and suggest requesting on the node side if a third party integration wants to do that rather than an evaluateAsync(fetch('my-url'))
  3. since afterPass doesn't freeze the page or anything and we're not guaranteed to be done at the 25s timeout it felt weird to unblock these urls while the page could feasibly still be requesting or retrying them

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't have any gatherers that load new content that wasn't already requested by the page

that's actually why I brought it up, so it wouldn't surprise us when someone does write a gatherer that tries it :)

we should probably discourage that behavior as something outside of Lighthouse realm anyway, and suggest requesting on the node side if a third party integration wants to do that rather than an evaluateAsync(fetch('my-url'))

but that's definitely something we rely on when we need to get around authentication or whatever. As an easy workaround to some of those issues, fetching in the context of the page can't be beat.

since afterPass doesn't freeze the page or anything and we're not guaranteed to be done at the 25s timeout it felt weird to unblock these urls while the page could feasibly still be requesting or retrying them

yeah, good point, and this is what really separates it from useThrottling. While matching their behavior makes some sense from a user-surprise perspective, disabling useThrottling in afterPass means the run goes faster due to potential work going faster, while disabling url blocking potentially means the run going slower due to (potentially) making work.

My real hesitation is magic while having no data about actual downsides. This is why we need users making custom gatherers :)

In the meantime, I suspect we'll have to revisit scheduling of all of this for #1826 anyways, so I'm good with this.

@paulirish paulirish merged commit 4c515cf into master May 9, 2017
@paulirish paulirish deleted the faster_redirect_pass branch May 9, 2017 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants