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

new_audit(font-size-audit): legible font sizes audit #3533

Merged
merged 71 commits into from
Dec 14, 2017
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
4cc44c1
Font Size audit - WIP
kdzwinel Sep 13, 2017
ad797fc
Calculate percentage of ilegible text on page. Show failing elements …
kdzwinel Sep 16, 2017
b2aa5c8
Getting font-size information togheter with associated CSS rules - WIP
kdzwinel Sep 17, 2017
64360dc
Matched rules - WIP
kdzwinel Sep 18, 2017
3f2effc
Extracting style info - WIP
kdzwinel Sep 20, 2017
fdf6473
Expose effective rule
kdzwinel Sep 26, 2017
35599d3
Show what percentage of text each rule affected. Show table with fail…
kdzwinel Sep 28, 2017
483a5c2
Work on inline styles, clean up jsdoc
kdzwinel Oct 2, 2017
9a10a10
Handle inline styels, attribute styles and user agent styles.
kdzwinel Oct 3, 2017
4b0863c
Expose stylesheet URL, line number and column.
kdzwinel Oct 4, 2017
005d308
Update output table according to the latst decisions.
kdzwinel Oct 10, 2017
a4ec14e
Changes to the result table. Clean up.
kdzwinel Oct 11, 2017
7298ae6
Gatherer test.
kdzwinel Oct 11, 2017
acb9aa8
Smoke tests. Fixing edgecase when size is inherited from attribute st…
kdzwinel Oct 11, 2017
a61106e
Add unit tests.
kdzwinel Oct 11, 2017
eaf454b
Remove info about color prop.
kdzwinel Oct 11, 2017
6d1b518
Remove debugMessage from passing test expectations as it doesn't exist.
kdzwinel Oct 11, 2017
e07a3f8
Replace URL with parseURL
kdzwinel Oct 12, 2017
242024d
Make linter happy.
kdzwinel Oct 12, 2017
3c66033
Check number of failing items in the smoke test.
kdzwinel Oct 15, 2017
99d89ba
getOrigin -> findStyleRuleSource
kdzwinel Oct 15, 2017
018e2bf
Collect stylesheet metadata in font-size gatherer. Get rid of separat…
kdzwinel Oct 15, 2017
4e1f171
Font Size audit - WIP
kdzwinel Sep 13, 2017
dc13c14
Calculate percentage of ilegible text on page. Show failing elements …
kdzwinel Sep 16, 2017
66d4b73
Getting font-size information togheter with associated CSS rules - WIP
kdzwinel Sep 17, 2017
507c78d
Matched rules - WIP
kdzwinel Sep 18, 2017
045fc6a
Extracting style info - WIP
kdzwinel Sep 20, 2017
696f926
Expose effective rule
kdzwinel Sep 26, 2017
1da6cfe
Show what percentage of text each rule affected. Show table with fail…
kdzwinel Sep 28, 2017
9051b92
Work on inline styles, clean up jsdoc
kdzwinel Oct 2, 2017
8596665
Handle inline styels, attribute styles and user agent styles.
kdzwinel Oct 3, 2017
64374a0
Expose stylesheet URL, line number and column.
kdzwinel Oct 4, 2017
312d030
Update output table according to the latst decisions.
kdzwinel Oct 10, 2017
1f7ddbb
Changes to the result table. Clean up.
kdzwinel Oct 11, 2017
1698dd7
Gatherer test.
kdzwinel Oct 11, 2017
97e1096
Smoke tests. Fixing edgecase when size is inherited from attribute st…
kdzwinel Oct 11, 2017
12fecc7
Add unit tests.
kdzwinel Oct 11, 2017
0929685
Remove info about color prop.
kdzwinel Oct 11, 2017
a0a08f7
Remove debugMessage from passing test expectations as it doesn't exist.
kdzwinel Oct 11, 2017
b3a99b9
Replace URL with parseURL
kdzwinel Oct 12, 2017
d45a313
Make linter happy.
kdzwinel Oct 12, 2017
e810e67
Check number of failing items in the smoke test.
kdzwinel Oct 15, 2017
1f4c6d2
getOrigin -> findStyleRuleSource
kdzwinel Oct 15, 2017
682b2c7
Collect stylesheet metadata in font-size gatherer. Get rid of separat…
kdzwinel Oct 15, 2017
e3007b2
Merge branch 'seo-font-size-rdp' of github.com:kdzwinel/lighthouse in…
kdzwinel Oct 29, 2017
26ea8c3
Merge remote-tracking branch 'upstream/master' into seo-font-size-rdp
kdzwinel Oct 29, 2017
a8b14f6
Address some of the review comments
kdzwinel Oct 29, 2017
a7fa017
Add comment, fix jsdoc
kdzwinel Oct 31, 2017
f93ad70
Merge remote-tracking branch 'upstream/master' into seo-font-size-rdp
kdzwinel Nov 19, 2017
9e2346e
Merge remote-tracking branch 'upstream/master' into seo-font-size-rdp
kdzwinel Nov 19, 2017
83f49c7
Limit number of CDP calls to make sure that gatherer doesn't take too…
kdzwinel Nov 25, 2017
94efb06
Reuse method from driver, introduce block list for text nodes
kdzwinel Nov 25, 2017
9e912de
Adjust tests and make linter happy.
kdzwinel Nov 27, 2017
cf25be4
A word.
kdzwinel Nov 27, 2017
ece62d2
Sort nodes by text length before limiting number of visited.
kdzwinel Nov 27, 2017
c017451
Merge branch 'master' into seo-font-size-rdp
kdzwinel Nov 29, 2017
93efc77
Typo
kdzwinel Nov 29, 2017
ae2c823
Typo 🔎
kdzwinel Dec 1, 2017
a6c6ecd
Move analyzedFailingTextLength calculation to the gatherer, rename fa…
kdzwinel Dec 3, 2017
68f896a
Add fileoverview to font-size gatherer
kdzwinel Dec 3, 2017
f2af51f
Merge remote-tracking branch 'upstream/master' into seo-font-size-rdp
kdzwinel Dec 5, 2017
007a458
Remove gatherers from seo config as they are already in default config.
kdzwinel Dec 5, 2017
0d5da12
Prevent gatherer from failing if one of the nodes can't be found
kdzwinel Dec 5, 2017
3b91408
Take into account that each property can be defined multiple times in…
kdzwinel Dec 6, 2017
ede0864
Update copy, remove audits from seo config, show 'dynamic' as source …
kdzwinel Dec 7, 2017
a588863
Fix test
kdzwinel Dec 7, 2017
06443e5
Fix tests
kdzwinel Dec 7, 2017
88091d7
Add simple selector to nodes in the details table.
kdzwinel Dec 8, 2017
5a71a58
Add'l 🚲🏠
kdzwinel Dec 12, 2017
3223cb5
Fix tests.
kdzwinel Dec 12, 2017
0b0cb9a
Additional info in the helpText
kdzwinel Dec 13, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion lighthouse-cli/test/fixtures/seo/seo-tester.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,20 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<meta name="description" content="The premiere destination for testing your SEO audit gathering">
<style>
.small {
font-size: 15px;
}
</style>
</head>
<body>
crawlz me
<!-- regular text -->
<p>123451234512345</p>

