Conversation
3682c73 to
d6e9c49
Compare
kristoferbaxter
left a comment
There was a problem hiding this comment.
Lots of great work here, thank you!
Left you a few nits and other items for the future.
| const url = process.argv[2]; | ||
|
|
||
| (async () => { | ||
| const result = await new PageExperienceGuide().analyze(url); |
There was a problem hiding this comment.
Can't wait for top level await!
| const parseFontfaces = require('./helpers/parseFontface'); | ||
|
|
||
| // Pixel 5 XL | ||
| const DEFAULT_VIEWPORT = { |
There was a problem hiding this comment.
Nit: Is there a URL you could link to that lists dimensions for popular devices?
There was a problem hiding this comment.
Additionally, do we need to provide a dpi value to puppeteer?
There was a problem hiding this comment.
Afaik no DPI value needed as the default is 1. Not sure why a link would be helpful here.
| * Renders a page in Puppeteer and collects all data required for the page experience recommendations. | ||
| */ | ||
| class PageAnalyzer { | ||
| constructor(config = {}) { |
There was a problem hiding this comment.
Nit: Does the config parameter need types?
There was a problem hiding this comment.
Added type info
| return await this.gatherPageData(page, remoteStyles); | ||
| } | ||
|
|
||
| async gatherPageData(page, remoteStyles) { |
There was a problem hiding this comment.
Nit: Do these params and the return need to be typed?
| * @return {Array<string>} a list of URLs | ||
| */ | ||
| const collectFontPreloads = () => { | ||
| return Array.from(document.querySelectorAll('link[rel=preload][as=font]')).map( |
There was a problem hiding this comment.
Is there a separate check for invalid preloads somewhere? Perhaps a preload of a value used in a font-face declaration but not preloaded as a font?
There was a problem hiding this comment.
Not yet, created an issue.
| !request.url().startsWith('https://cdn.ampproject.org') | ||
| ) { | ||
| // Only donwload AMP runtime scripts as they're need for layouting the page | ||
| // Once self-hosting is a thing we'll have to change this |
There was a problem hiding this comment.
Is there a flag for when the CLI tools know self-hosting is valid?
There was a problem hiding this comment.
Not yet, will add later
| * @private | ||
| */ | ||
| async loadChecks() { | ||
| const jsFileExtension = '.js'; |
There was a problem hiding this comment.
Does this work with the recently launched module mode?
There was a problem hiding this comment.
This loads files from the filesystem which we control.
| } | ||
| `; | ||
| parseFontface(styles, 'http://example.com'); | ||
| }); |
There was a problem hiding this comment.
For completeness should there be a check with subset fonts?
| const fontfaceSrcParser = require('css-font-face-src'); | ||
|
|
||
| /** | ||
| * Extracts the best fontface URL for preloading (woff2 > woff > ?). |
There was a problem hiding this comment.
Smart here: I was naively thinking the result would always be woff2 but this code correctly validates if there are other formats available to use.
| @@ -0,0 +1,39 @@ | |||
| /** | |||
| * Copyright 2019 The AMP HTML Authors. All Rights Reserved. | |||
There was a problem hiding this comment.
removed the file as no longer needed
* Fixed JSDocs * More tests
d6e9c49 to
6ba0f47
Compare
packages/page-experience/README.md
Outdated
| const pageExperienceGuide = new PageExperienceGuide(); | ||
| const result = pageExperienceGuide.analyze('https://amp.dev'); | ||
| console.log('result') | ||
| }) |
There was a problem hiding this comment.
is there a reason this is wrapped in () but not invoked?
There was a problem hiding this comment.
not at all...fixed
| */ | ||
| async execute(url) { | ||
| if (!this.started) { | ||
| throw new Error('Puppeteer not running, please call `start` first.'); |
There was a problem hiding this comment.
is there any reason you don't just call start?
There was a problem hiding this comment.
You're right, but somehow I preferred the more explicit symmetry of calling start and shutdown. It's an internal API though so I don't really care...
| ) { | ||
| // Only donwload AMP runtime scripts as they're need for layouting the page | ||
| // Once self-hosting is a thing we'll have to change this | ||
| // TODO: investigate whether we could cache these locally |
There was a problem hiding this comment.
You could catch them https://theheadless.dev/posts/request-interception/, and reply with local filesystem?
There was a problem hiding this comment.
that was my idea as well
| return request.continue(); | ||
| }); | ||
|
|
||
| // Collect external stylesheets from requests as we can't read them otherwise due to CORS |
There was a problem hiding this comment.
Is there a way to miss some stuff as a result of this? Any reason not to just disable CORS in rendering options?
There was a problem hiding this comment.
That didn't work for me.
| } | ||
| if (!pageData.fontPreloads.includes(fontface.mainSrc)) { | ||
| if (fontface.mainSrc.startsWith('https://fonts.gstatic.com')) { | ||
| result.warn({ |
There was a problem hiding this comment.
would it make sense to extract these text blobs into an external file?
|
|
||
| if (!fontface.fontDisplay) { | ||
| result.warn({ | ||
| title: 'Improve LCP using `font-display: optional`', |
There was a problem hiding this comment.
Would it make sense to extract the warnings into an external file?
There was a problem hiding this comment.
For translation?
|
comments and nits, nothing blocking a LGTM though |
ae1425c to
4a34bb5
Compare
|
Thanks for the reviews! |
No description provided.