> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashcat.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Metrics Collection and Reporting

> Learn about Flashduty RUM performance metrics collection methods, reporting mechanisms, and configuration instructions.

Flashduty RUM supports collecting and reporting Web Vitals-related performance metrics to help you comprehensively monitor and optimize website performance. Through these metrics, you can understand the actual experience of users when visiting your website and make targeted optimizations.

## Web Vitals Metrics Overview

Flashduty RUM supports the following [Core Web Vitals metrics](https://web.dev/articles/vitals):

| Metric   | Full Name                 | Description                                              |
| -------- | ------------------------- | -------------------------------------------------------- |
| **LCP**  | Largest Contentful Paint  | Measures loading performance of main page content        |
| **INP**  | Interaction to Next Paint | Measures overall interaction responsiveness              |
| **CLS**  | Cumulative Layout Shift   | Measures visual stability                                |
| **FCP**  | First Contentful Paint    | Measures first content rendering time                    |
| **FID**  | First Input Delay         | Measures page interaction performance (auxiliary metric) |
| **TTFB** | Time to First Byte        | Measures server response speed (auxiliary metric)        |

These metrics are automatically collected when users visit pages and reported to the Flashduty platform through the SDK. You can view detailed performance data in the analytics dashboard.

<Warning>
  For pages opened in the background (e.g., in a new tab or unfocused window), INP and LCP data will not be collected.
</Warning>

## Metric Calculation Methods

<AccordionGroup>
  <Accordion title="LCP - Largest Contentful Paint">
    **Calculation Method:** Time from page load start (`navigationStart`) to when the largest visible content element (such as images, text blocks) finishes rendering.

    **Use Case:** Monitor main page or critical page content loading speed, identify resource loading bottlenecks.
  </Accordion>

  <Accordion title="FCP - First Contentful Paint">
    **Calculation Method:** Measures the time from when the user first navigates to the page to when any part of the page content is rendered on the screen.

    **Use Case:** Used to measure perceived loading speed, helps assure users that something is happening.
  </Accordion>

  <Accordion title="INP - Interaction to Next Paint">
    **Calculation Method:** Measures the delay from all user interactions (clicks, taps, keyboard input) to the next frame rendering.

    **Use Case:** Evaluate overall page interaction responsiveness, optimize high-latency interaction scenarios.
  </Accordion>

  <Accordion title="CLS - Cumulative Layout Shift">
    **Calculation Method:** Calculates the score of all unexpected layout shifts (shift distance × impact area).

    **Use Case:** Identify page jumping issues caused by dynamic content or ads.
  </Accordion>

  <Accordion title="FID - First Input Delay">
    **Calculation Method:** Time difference from when the user first interacts to when the browser processes the event.

    **Use Case:** Optimize response speed of interaction-intensive pages (such as forms, navigation menus).
  </Accordion>
</AccordionGroup>

## Monitoring Single Page Applications (SPA)

For single page applications, the RUM Browser SDK distinguishes between `initial_load` and `route_change` navigation types through the `loading_type` attribute.

<Tabs>
  <Tab title="History SPA">
    If an interaction on the page causes the URL to change without a full page refresh, the RUM SDK starts a new `view` with `loading_type:route_change`.

    RUM uses the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History) to track URL changes.
  </Tab>

  <Tab title="Hash SPA">
    The RUM SDK automatically monitors frameworks that rely on hash (`#`) navigation. The SDK listens for `HashChangeEvent` and emits a new `view`.

    Events from HTML anchors that don't affect the current view context are ignored.
  </Tab>
</Tabs>

<Tip>
  For SPA applications, if you need to monitor performance after route changes, it's recommended to use custom performance monitoring features to measure performance metrics of specific components or interactions.
</Tip>

## Custom Performance Monitoring

### Component-Level Performance Measurement

Use the `customVital` API to monitor the performance of specific components or interactions, suitable for:

* Critical component rendering time
* User interaction response time
* Business process duration

<CodeGroup>
  ```javascript Measure Component Rendering theme={null}
  // Start timing
  const ref = window.FC_RUM.startDurationVital("componentRendering", {
    description: "login-form",
    context: { clientId: "xxx", componentVersion: "1.0.0" },
  });

  // Stop timing
  window.FC_RUM.stopDurationVital(ref);
  ```

  ```javascript Report Duration Directly theme={null}
  window.FC_RUM.addDurationVital("dropdownRendering", {
    startTime: 1707755888000, // UNIX timestamp (milliseconds)
    duration: 10000, // Duration (milliseconds)
  });
  ```
</CodeGroup>

### Performance Timing Records

Use the `addTiming` API to record key time points, suitable for:

* Critical element loading (such as first screen images)
* First user interaction (such as first scroll)
* Business milestone timestamps

<CodeGroup>
  ```javascript Record First Scroll theme={null}
  document.addEventListener("scroll", function handler() {
    document.removeEventListener("scroll", handler);
    window.FC_RUM.addTiming("first_scroll");
  });
  ```

  ```javascript Async Scenario theme={null}
  document.addEventListener("scroll", function handler() {
    document.removeEventListener("scroll", handler);
    const timing = Date.now();
    window.FC_RUM.onReady(() => {
      window.FC_RUM.addTiming("first_scroll", timing);
    });
  });
  ```
</CodeGroup>

## Important Notes

<CardGroup cols={2}>
  <Card title="Naming Conventions" icon="tag">
    * Avoid spaces and special characters in metric names
    * Use descriptive naming (e.g., `login_form_render`)
    * Maintain naming consistency
  </Card>

  <Card title="Performance Impact Control" icon="gauge">
    * Control the number of custom metrics
    * Avoid frequent timing
    * Set reasonable sampling rates
  </Card>
</CardGroup>

## Frequently Asked Questions

<AccordionGroup>
  <Accordion title="Abnormal Page Load Time">
    * Check slow-loading resources (images, scripts)
    * Investigate third-party script blocking
    * Analyze long-running JavaScript
  </Accordion>

  <Accordion title="Inaccurate Activity State Determination">
    * Confirm if there are frequent background requests
    * Check handling of long connections or streaming requests
    * Use `excludedActivityUrls` to exclude interference
  </Accordion>

  <Accordion title="Custom Metrics Issues">
    * Verify metric names comply with conventions
    * Ensure timers start and stop correctly
    * Check timestamp accuracy in async scenarios
  </Accordion>

  <Accordion title="Empty Web Vitals Metrics">
    | Reason                | Description                                                                         |
    | --------------------- | ----------------------------------------------------------------------------------- |
    | Background Page       | Page opened in new tab or unfocused window, causing INP and LCP to not be collected |
    | SPA Route Change      | Core Web Vitals metrics are not re-collected during `loading_type:route_change`     |
    | Integration Method    | Page finished loading before SDK was fully initialized                              |
    | Page Lifecycle        | Page was closed or navigated away before metric collection completed                |
    | Browser Compatibility | Older browser versions don't support certain Web Vitals APIs                        |
    | No Page Content       | Page has no measurable content elements (such as blank pages)                       |
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Performance Analysis" icon="chart-line" href="./performance-analysis">
    Deep dive into performance data analysis
  </Card>

  <Card title="Diagnosis and Optimization" icon="wrench" href="./diagnosis-optimization">
    Learn problem diagnosis and optimization methods
  </Card>
</CardGroup>