<!-- small text -->
<p class='small'> 1 </p>
<small>2</small>
<font size="1">3<b>4</b></font>
<p style='font-size:10px'>5 </p>
</body>
</html>
7 changes: 7 additions & 0 deletions lighthouse-cli/test/smokehouse/seo/expectations.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ module.exports = [
'http-status-code': {
score: true,
},
'font-size': {
rawValue: true,
},
},
},
{
Expand All @@ -49,6 +52,10 @@ module.exports = [
score: false,
displayValue: '403',
},
'font-size': {
rawValue: false,
Copy link
Collaborator

Choose a reason for hiding this comment

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

perhaps we can assert how many elements fail too? details: { items: { length: x }}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here we fail because viewport is not configured (see debugString below), so we don't even go into evaluating text size and details will be empty. Viewport is empty on this page because of the viewport audit that we also want to fail here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah I figured that out last time, but who knows what I was thinking 18 days ago :)

debugString: 'Text is illegible because of a missing viewport config',
},
},
},
];
214 changes: 214 additions & 0 deletions lighthouse-core/audits/seo/font-size.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
/**
* @license Copyright 2017 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
'use strict';

const parseURL = require('url').parse;
const Audit = require('../audit');
const ViewportAudit = require('../viewport');
const CSSStyleDeclaration = require('../../lib/web-inspector').CSSStyleDeclaration;
const MINIMAL_LEGIBLE_FONT_SIZE_PX = 16;
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we have any supporting links to reference for these constants?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is "a good default", but since it depends on the font (and language?) it's a hard value to pinpoint. @rviscomi plans to adjust it once we have more data from running this audit on httparchive and making it available to the test users.

Copy link
Collaborator

Choose a reason for hiding this comment

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

perfect let's just add a link there for now then 👍

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Link is in the meta section of this audit, but it makes sense to put it also here 👍

const MINIMAL_PERCENTAGE_OF_LEGIBLE_TEXT = 75;

/**
* @param {!Array<{textLength:number}>} rules
* @returns number
*/
function getTotalTextLength(rules) {
return rules.reduce((sum, item) => sum + item.textLength, 0);
}

