-
Notifications
You must be signed in to change notification settings - Fork 9.3k
/
link-blocking-first-paint.js
110 lines (96 loc) · 3.35 KB
/
link-blocking-first-paint.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/**
* @license
* Copyright 2016 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.
*/
/**
* @fileoverview Audit a page to see if it does not use <link> that block first paint.
*/
'use strict';
const Audit = require('../audit');
const URL = require('../../lib/url-shim');
const Formatter = require('../../formatters/formatter');
class LinkBlockingFirstPaintAudit extends Audit {
/**
* @return {!AuditMeta}
*/
static get meta() {
return {
category: 'Performance',
name: 'link-blocking-first-paint',
description: 'Site does not use <link> that delay first paint',
helpText: 'Link elements are blocking the first paint of your page. Consider ' +
'inlining critical links and deferring non-critical ones. ' +
'[Learn more](https://developers.google.com/web/tools/lighthouse/audits/blocking-resources).',
requiredArtifacts: ['TagsBlockingFirstPaint']
};
}
/**
* @param {!Artifacts} artifacts
* @param {string} tagFilter The tagName to filter on
* @return {!Object} The object to pass to `generateAuditResult`
*/
static computeAuditResultForTags(artifacts, tagFilter) {
const artifact = artifacts.TagsBlockingFirstPaint;
if (artifact.value === -1) {
return {
rawValue: -1,
debugString: artifact.debugString
};
}
const filtered = artifact.filter(item => item.tag.tagName === tagFilter);
let startTime = Number.MAX_VALUE;
let endTime = 0;
startTime = filtered.reduce((t, item) => Math.min(t, item.startTime), startTime);
const results = filtered.map(item => {
endTime = Math.max(item.endTime, endTime);
return {
url: URL.getDisplayName(item.tag.url),
totalKb: `${Math.round(item.transferSize / 1024)} KB`,
totalMs: `${Math.round((item.endTime - startTime) * 1000)}ms`
};
});
const delayTime = Math.round((endTime - startTime) * 1000);
let displayValue = '';
if (results.length > 1) {
displayValue = `${results.length} resources delayed first paint by ${delayTime}ms`;
} else if (results.length === 1) {
displayValue = `${results.length} resource delayed first paint by ${delayTime}ms`;
}
return {
displayValue,
rawValue: results.length === 0,
extendedInfo: {
formatter: Formatter.SUPPORTED_FORMATS.TABLE,
value: {
results,
tableHeadings: {
url: 'URL',
totalKb: 'Size (KB)',
totalMs: 'Delayed Paint By (ms)'
}
}
}
};
}
/**
* @param {!Artifacts} artifacts
* @return {!AuditResult}
*/
static audit(artifacts) {
const result = LinkBlockingFirstPaintAudit.computeAuditResultForTags(artifacts, 'LINK');
return LinkBlockingFirstPaintAudit.generateAuditResult(result);
}
}
module.exports = LinkBlockingFirstPaintAudit;