Skip to content

Instantly share code, notes, and snippets.

@daliborgogic
Last active May 8, 2020 11:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daliborgogic/fa61cc2f9aea021700588f204d832e23 to your computer and use it in GitHub Desktop.
Save daliborgogic/fa61cc2f9aea021700588f204d832e23 to your computer and use it in GitHub Desktop.
[POC] Web Vitals for Nuxt.js https://web.dev/vitals/
export default {
plugins: ['~/plugins/vitals.client.js']
}
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))
})
}
@daliborgogic
Copy link
Author

daliborgogic commented May 7, 2020

ToDo

  • Replace event label with route full path
  • Use navigator.sendBeacon() fallback to fetch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment