Skip to content

Commit

Permalink
Only allow same origin (domain + subdomains) for preload
Browse files Browse the repository at this point in the history
  • Loading branch information
wardpeet committed May 4, 2018
1 parent f0558f7 commit 3815f12
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 7 deletions.
20 changes: 18 additions & 2 deletions lighthouse-core/audits/uses-rel-preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
'use strict';

const URL = require('../lib/url-shim');
const Audit = require('./audit');
const UnusedBytes = require('./byte-efficiency/byte-efficiency-audit');
const THRESHOLD_IN_MS = 100;
Expand Down Expand Up @@ -58,6 +59,20 @@ class UsesRelPreloadAudit extends Audit {
return requests;
}

/**
*
* @param {LH.WebInspector.NetworkRequest} request
* @param {LH.WebInspector.NetworkRequest} mainResource
* @return {boolean}
*/
static shouldPreload(request, mainResource) {
if (request._isLinkPreload || request.protocol === 'data') {
return false;
}

return URL.rootDomainsMatch(request.url, mainResource.url);
}

/**
* Computes the estimated effect of preloading all the resources.
* @param {Set<string>} urls The array of byte savings results per resource
Expand Down Expand Up @@ -117,6 +132,7 @@ class UsesRelPreloadAudit extends Audit {
const originalNode = originalNodesByRecord.get(node.record);
const timingAfter = simulationAfterChanges.nodeTimings.get(node);
const timingBefore = simulationBeforeChanges.nodeTimings.get(originalNode);

// @ts-ignore TODO(phulce): fix timing typedef
const wastedMs = Math.round(timingBefore.endTime - timingAfter.endTime);
if (wastedMs < THRESHOLD_IN_MS) continue;
Expand Down Expand Up @@ -163,8 +179,8 @@ class UsesRelPreloadAudit extends Audit {
/** @type {Set<string>} */
const urls = new Set();
for (const networkRecord of criticalRequests) {
if (!networkRecord._isLinkPreload && networkRecord.protocol !== 'data') {
urls.add(networkRecord._url);
if (UsesRelPreloadAudit.shouldPreload(networkRecord, mainResource)) {
urls.add(networkRecord.url);
}
}

Expand Down
20 changes: 20 additions & 0 deletions lighthouse-core/lib/url-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,26 @@ class URLShim extends URL {
}
}

/**
* Check if rootDomains matches
*
* @param {string} urlA
* @param {string} urlB
*/
static rootDomainsMatch(urlA, urlB) {
const urlAInfo = new URL(urlA);
const urlBInfo = new URL(urlB);

if (!urlAInfo.host || !urlBInfo.host) {
return false;
}

const urlARootDomain = urlAInfo.host.split('.').slice(-2).join('.');
const urlBRootDomain = urlBInfo.host.split('.').slice(-2).join('.');

return urlARootDomain === urlBRootDomain;
}

/**
* @param {string} url
* @param {{numPathParts: number, preserveQuery: boolean, preserveHost: boolean}=} options
Expand Down
44 changes: 39 additions & 5 deletions lighthouse-core/test/audits/uses-rel-preload-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ describe('Performance: uses-rel-preload audit', () => {
const mainDocumentNode = buildNode(2, 'http://www.example.com');
const scriptNode = buildNode(3, 'http://www.example.com/script.js');
const scriptAddedNode = buildNode(4, 'http://www.example.com/script-added.js');
const scriptSubNode = buildNode(5, 'http://sub.example.com/script-sub.js');
const scriptOtherNode = buildNode(6, 'http://otherdomain.com/script-other.js');

mainDocumentNode.addDependency(rootNode);
scriptNode.addDependency(mainDocumentNode);
scriptAddedNode.addDependency(scriptNode);
scriptSubNode.addDependency(scriptNode);
scriptOtherNode.addDependency(scriptNode);

mockGraph = rootNode;
mockSimulator = {
Expand All @@ -68,19 +72,31 @@ describe('Performance: uses-rel-preload audit', () => {
const mainDocumentNodeLocal = nodesByUrl.get(mainDocumentNode.record.url);
const scriptNodeLocal = nodesByUrl.get(scriptNode.record.url);
const scriptAddedNodeLocal = nodesByUrl.get(scriptAddedNode.record.url);
const scriptSubNodeLocal = nodesByUrl.get(scriptSubNode.record.url);
const scriptOtherNodeLocal = nodesByUrl.get(scriptOtherNode.record.url);

const nodeTimings = new Map([
[rootNodeLocal, {starTime: 0, endTime: 500}],
[mainDocumentNodeLocal, {startTime: 500, endTime: 1000}],
[scriptNodeLocal, {startTime: 1000, endTime: 2000}],
[scriptAddedNodeLocal, {startTime: 2000, endTime: 3250}],
[scriptSubNodeLocal, {startTime: 2000, endTime: 3000}],
[scriptOtherNodeLocal, {startTime: 2000, endTime: 3500}],
]);

if (scriptAddedNodeLocal.getDependencies()[0] === mainDocumentNodeLocal) {
nodeTimings.set(scriptAddedNodeLocal, {startTime: 1000, endTime: 2000});
}

return {timeInMs: 3250, nodeTimings};
if (scriptSubNodeLocal.getDependencies()[0] === mainDocumentNodeLocal) {
nodeTimings.set(scriptSubNodeLocal, {startTime: 1000, endTime: 2000});
}

if (scriptOtherNodeLocal.getDependencies()[0] === mainDocumentNodeLocal) {
nodeTimings.set(scriptOtherNodeLocal, {startTime: 1000, endTime: 2500});
}

return {timeInMs: 3500, nodeTimings};
},
};

Expand All @@ -92,17 +108,27 @@ describe('Performance: uses-rel-preload audit', () => {
{
requestId: '2',
_isLinkPreload: false,
_url: 'http://www.example.com',
url: 'http://www.example.com',
},
{
requestId: '3',
_isLinkPreload: false,
_url: 'http://www.example.com/script.js',
url: 'http://www.example.com/script.js',
},
{
requestId: '4',
_isLinkPreload: false,
_url: 'http://www.example.com/script-added.js',
url: 'http://www.example.com/script-added.js',
},
{
requestId: '5',
_isLinkPreload: false,
url: 'http://sub.example.com/script-sub.js',
},
{
requestId: '6',
_isLinkPreload: false,
url: 'http://otherdomain.com/script-other.js',
},
];

Expand All @@ -119,6 +145,14 @@ describe('Performance: uses-rel-preload audit', () => {
request: networkRecords[2],
children: {},
},
'5': {
request: networkRecords[3],
children: {},
},
'6': {
request: networkRecords[4],
children: {},
},
},
},
},
Expand All @@ -130,7 +164,7 @@ describe('Performance: uses-rel-preload audit', () => {
return UsesRelPreload.audit(mockArtifacts(networkRecords, chains, mainResource), {}).then(
output => {
assert.equal(output.rawValue, 1250);
assert.equal(output.details.items.length, 1);
assert.equal(output.details.items.length, 2);
}
);
});
Expand Down

0 comments on commit 3815f12

Please sign in to comment.