Last active
May 8, 2020 11:42
-
-
Save daliborgogic/fa61cc2f9aea021700588f204d832e23 to your computer and use it in GitHub Desktop.
[POC] Web Vitals for Nuxt.js https://web.dev/vitals/
This file contains hidden or 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
export default { | |
plugins: ['~/plugins/vitals.client.js'] | |
} |
This file contains hidden or 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
const KEY = 'ga:user' | |
const UID = (localStorage[KEY] = localStorage[KEY] || Math.random() + '.' + Math.random()) | |
function encode(obj) { | |
let k | |
let str = 'https://www.google-analytics.com/collect?v=1' | |
for (k in obj) { | |
if (obj[k]) { | |
str += `&${k}=${encodeURIComponent(obj[k])}` | |
} | |
} | |
return str | |
} | |
async function sendToAnalytics(fullPath, metric) { | |
const { name, delta, entries } = metric | |
let opts = { | |
ec: 'Web Vitals', | |
ea: name, | |
el: fullPath, | |
// Google Analytics metrics must be integers, so the value is rounded. | |
ev: parseInt(delta), | |
ni: false | |
} | |
// For CLS the value is first multiplied by 1000 for greater precision | |
// (note: increase the multiplier for greater precision if needed). | |
if ('CLS' === name) opts.ev = parseInt(delta * 1000) | |
// Calculate the request time by subtracting from TTFB | |
// everything that happened prior to the request starting. | |
if ('TTFB' === name) opts.ev = parseInt(delta - entries[0].requestStart) | |
// Replace UA-XXXXXXXX-X by your Google Analytics tracking ID. | |
const args = Object.assign({ tid: 'UA-XXXXXXXX-X', cid: UID }, opts) | |
const obj = Object.assign({ t: 'event' }, args, opts, { z: Date.now() }) | |
// console.log(name, encode(obj)) | |
// console.log(name, metric) | |
const URL = encode(obj) | |
if (process.browser && navigator.sendBeacon) | |
navigator.sendBeacon(URL, null) | |
else | |
fetch(URL, { method: 'POST', keepalive: true }) | |
} | |
async function webVitals(fullPath) { | |
await import('web-vitals').then( | |
({ getCLS, getFID, getLCP, getTTFB, getFCP }) => { | |
getFID(metric => sendToAnalytics(fullPath, metric)) | |
getTTFB(metric => sendToAnalytics(fullPath, metric)) | |
getLCP(metric => sendToAnalytics(fullPath, metric)) | |
getCLS(metric => sendToAnalytics(fullPath, metric)) | |
getFCP(metric => sendToAnalytics(fullPath, metric)) | |
} | |
) | |
} | |
export default async function ({ app: { router } }) { | |
router.onReady(async to => { | |
await webVitals(to.fullPath) | |
router.afterEach(async to => await webVitals(to.fullPath)) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ToDo
navigator.sendBeacon()
fallback tofetch