DEV Community

azu
azu

Posted on • Originally published at Medium on

6

WebApp performance monitoring by performance.mark with metadata

I’ve created performance-mark-metadata. This library provide performance.mark with custom meta data.

This library inspired by User Timing API Level 3 proposal. This proposal will add details as metadata to performance.mark.

Currently, Performance.mark() API can not add metadata to marking.

Supports

Old browser need to Performance.mark() polyfill.

Install

Install with npm:

npm install performance-mark-metadata
Enter fullscreen mode Exit fullscreen mode

Example

import { PerformanceMetadataMarker } from "performance-mark-metadata";
const marker = new PerformanceMetadataMarker();
const metadata = {
details: { key: "value" }
};
const markerName = "name";
// mark with metadata
marker.mark(markerName, metadata);
performance.getEntriesByName(markerName).forEach(entry => {
// get metadata for entry
const result = marker.getEntryMetadata(entry);
/*
{
details: { key: "value" }
};
*/
assert.strictEqual(result, metadata, "should get same metadata");
});
view raw block1.js hosted with ❤ by GitHub

Usage in Node.js

Node.js 8.5.0 introduce perf_hooks module. You can use this library by passing require("perf_hooks").performance to PerformanceMetadataMarker constructor arguments.

import { PerformanceMetadataMarker } from "performance-mark-metadata";
const nodePerformanceHook = require("perf_hooks");
const performance = nodePerformanceHook.performance;
const marker = new PerformanceMetadataMarker({
performance
});
marker.mark("name", {
details: { key: "value" }
});
view raw block2.js hosted with ❤ by GitHub

UseCase

This example show actual usage.

You want to found performance problem on viewing the site. You can analyze the problem by using performance-mark-metadata.

It is useful for Real user monitoring(RUM). In development, you can use browser’s development tools, but it is difficult about RUM.

Mark points

  • Mark current Frame Per Seconds(FPS)
  • Mark each action like “onClick”

Record FPS

const { PerformanceMetadataMarker } = require("performance-mark-metadata");
const marker = new PerformanceMetadataMarker();
const FpsEmitter = require("fps-emitter");
const fps = new FpsEmitter();
fps.on("update", function(FPS) {
// mark current FPS
marker.mark("FPS", {
details: {
FPS: FPS
}
});
});
view raw block3.js hosted with ❤ by GitHub

and record action

// heavy task
const heavyTaskButton = document.getElementById("js-button");
heavyTaskButton.addEventListener("click", () => {
marker.mark("Heavy Action");
// ... heavy task ...
})
view raw block4.js hosted with ❤ by GitHub

After that, you can get FPS and action logs.

const logData = performance.getEntriesByType("mark").map(entry => {
const meta = marker.getEntryMetadata(entry);
return {
type: entry.name,
timeStamp: entry.startTime,
meta: meta
};
});
view raw block5.js hosted with ❤ by GitHub

Analytics

You can get the log data and analyze the log data.

For example, visualize the log data by using C3.js.

https://azu.github.io/performance-mark-metadata/

You can found the relationship between “FPS” and “Heavy Task”. As a result, You can found that the performance problem is caused by “Heavy Task”.

Welcome to ⭐️ and Pull Request!

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (2)

Collapse
 
bgadrian profile image
Adrian B.G.

Can it be used to gather sample data from users and centralize it? Also can it be used w/o nodejs? For a static website for example.

Collapse
 
azu profile image
azu

Can it be used to gather sample data from users and centralize it?

Yes, But you should prepare own logging system and post data to the logging system.
For example, API Gateway + Lambda + S3(Post serialized JSON data from a browser to lambda via API Gateway, and save it to S3).

Also can it be used w/o nodejs?

Yes, It is work on modern browser.

Logging backend could be implemented in any language. It just treat log data like json.

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs