npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-component-timing

v0.1.2

Published

Monitor performance at a per component level

Downloads

30

Readme

react-component-performance

Monitor performance at a per component level

Current state is RFC 📄

If you like this idea, or have know of something like this that already exists, or have feedback before I start making anything, let me know!

Motivation for this tool

We want to measure the load time of our apps in a way that,

  • Meaningfully reflects real user experiences, including geography, devices, network conditions
  • Works for single page applications that progressively load parts of the app ("cold" vs. "warm" page loads)
  • Is easily comparible between applications

There are a number of performance metrics that already exist

Ways of measuring performance

  • window.onload timing
  • Above-the-fold render time (ATF)
    • Measurable with webpagetest.org
  • Time to first paint
  • Time to first contentful paint
  • Time to first meaningful paint
  • Apdex (uses timings to create an index)

Measuring Single page app performance

  • window.onload just doesn't work for SPA's, it's not triggered for subsequent page loads, or at the right time
  • Above-the-fold render time doesn't work for real traffic, but it does give a good impression with simulated traffic.
  • "Apdex" is not easy to compare (with different t values), and does not define what a "satisfactory" page load is.
  • There is no such thing as "load time" as a single number. We want to represent a much richer picture.
    • We represent many different experiences (cold page load, warm page load)
    • We represent many different environments (network conditions, geographical location)
    • However, we need to reduce it to a single number for KPI's, OKR's, etc.
    • We want to compare fairly with other applications

First "meaningful" paint

First meaningful paint provides a good way of measuring user experience, but requires knowledge of what "meaningful" is.

We also still need a good way to measure load times across "warm" page loads, as the first paint isn't the only one!

⏰ react-component-timing

React component timing is a tool that helps you get the above data, so that when you try to move the needle, you actually move it for your users.

  • It lets you define what a meaningful paint is for a React app
  • It breaks down timings by component, so that you can see how your app progressively loads.
  • It provides timings via the User timing API that are easily comparible across different experiences.
  • It provides a pluggable layer that fits into your existing tools: New Relic, Google Analytics, etc.

API

import * as React from "react";
import { ReactComponentTimingProvider } from "react-component-timing";
import { newRelicIntegration } from "./new-relic-timing-reporter";
import withData from "./app-data-provider";

export class AppImpl extends React.Component {
  checkLoaded({ childTimings }) {
    /* We have access to the timings of all of the children, through some magic */
    return (
      childTimings.nav.loaded &&
      childTimings.article.loaded &&
      this.props.data.loaded
    );
  }

  render() {
    return (
      <ReactComponentTimingProvider reporter={newRelicIntegration}>
        <Page>
          <ReactComponentTiming
            componentName="page"
            checkLoaded={this.checkLoaded}
          >
            <Nav />
            <Content>
              <Article />
              <Comments />
            </Content>
          </ReactComponentTiming>
        </Page>
      </ReactComponentTimingProvider>
    );
  }
}

export const App = withData(AppImpl);
import * as React from "react";
import { ReactCompomnentTiming } from "react-component-timing";
import { NavigationInner } from "./navigation-inner";
import withData from "./nav-data-provider";

class NavImpl extends React.Component {
  checkLoaded() {
    return this.props.data.loaded;
  }

  render() {
    return (
      <>
        <ReactCompomnentTiming
          componentName="nav"
          checkLoaded={this.checkLoaded}
        />
        <NavigationInner />
      </>
    );
  }
}

export const Nav = withData(NavImpl);

(And similar for Comments and Article, which would both include dynamically loaded data)

API Concepts

Events

  • Load: a component transitioned from "isLoading: false" -> true -> false. The time taken between falses is reported as a "load" event
    • Metadata:
      • Props given to the component during the transition
      • Page path
  • Render: a component entered a render state

How it would work

✨ Through some wizardry and probably some API changes from the above, I think it'd be possible to implement something that would build a picture of the timing of when these "timing" components got rendered, and when they reported that they were loaded.

When props change (and are rerendered), a component can go into and out of a loading state. This loading state, and the reasons why, would be captured by the reporter.

This would let you define custom metrics, for, say, the comments component. You would be able to know a performance timing from cold page load to the comments being loaded, and how that is different on subsequent warm page loads.

The API also allows you to define "loading" states by composing your child loading states (possibly excluding some if they do not constitute "meaningful" for the parent component).


Additional reading

Goals for performance

For what targets to hit, the rail guideline provides good information.

  • Focus on the user.
  • Respond to user input in under 100ms.
  • Produce a frame in under 10ms when animating or scrolling.
  • Maximize main thread idle time.
  • Load interactive content in under 5000ms.

The RAIL framework: _ Response _ Animation _ Idle _ Load

This tool will help measure the Load and Response parts of this framework.