generated from adobe/aem-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 174
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MWPW-154969 Log LCP and key user attributes
This adds the ability to log performance data back to Lana. To enable the feature, metadata `pageperf = ‘on’ ` must be set for the page. This feature only works in Chrome browsers. Additionally `pageperf-rate` can be set to determine what percentage of pages will send data. E.g `pageperf-rate=15` would have 15% of the pages send perf data. The default rate is `50`%. The sending of the data to Lana is delayed so as to not affect any parts of the page load. Data sent: * Chrome Version * CLS Score * Country (only if georouting is enabled via geo2) * Downlink: Mbps - Chrome caps value at `10` * LCP Score * LCP Element Type * LCP URL * If there is no identifying url, the element html will be used. * Adobe IMS Logged In Status * OS * URL of page * Window Width & Height * MEP Manifest Data * Manifest(s) Used (only the ones that have been applied to the page) * Selected Target in the manifest
- Loading branch information
1 parent
071a858
commit d4df0a3
Showing
3 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
const LANA_CLIENT_ID = 'pageperf'; | ||
|
||
let lanaSent = false; | ||
|
||
function sendToLana(lanaData) { | ||
if (lanaSent) return; | ||
const ua = window.navigator.userAgent; | ||
|
||
Object.assign(lanaData, { | ||
chromeVer: (ua.match(/Chrome\/(\d+\.\d+\.\d+\.\d+)/) || [])[1] || '', | ||
country: sessionStorage.getItem('akamai') || '', | ||
// eslint-disable-next-line compat/compat | ||
downlink: window.navigator?.connection?.downlink || '', | ||
loggedIn: window.adobeIMS?.isSignedInUser() || false, | ||
os: (ua.match(/Windows/) && 'win') | ||
|| (ua.match(/Mac/) && 'mac') | ||
|| (ua.match(/Android/) && 'android') | ||
|| (ua.match(/Linux/) && 'linux') | ||
|| '', | ||
windowHeight: window.innerHeight, | ||
windowWidth: window.innerWidth, | ||
url: `${window.location.host}${window.location.pathname}`, | ||
}); | ||
|
||
lanaData.cls ||= 0; | ||
const lanaDataStr = Object.entries(lanaData) | ||
.sort(([a], [b]) => a.localeCompare(b)) | ||
.map(([key, value]) => `${key}=${value}`) | ||
.join(','); | ||
|
||
window.lana.log(lanaDataStr, { | ||
clientId: LANA_CLIENT_ID, | ||
sampleRate: 100, | ||
}); | ||
|
||
lanaSent = true; | ||
} | ||
|
||
function observeCLS(lanaData) { | ||
let cls = 0; | ||
/* c8 ignore start */ | ||
new PerformanceObserver((entryList) => { | ||
for (const entry of entryList.getEntries()) { | ||
if (!entry.hadRecentInput) { | ||
cls += entry.value; | ||
} | ||
} | ||
lanaData.cls = cls.toPrecision(4); | ||
}).observe({ type: 'layout-shift', buffered: true }); | ||
} | ||
|
||
function getElementInfo(el) { | ||
const elSrc = el.src || el.currentSrc || el.href || el.poster; | ||
if (elSrc) { | ||
try { | ||
const srcUrl = new URL(elSrc); | ||
return srcUrl.origin === window.location.origin ? srcUrl.pathname : srcUrl.href; | ||
} catch { | ||
// fall through | ||
} | ||
} | ||
const elHtml = el.outerHTML.replaceAll(',', ''); | ||
if (elHtml.length <= 100) return elHtml; | ||
return `${el.outerHTML.substring(0, 100)}...`; | ||
} | ||
|
||
function observeLCP(lanaData, delay) { | ||
new PerformanceObserver((list) => { | ||
const entries = list.getEntries(); | ||
const lastEntry = entries[entries.length - 1]; // Use the latest LCP candidate | ||
lanaData.lcp = parseInt(lastEntry.startTime, 10); | ||
const lcpEl = lastEntry.element; | ||
lanaData.lcpElType = lcpEl.nodeName.toLowerCase(); | ||
lanaData.lcpEl = getElementInfo(lcpEl); | ||
|
||
setTimeout(() => { | ||
sendToLana(lanaData); | ||
}, delay); | ||
}).observe({ type: 'largest-contentful-paint', buffered: true }); | ||
/* c8 ignore stop */ | ||
} | ||
|
||
function logMepExperiments(lanaData, mep) { | ||
mep?.experiments?.forEach((exp, idx) => { | ||
// only log manifests that affect the page | ||
if (exp.selectedVariantName === 'default') return; | ||
lanaData[`manifest${idx + 1}path`] = exp.manifestPath; | ||
lanaData[`manifest${idx + 1}selected`] = exp.selectedVariantName; | ||
}); | ||
} | ||
|
||
export default function webVitals(mep, { delay = 1000 } = {}) { | ||
const lanaData = {}; | ||
logMepExperiments(lanaData, mep); | ||
observeCLS(lanaData); | ||
observeLCP(lanaData, delay); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.