/**
* @param {Array<{cssRule: WebInspector.CSSStyleDeclaration, fontSize: number, textLength: number, node: Node}>} fontSizeArtifact
* @returns {Array<{cssRule: WebInspector.CSSStyleDeclaration, fontSize: number, textLength: number, node: Node}>}
*/
function getFailingRules(fontSizeArtifact) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: maybe rename to reflect that this is coalescing/de-duping rules too? I expected to find a simple filter

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point - I renamed it to getUniqueFailingRules

const failingRules = new Map();

fontSizeArtifact.forEach(({cssRule, fontSize, textLength, node}) => {
if (fontSize >= MINIMAL_LEGIBLE_FONT_SIZE_PX) {
return;
}

const artifactId = getFontArtifactId(cssRule, node);
Copy link
Collaborator

Choose a reason for hiding this comment

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

perhaps something got thrown off between the iterations but it seems like analyzed text nodes aren't always getting de-duped anymore?

image

rule is in CSS
image

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Turned out not to be a regression but rather bug that was there from the beginning. Note that font-size is defined twice in this rule and I've been only examining first occurrence in getEffectiveRule:

font-size-oh-no

This was causing effective rule not to be found and every node listed as a separate entry in the details table.

Fixed 🔧

Copy link
Collaborator

Choose a reason for hiding this comment

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

ah ok, great catch!

const failingRule = failingRules.get(artifactId);

if (!failingRule) {
failingRules.set(artifactId, {
node,
Copy link
Collaborator

Choose a reason for hiding this comment

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

will all duplicate rules correspond to the same node? or is this the optional node that's only set for inline style?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's always set, but it only matters for inline (font-size: 10px) or attribute (<font size='1'>) styles (where we want to show a node in the audit details). For CSS rules we don't show affected nodes so we don't have to collect them.

Copy link
Collaborator

Choose a reason for hiding this comment

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

ah ok and in the inline and attribute cases it's obviously the same node since that's the source, gotcha

cssRule,
fontSize,
textLength,
});
} else {
failingRule.textLength += textLength;
}
});

return failingRules.valuesArray();
}

