Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Commit

Permalink
PWA custom metric (#198)
Browse files Browse the repository at this point in the history
* pwa custom metric

* initiators

* workbox

* one more while i'm here

* workbox version 4+

* workbox version
  • Loading branch information
rviscomi authored May 13, 2021
1 parent d572284 commit 0a07b61
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
9 changes: 9 additions & 0 deletions custom_metrics/event-names.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const response_bodies = $WPT_BODIES;
const eventNamePattern = /addEventListener\([\'"`](\w+)/g;

return Object.fromEntries(response_bodies.filter(har => {
return eventNamePattern.test(har.response_body);
}).map(har => {
const eventNames = Array.from(har.response_body.matchAll(eventNamePattern)).map(match => match[1]);
return [har.url, eventNames];
}));
11 changes: 11 additions & 0 deletions custom_metrics/initiators.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const requests = $WPT_REQUESTS;
return requests.reduce((map, request) => {
const url = request.url;
let initiator = request.initiator.url;
if (!initiator) {
initiator = request.initiator?.stack?.callFrames?.[0]?.url
}
map[initiator] = map[initiator] || [];
map[initiator].push(url);
return map;
}, {});
85 changes: 85 additions & 0 deletions custom_metrics/pwa.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//[pwa]
const response_bodies = $WPT_BODIES;
const requests = $WPT_REQUESTS;
const serviceWorkerRegistrationPattern = /navigator\.serviceWorker\.register\(['"]([^"']+)/m;

const serviceWorkerURLs = response_bodies.filter(har => {
return serviceWorkerRegistrationPattern.test(har.response_body);
}).map(har => {
const base = new URL(har.url).origin;
const serviceWorkerPath = har.response_body.match(serviceWorkerRegistrationPattern)[1];
return new URL(serviceWorkerPath, base).href;
}).reduce((set, url) => {
set.add(url);
return set;
}, new Set());


const manifestURLs = new Set(Array.from(document.querySelectorAll('link[rel=manifest]')).map(link => {
const base = new URL(location.href).origin;
const href = link.getAttribute('href');
return new URL(href, base).href;
}));


const initiatorMap = requests.reduce((map, request) => {
const url = request.url;
let initiator = request.initiator.url;
if (!initiator) {
initiator = request.initiator?.stack?.callFrames?.[0]?.url
}
map[initiator] = map[initiator] || [];
map[initiator].push(url);
return map;
}, {});

function getURLsInitiatedBy(initialURL) {
let initiatorChain = [initialURL];
for (let i = 0; i < initiatorChain.length; i++) {
const url = initiatorChain[i];
if (url in initiatorMap) {
initiatorChain = initiatorChain.concat(initiatorMap[url].filter(url => {
return !initiatorChain.includes(url);
}));
}
}
return initiatorChain;
}

function getEntriesForURLs(urlSet) {
return response_bodies.filter(har => {
return urlSet.has(har.url);
}).map(har => {
return [har.url, har.response_body];
});
}

const serviceWorkers = getEntriesForURLs(serviceWorkerURLs);
const manifests = getEntriesForURLs(manifestURLs).map(([url, body]) => {
let manifest;
try {
manifest = JSON.parse(body);
} catch (e) {
manifest = body;
}
return [url, manifest];
});


const serviceWorkerInitiatedURLs = new Set(Array.from(serviceWorkerURLs).flatMap(getURLsInitiatedBy));
const serviceWorkerInitiated = getEntriesForURLs(serviceWorkerInitiatedURLs);

const workboxPattern = /(?:workbox:[a-z\-]+:[\d.]+|workbox\.[a-zA-Z]+\.?[a-zA-Z]*)/g;
// We should use serviceWorkerInitiatedURLs here, but SW detection has some false negatives.
const workboxInfo = response_bodies.filter(har => {
return workboxPattern.test(har.response_body);
}).map(har => {
return [har.url, Array.from(har.response_body.matchAll(workboxPattern)).map(m => m[0])];
});

return {
serviceWorkers: Object.fromEntries(serviceWorkers),
manifests: Object.fromEntries(manifests),
serviceWorkerInitiated: Object.keys(Object.fromEntries(serviceWorkerInitiated)),
workboxInfo: Object.fromEntries(workboxInfo)
};

0 comments on commit 0a07b61

Please sign in to comment.