3.1.5 • Public • Published


    Collect and measure browser performance metrics

    All metrics are converted to snake_case

    import { navigation, paint } from 'page-timing';
    (async () => {
        const results = await Promise.all([
        const metrics = Object.assign(...results);
        fetch('/browser-performance-metrics', {
            method: 'POST',
            body: JSON.stringify({
                page_name: 'my page',

    API endpoints


    Name Meaning Group Type
    navigation_start Termination of previous document upon navigating navigation number
    unload_event_start Previous document unload navigation number
    unload_event_end navigation number
    redirect_count Numbers of redirects while requesting this page navigation number
    redirect_start Redirect from previous document navigation number
    redirect_end navigation number
    fetch_start Ready to fetch the document navigation number
    domain_lookup_start navigation number
    domain_lookup_end navigation number
    duration Difference between responseEnd and startTime navigation number
    connect_start Sent request to open a connection navigation number
    connect_end navigation number
    secure_connection_start Secure connection handshake navigation number
    request_start Request the document navigation number
    response_start Received the first byte of the response navigation number
    response_end Received the last byte of the response navigation number
    dom_loading Parser started work navigation number
    dom_interactive Parser finished work on main document. Changed document readyState to "interactive" navigation number
    dom_content_loaded_event_start Executed required scripts after parsing the document navigation number
    dom_content_loaded_event_end navigation number
    dom_complete Changed document readyState to "complete" navigation number
    load_event_start All assets are loaded. Document fires "load" event navigation number
    load_event_end Document finished executing "load" event listeners navigation number
    transfer_size Size (octets) of response headers and payload body navigation number
    encoded_body_size Size (octets) of payload body navigation number
    decoded_body_size Size (octets) of message body navigation number
    worker_start Time until service worker ran navigation number
    first_paint User agent first rendered after navigation paint number
    first_contentful_paint Document contains at least one element that is paintable and contentful † paint number
    first_image_paint TBD paint number
    final_asset_javascript_count Total number of Javascript resources assets number
    final_asset_javascript_load Loading time spent on Javascript resources assets number
    final_asset_javascript_size Total size of Javascript resources assets number
    final_asset_stylesheets_count Total number of CSS resources assets number
    final_asset_stylesheets_load Loading time spent on CSS resources assets number
    final_asset_stylesheets_size Total size of CSS resources assets number
    final_asset_images_count Total number of image resources assets number
    final_asset_images_load Loading time spent on image resources assets number
    final_asset_images_size Total size of image resources assets number
    final_asset_other_count Total number of other resources assets number
    final_asset_other_load Loading time spent on other resources assets number
    final_asset_other_size Total size of other resources assets number
    connection_type bluetooth, cellular, ethernet, none, wifi, wimax, other, unknown connection string
    effective_bandwidth Mbps connection number
    effective_connection_type slow-2g, 2g, 3g, 4g connection string
    effective_max_bandwidth Mbps connection number
    reduced_data_usage Vendor's "Data Saver" feature enables connection boolean
    round_trip_time Estimated effective round-trip in ms connection number
    navigation_type navigate, reload, back_forward, prerender connection string
    js_heap_size_limit Maximum bytes available for JS heap memory number
    total_js_heap_size Total allocated bytes for JS heap memory number
    used_js_heap_size Currently active bytes of JS heap memory number
    window_inner_height Height of the window's layout viewport display number
    window_inner_width Width of the window's layout viewport display number
    screen_color_depth Color depth of the screen display number
    screen_pixel_depth Bit depth of the screen display number
    screen_orientation_type landscape-primary, landscape-secondary, portrait-primary, portrait-secondary display string
    final_dom_node_count Total number of nodes under the document object dom number
    final_dom_nest_depth Highest nesting depth of DOM element under the document dom number
    final_html_size Character count of the HTML document dom number
    page_time_elapsed milliseconds elapsed since the time origin elapsed number

    contentful element: A visible element which contains non empty text, media content or input.

    More functions


    Measure page frame rate at a certain point in time

    import { fps } from 'page-timing';
    const frames_per_second = await fps();
    console.log({ frames_per_second });

    Increase sample rate by checking more than one second. (Result is still in frames per second)

    const frames_per_second = await fps({ sample: 5 });
    console.log({ frames_per_second });


    Wrap a function and measure it's execution time in milliseconds into a performance measure entry.

    import { measure } from 'page-timing';
    async function myFunction(
        await wait(50);
    await measure(myFunction, 'my-function');
    // Example: Convert entries to a named array
            ({ name, duration }) => ({[name]: duration})
    // {my-function: 53.35999990347773}
    // Example: Retrieve a specific entry
    const { duration } = performance.getEntriesByName('my-function');
    // 53.35999990347773

    Illustration of navigation events


    A simple example to add web vitals and TTI

    npm i page-timing web-vitals tti-polyfill
    import { all, connection } from 'page-timing';
    import { getLCP, getFID, getCLS } from 'web-vitals';
    import TTI from 'tti-polyfill';
    (async () => {
        const connectionInfo = await connection();
        // Send metrics from browser performance API
        send(await all());
        // Send web vitals to the same endpoint
            [getLCP, 'largest_contentful_paint'],
            [getFID, 'first_input_delay'],
            [getCLS, 'cumulative_layout_shift'],
            ([ fn, name ]) => fn(
                ({ value }) => send({
                    [name]: value,
                    ...connectionInfo // Some connection info
            (time_to_interactive) => send({
                ...connectionInfo // Some connection info
        ).catch(() => null)
    const send = metrics => fetch('/browser-performance-metrics', {
      method: 'POST',
      body: JSON.stringify({ page_name: 'my page', metrics }),


    npm i page-timing

    DownloadsWeekly Downloads






    Unpacked Size

    28.8 kB

    Total Files


    Last publish


    • fiverrit
    • omrilotan
    • michael5r