/**
* @param {Node} node
* @return {{type:string, snippet:string}}
*/
function nodeToTableNode(node) {
const attributesString = node.attributes.map((value, idx) =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

how does this look in practice, are the attributes way too long? is there a subset we might be interested in?

Copy link
Collaborator Author

@kdzwinel kdzwinel Oct 12, 2017

Choose a reason for hiding this comment

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

good point, list of attributes may be long in some cases (e.g. schema.org metadata). However, limiting number of attributes shown to e.g. class and id, may be IMO confusing to the user as our representation of the node won't match the original one. This is especially problematic as ATM users have to find these nodes manually in their code/DOM (we don't link to the Element's panel from the report). If we want to limit number of attributes shown, we should at least expose node's xpath (just like a11y tests do) to make sure it is findable:
screen shot 2017-10-12 at 23 25 06

Copy link
Collaborator

Choose a reason for hiding this comment

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

hm yeah I agree, I'm on board with the path to element on hover either way

(idx % 2 === 0) ? ` ${value}` : `="${value}"`
).join('');

return {
type: 'node',
snippet: `<${node.localName}${attributesString}>`,
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we add a selector here so they title won't be undefined or do we not really have access to it at this point?

image

Copy link
Collaborator Author

@kdzwinel kdzwinel Dec 8, 2017

Choose a reason for hiding this comment

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

Getting a nice looking unique selector is quite complicated and since we don't have real DOM nodes here, but rather devtools protocol nodes, it'd be tricky to reuse Axe's getSelector. I've put together a simpler alternative that would work here, but it doesn't guarantee uniques. WDYT?

BTW I realized that two of my audits that already landed: hreflang and is-crawlable, both suffer from the same issue (selector is not provided). For both of those however I don't have access to the parent nodes making it impossible to produce an useful selector. Should I just pass an empty string there?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm, yeah maybe not worry about it just yet then.

Just use the ID/class of the immediate node if we have it, add a TODO, and we'll file an issue linking off to that gist to make better selectors for these SEO audits then

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, PTAL: 88091d7 . Should I file the issue for that TODO?

Copy link
Collaborator

Choose a reason for hiding this comment

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

looks good! and yeah that'd be great :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

#4015 👍

};
}

/**
* @param {Array<{header:{styleSheetId:string, sourceURL:string}}>} stylesheets
* @param {string} baseURL
* @param {WebInspector.CSSStyleDeclaration} styleDeclaration
* @param {Node} node
* @returns {{source:!string, selector:string}}
*/
function getOrigin(stylesheets, baseURL, styleDeclaration, node) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

origin is a pretty overloaded term on the web, how about "findStyleRuleSource" or something?

if (
!styleDeclaration ||
styleDeclaration.type === CSSStyleDeclaration.Type.Attributes ||
styleDeclaration.type === CSSStyleDeclaration.Type.Inline
) {
return {
source: baseURL,
selector: nodeToTableNode(node),
};
}

if (styleDeclaration.parentRule &&
styleDeclaration.parentRule.origin === global.CSSAgent.StyleSheetOrigin.USER_AGENT) {
return {
selector: styleDeclaration.parentRule.selectors.map(item => item.text).join(', '),
source: 'User Agent Stylesheet',
Copy link
Collaborator

Choose a reason for hiding this comment

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

this seems like an unfortunate situation to show to a user, is the default on mobile illegible text?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Default UA font size value is legible (1em, which by default is 16px), but there are multiple tags with font-size < 1em, e.g. <h5>, <small> or <sub>.

Copy link
Collaborator

Choose a reason for hiding this comment

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

got it

};
}

