Skip to content

Instantly share code, notes, and snippets.

@WebCloud
Created May 20, 2025 21:42
Show Gist options
  • Save WebCloud/3f03594f42271a7ee62174fcf7c50429 to your computer and use it in GitHub Desktop.
Save WebCloud/3f03594f42271a7ee62174fcf7c50429 to your computer and use it in GitHub Desktop.

INP report based on trace analysis

Your INP value is 285.322 and your score is needs improvement

Interaction to Next Paint (INP) is a crucial metric that measures the overall responsiveness of your page to user interactions. It captures the latency of all clicks, taps, and key presses throughout the page's lifespan and reports the single worst interaction latency. Your current INP score of 285.322 ms falls into the "needs improvement" category, indicating that users may experience noticeable delays when interacting with your page.

Optimizing INP is essential for a smooth and engaging user experience. A high INP often points to a busy main thread that is unable to quickly respond to user input and render the next visual update. This report analyzes the specific interaction that contributed to this score and provides actionable steps to improve it.

Actionable Optimizations

The primary contributor to your INP score is the significant time spent in the processing phase of the interaction. To improve your INP, you must focus on reducing the duration of tasks executed on the main thread in response to user input. This often involves optimizing JavaScript code triggered by interactions.

Data from trace analysis

  • Input delay: 2 ms - The input delay is minimal, suggesting the main thread was available when the user initiated the interaction. This is a good starting point.
  • Processing: 258 ms - This is the largest component of the interaction latency. It indicates that the browser spent a considerable amount of time executing code (likely JavaScript) after receiving the input but before it could start rendering the visual update. This phase is the main target for optimization.
  • Presentation delay: 25.322 ms - This is the time taken from the end of processing until the next frame is painted. While smaller than the processing time, optimizing rendering and layout work can help reduce this delay further.
  • Animation frames events data: Analysis of the animation frame events during the interaction reveals a particularly long event handler execution lasting 197.7 ms, associated with a click on a DIV#__next element. This single long task is the most probable cause of the high processing time and the resulting "needs improvement" INP score. There was also a style duration of 8ms within this event, suggesting some style recalculation occurred.

INP interaction on timeline

INP Interaction on timeline image

To address the high INP, focus your efforts on the processing phase, specifically identifying and optimizing the code executed by the long event handler (the 197.7 ms task). Use browser developer tools, particularly the Performance tab, to record a trace of the interaction. This will allow you to drill down into the call stack of the long task and pinpoint the exact functions or operations consuming the most time. Research techniques for breaking up long JavaScript tasks, optimizing DOM updates, and minimizing style recalculations to ensure interactions complete within the recommended 200 ms threshold.

Trace events analysis

image

The selected callframe is a Function call originating from the NextJS framework bundle (_next/static/chunks/framework-...js). This function call is executing as part of a microtask queue (Run microtasks), which was triggered by a v8.callFunction event, itself initiated by a click event handler. Essentially, this represents a significant chunk of work performed by the NextJS framework in response to a user click.

Execution Context:

  • Ancestors: The execution path leading to this Function call is Task -> Event: click -> v8.callFunction -> Run microtasks -> v8.callFunction -> Function call. This shows that the selected task is a direct consequence of a user clicking on an element, and the work is being processed within a microtask, likely scheduled by the initial click handler.
  • Descendants: The selected Function call (duration 148.9ms) primarily delegates work to two main children:
    • An anonymous function (duration 117.1ms) which involves a deep chain of calls related to styling, layout (css, renderRule, _renderStyleToClassNames, Recalculate style), and scheduling asynchronous tasks (setTimeout).
    • A function named oK (duration 8.3ms), which initiates a highly repetitive call pattern (oK -> oQ) that appears many times in the tree. This pattern eventually leads to DOM manipulation (removeChild) and subsequent style recalculations (Recalculate style).

Performance Quantification:

  • Duration: The selected Function call took 148.9ms to execute.
  • Relative Cost: This single function call accounts for the vast majority (nearly 100%) of the Run microtasks duration (149.9ms) and a significant portion (about 58%) of the total click event handling duration (257.8ms). It is a major contributor to the overall task time (260.9ms).
  • Potential Bottlenecks: The selected Function call is a "Long Task" (exceeding 50ms), which can block the main thread and make the page unresponsive to user input. The analysis of its children reveals two key areas contributing to this:
    • Repetitive/Recursive Calls & DOM Manipulation: The deep and repeated oK -> oQ call pattern, originating from the NextJS framework bundle and leading to removeChild and Recalculate style, is a strong indicator of inefficient DOM manipulation within a loop or recursive structure. This pattern consumes a substantial amount of time.
    • Styling and Layout: The chain involving css, renderRule, _renderStyleToClassNames, and Recalculate style also adds noticeable overhead (around 40.5ms in one branch, plus other recalculations). Forced synchronous layouts (getPropertyValue followed by Recalculate style) are also observed and contribute to layout thrashing.

Suggestions for Improvement:

  1. Investigate the Repetitive Framework Logic: The most prominent bottleneck is the deep, repetitive call stack (oK -> oQ) originating from the NextJS framework bundle, which seems tied to DOM manipulation (removeChild) and style recalculations. This pattern suggests an inefficient update loop or rendering process.
    • Action: Identify the specific component or state change that triggers this deep call stack. Analyze the logic within the oK and oQ functions (or the code they represent) to understand why it's repeating so many times and causing DOM removals.
    • Research: Look into optimizing state updates, list rendering, or component unmounting logic in your NextJS application. Consider techniques like virtualizing long lists or optimizing how components handle updates to minimize unnecessary DOM operations.
  2. Optimize Styling and Layout: The time spent in CSS-in-JS related functions (css, renderRule, etc.) and style recalculations is also significant.
    • Action: Review the styles being applied in response to the click event. Are complex styles or layout changes being triggered? Identify and optimize instances of forced synchronous layouts (reading layout properties like getPropertyValue immediately after modifying the DOM or styles).
    • Research: Explore ways to optimize CSS-in-JS performance, potentially by reducing the complexity of generated styles or using techniques that minimize runtime style computation. Learn about avoiding layout thrashing by batching DOM reads and writes.
  3. Review Third-Party Tracking Scripts: While not the selected node, a considerable amount of time within the click handler is spent executing Google Tag Manager scripts (from googletagmanager.com). These calls (legacySendEvent, sendGA4Event, push, etc.) add overhead.
    • Action: Evaluate the necessity and implementation of all tracking events fired on this click.
    • Research: Investigate options for deferring or asynchronously sending tracking events that don't need to block the main thread for immediate user feedback. Ensure your GTM tags are configured efficiently and are not causing performance issues like excessive DOM access or synchronous network requests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment