uxm
TypeScript icon, indicating that this package has built-in type declarations

1.2.0 • Public • Published

A tiny (1kb gzip) utility library for collecting web performance metrics
that affect user experience.

Why?UsageAPICredits



Modern web platform provides a lot of APIs to analyze page speed information. But it's hard to follow them and even harder to deal with the lack of implementation in different browsers.

UXM is a modular library that allows to combine various functions and collect the data you need. Think about it, as Lodash for user experience APIs.

Use cases:

  • Collect RUM data.
  • Build private version of Chrome User Experience Report.
  • Audit the page performance using Puppeteer (example).
  • Dynamically evaluate the performance of the user's device and adapt the UI.

Features:

Usage

npm install uxm

Collect loading performance metrics:

import { getUrl, getTimeToFirstByte, getFirstContentfulPaint, getDomContentLoaded } from 'uxm'
 
const metrics = {
  url: getUrl(),
  ttfb: getTimeToFirstByte(),
  fcp: getFirstContentfulPaint(),
  dcl: getDomContentLoaded()
}

Analyze current device and connection:

import { getDeviceType, getDeviceMemory, getEffectiveConnectionType } from 'uxm'
 
const device = {
  type: getDeviceType(),
  memory: getDeviceMemory(),
  connection: getEffectiveConnectionType()
}

Collect CrUX-like data:

import { uxm } from 'uxm'
 
uxm().then(metrics => {
  console.log(metrics) // ->
  {
    "deviceType": "desktop",
    "effectiveConnectionType": "4g",
    "firstPaint": 1646,
    "firstContentfulPaint": 1646,
    "domContentLoaded": 1698,
    "onLoad": 2508
  }
})

API

An API is a set of pure functions with one exception to uxm, which is a meta-function to collect multiple metrics at once.

mark(markName)

Create User Timing mark to mark important loading event. A convenient shortcut for window.performance.mark.

import { mark } from 'uxm'
 
mark('page load started')
// ...
mark('hero image displayed')
// ...
mark('page fully loaded')

measure(measureName, [startMarkName])

Create User Timing measure to evaluate timing between 2 marks. A convenient shortcut for window.performance.measure.

import { mark, measure } from 'uxm'
 
mark('start load fonts')
// ...
measure('fonts loaded', 'start load fonts')

getUserTiming()

Return an array with collected performance marks/measures. Each item contains:

  • type - "mark" or "measure"
  • name - unique name
  • startTime - start time since page load
  • duration - measure duration

Example:

[
  {
    "type": "mark",
    "name": "boot",
    "startTime": 1958
  },
  {
    "type": "measure",
    "name": "page did mount",
    "startTime": 1958,
    "duration": 197
  }
]

getTimeToFirstByte()

Return server response time, that is useful for backend monitoring.

getFirstContentfulPaint()

Return the time when first paint which includes text, image (including background images), non-white canvas, or SVG happened. W3C draft for Paint Timing 1.

getFirstPaint()

It's similar to getFirstContentfulPaint but may contain a different value when First Paint is just background change without content.

getDomContentLoaded()

Return the time when DOMContentLoaded event was fired.

getOnLoad()

Return the time when load event was fired.

getEffectiveConnectionType()

Return the effective connection type (“slow-2g”, “2g”, “3g”, or “4g”) string as determined by round-trip and bandwidth values. W3C draft for Network Information API.

getDeviceType()

Return the device type ("phone", "tablet", or "desktop") string using the lightweight heavy-tested user-agent parser.

getDeviceMemory()

Return the device memory ("full" or "lite") string, depends if available memory is bigger than 1 GB. Learn more about Device Memory.

getUrl()

Return a current page URL. A convenient shortcut for window.location.href.

getUserAgent()

Return a User-Agent string. A convenient shortcut for window.navigator.userAgent.

getResources()

Return an array of performance information for each resource on the page. Each item contains:

  • url - resource URL
  • type - one of resource types ("navigation", "link", "img", "script", "xmlhttprequest", or "font")
  • size - transferred size in bytes
  • startTime - when load started
  • duration - loading time in milliseconds

Example:

[
  {
    "url": "https://booking.com/",
    "type": "navigation",
    "size": 79263,
    "startTime": 0,
    "duration": 1821
  },
  {
    "url": "https://q-fa.bstatic.com/mobile/css/core_not_critical_fastly.iq_ltr/8051b1d9fafb2e6339aea397447edfded9320dbb.css",
    "type": "link",
    "size": 54112,
    "startTime": 515,
    "duration": 183
  },
  {
    "url": "https://r-fa.bstatic.com/mobile/images/hotelMarkerImgLoader/211f81a092a43bf96fc2a7b1dff37e5bc08fbbbf.gif",
    "type": "img",
    "size": 2295,
    "startTime": 657,
    "duration": 181
  },
  {
    "url": "https://r-fa.bstatic.com/static/js/error_catcher_bec_fastly/ba8921972cc55fbf270bafe168450dd34597d5a1.js",
    "type": "script",
    "size": 2495,
    "startTime": 821,
    "duration": 43
  },
  ...
]

getLongTasks()

Return an array of { startTime, duration } pairs. Until buffered flag supported, you need to add extra script to the <head /> to collect all Long Tasks:

<script>
  !(function() {
    if ('PerformanceLongTaskTiming' in window) {
      var g = (window.__lt = { e: [] })
      g.o = new PerformanceObserver(function(l) {
        g.e = g.e.concat(l.getEntries())
      })
      g.o.observe({ entryTypes: ['longtask'] })
    }
  })()
</script> 

And then get collected long-tasks using:

import { getLongTasks } from 'uxm'
getLongTasks() // [{"startTime": 672, "duration": 84}, {"startTime": 931, "duration": 84}, {"startTime": 1137, "duration": 135}]

Learn more about Long Tasks.

uxm(opts = {})

Returns a Promise that resolves after load event fired. A default set of metrics is defined by Chrome User Experience Report, but you can customize them using options (url, userAgent, deviceMemory, userTiming, longTasks, resources).

Or pass all to get the full report:

import { uxm } from 'uxm'
 
uxm({ all: true }).then(metrics => {
  console.log(metrics) // ->
  {
    "deviceType": "phone",
    "effectiveConnectionType": "4g",
    "firstPaint": 531,
    "firstContentfulPaint": 531,
    "domContentLoaded": 768,
    "onLoad": 1317,
    "url": "https://www.booking.com/",
    "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1",
    "deviceMemory": "full",
    "userTiming": [
      {
        "type": "measure",
        "name": "b-stylesheets",
        "startTime": 0,
        "duration": 436
      },
      ...
    ],
    "longTasks": [
      {
        "startTime": 587,
        "duration": 79
      },
      ...
    ],
    "resources": [
      {
        "url": "https://booking.com/",
        "type": "navigation",
        "size": 77953,
        "startTime": 0,
        "duration": 1568
      },
      ...
    ]
  }
})

Credits

Treo.sh - Page speed monitoring with Lighthouse

Made with ❤️ by Treo.sh.

Dependencies (0)

    Dev Dependencies (8)

    Package Sidebar

    Install

    npm i uxm

    Weekly Downloads

    1,739

    Version

    1.2.0

    License

    MIT

    Unpacked Size

    26.6 kB

    Total Files

    7

    Last publish

    Collaborators

    • alekseykulikov