if (styleDeclaration.type === CSSStyleDeclaration.Type.Regular && styleDeclaration.parentRule) {
const rule = styleDeclaration.parentRule;
const stylesheetMeta = stylesheets.find(ss => ss.header.styleSheetId === rule.styleSheetId);

if (stylesheetMeta) {
const url = parseURL(stylesheetMeta.header.sourceURL, baseURL);
const range = styleDeclaration.range;
const selector = rule.selectors.map(item => item.text).join(', ');
let source = `${url.href}`;
Copy link
Collaborator

Choose a reason for hiding this comment

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

there seem to be quite a few where the url.href isn't set, does that mean they came from the root document? maybe we can fill in with "" or something instead of empty? it threw me off a bit

image

Copy link
Collaborator Author

@kdzwinel kdzwinel Dec 6, 2017

Choose a reason for hiding this comment

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

fill in with ""

🤔

Normally, source path is shown before line and column number, but when CSS is dynamically injected its source URL is not set:
dynamic-css

We could default to the main resource path, but line and column numbers are relative to the injected stylesheet, not the document so it might be confusing. IMO it would make most sense to just say 'dynamically injected' in this case (and drop line and column numbers). WDYT?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm yeah rather tricky

"dynamically injected" or even just "dynamic" sounds good to me

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated:

dyanmic


if (range) {
const absoluteStartLine = range.startLine + stylesheetMeta.header.startLine + 1;
const absoluteStartColumn = range.startColumn + stylesheetMeta.header.startColumn + 1;

source += `:${absoluteStartLine}:${absoluteStartColumn}`;
}

return {
selector,
source,
};
}
}

return {
source: 'Unknown',
};
}

/**
* @param {WebInspector.CSSStyleDeclaration} styleDeclaration
* @param {Node} node
* @return string
*/
function getFontArtifactId(styleDeclaration, node) {
if (styleDeclaration && styleDeclaration.type === CSSStyleDeclaration.Type.Regular) {
const startLine = styleDeclaration.range ? styleDeclaration.range.startLine : 0;
const startColumn = styleDeclaration.range ? styleDeclaration.range.startColumn : 0;
return `${styleDeclaration.styleSheetId}@${startLine}:${startColumn}`;
} else {
return `node_${node.nodeId}`;
}
}

class FontSize extends Audit {
/**
* @return {!AuditMeta}
*/
static get meta() {
return {
category: 'Mobile friendly',
Copy link
Collaborator

Choose a reason for hiding this comment

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

we nixed all the categories, so no need anymore :)

name: 'font-size',
description: 'Document uses legible font sizes.',
failureDescription: 'Document doesn\'t use legible font sizes.',
helpText: 'Font sizes less than 16px are too small to be legible and require mobile ' +
'visitors to “pinch to zoom” in order to read. ' +
Copy link
Member

Choose a reason for hiding this comment

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

it's a little funny to see this audit end up in passing even when there are failures (example). I know this is the same as other audits, but i'm thinking we could start explaining our passing cutoff in the helpText here.

Strive to have >75% of page text >=16px;

@vinamratasingal @kaycebasques hows that sound?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated!

font-size-copy

'[Learn more](https://developers.google.com/speed/docs/insights/UseLegibleFontSizes).',
requiredArtifacts: ['FontSize', 'Styles', 'URL', 'Viewport'],
};
}

/**
* @param {!Artifacts} artifacts
* @return {!AuditResult}
*/
static audit(artifacts) {
const hasViewportSet = ViewportAudit.audit(artifacts).rawValue;
if (!hasViewportSet) {
return {
rawValue: false,
debugString: 'Text is illegible because of a missing viewport config',
};
}

const totalTextLenght = getTotalTextLength(artifacts.FontSize);
Copy link
Collaborator

Choose a reason for hiding this comment

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

s/Lenght/Length


if (totalTextLenght === 0) {
return {
rawValue: true,
};
}

const failingRules = getFailingRules(artifacts.FontSize);
const failingTextLength = getTotalTextLength(failingRules);
const percentageOfPassingText = (totalTextLenght - failingTextLength) / totalTextLenght * 100;
const pageUrl = artifacts.URL.finalUrl;

const headings = [
{key: 'source', itemType: 'url', text: 'Source'},
{key: 'selector', itemType: 'code', text: 'Selector'},
{key: 'coverage', itemType: 'text', text: 'Coverage'},
{key: 'fontSize', itemType: 'text', text: 'Font Size'},
];

const tableData = failingRules.sort((a, b) => b.textLength - a.textLength)
.map(({cssRule, textLength, fontSize, node}) => {
const percentageOfAffectedText = textLength / totalTextLenght * 100;
const origin = getOrigin(artifacts.Styles, pageUrl, cssRule, node);

return {
source: origin.source,
selector: origin.selector,
coverage: `${percentageOfAffectedText.toFixed(2)}%`,
fontSize: `${fontSize}px`,
};
});
const details = Audit.makeTableDetails(headings, tableData);
const passed = percentageOfPassingText >= MINIMAL_PERCENTAGE_OF_LEGIBLE_TEXT;
const debugString = passed ?
null : `${parseFloat((100 - percentageOfPassingText).toFixed(2))}% of text is too small.`;

return {
rawValue: passed,
details,
debugString,
};
}
}

module.exports = FontSize;
8 changes: 8 additions & 0 deletions lighthouse-core/config/seo.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ module.exports = {
gatherers: [
'seo/meta-description',
],
}, {
passName: 'extraPass',
gatherers: [
'seo/font-size',
Copy link
Collaborator

Choose a reason for hiding this comment

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

are we also adding to the default config now just without the report reference? @brendankenny

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point, added it to the default config.

Copy link
Collaborator

Choose a reason for hiding this comment

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

now that we've added the gatherer to default config, no need to add it here too, it's just getting run twice now :)

image

just adding it to the report should be the only needed change in this file

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good catch. It would probably make sense to dedup gatherers or show some warning when duplicates are found. In the meantime I removed all gatherers from seo config because all of them are already in default config.

'styles',
Copy link
Collaborator

Choose a reason for hiding this comment

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

unfortunate that this relies on the styles gatherer :/ do you foresee a way the audit could optionally rely on the styles gatherer output? i.e. still report the violations but maybe with less helpful identifiers? I'm not sure we're going to get to a place in DevTools where we want to add the extra pass by default and it'd be a shame to miss out on the whole audit

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Only thing I need the styles gatherer for is stylesheetId -> stylesheet URL info. We can just say 'external stylesheet' if we don't have that mapping info, but I wonder - what's wrong with the 'styles' gatherer? Why does it need a separate run? Maybe I can collect stylesheetId -> stylesheet URL information in my gatherer separately and avoid requiring a separate run?

Copy link
Collaborator

Choose a reason for hiding this comment

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

styles gatherer parses all the stylesheets on the page with gonzales which can be extremely slow in some cases (old runs of theverge spent ~20s in styles gatherer)

this seems like a useful split though for cases where you don't need the actual parsed content of stylesheets 👍

Copy link
Collaborator Author

@kdzwinel kdzwinel Oct 15, 2017

Choose a reason for hiding this comment

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

I've tried creating a styles-metadata gatherer that duplicates styles gatherer minus the parsing. However, I couldn't get styleSheetIds to match. font-size gatherer returned different IDs than styles-metadata gatherer for the exact same stylesheets. As far as I can see, this happens when you have two separate CSS.enable->CSS.disable runs. When I've put CSS.styleSheetAdded into the font-size gatherer (same CSS.enable->CSS.disable run) everything started to work.

Why this happens? No idea, possibly a Chrome bug. Why it worked when I used styles gatherer? This gatherer starts collecting stylesheet info in beforePass and finishes in afterPass, I can't do it in the default run because LH will complain that: "CSS domain enabled when starting trace".

I'm not a fan of keeping CSS.styleSheetAdded in the font-size gatherer, but don't see any other option at this point. Please let me know if you have any other ideas.

],
}],
audits: [
'seo/meta-description',
'seo/http-status-code',
'seo/font-size',
],
groups: {
'seo-mobile': {
Expand All @@ -41,6 +48,7 @@ module.exports = {
{id: 'document-title', weight: 1, group: 'seo-content'},
{id: 'meta-description', weight: 1, group: 'seo-content'},
{id: 'http-status-code', weight: 1, group: 'seo-crawl'},
{id: 'font-size', weight: 1, group: 'seo-mobile'},
],
},
},
Expand Down
Loading