Skip to content

fix(web-vitals): report all changes for CLS#266

Open
huang-julien wants to merge 2 commits intomainfrom
fix/CLS_reportallchanges
Open

fix(web-vitals): report all changes for CLS#266
huang-julien wants to merge 2 commits intomainfrom
fix/CLS_reportallchanges

Conversation

@huang-julien
Copy link
Member

🔗 Linked issue

📚 Description

Forgot to enable the option to report every metric including metric before the hook registratiojn

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 7, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/hints@266

commit: e081909

@coderabbitai
Copy link

coderabbitai bot commented Mar 7, 2026

📝 Walkthrough

Walkthrough

The change modifies the web-vitals plugin configuration to enable the reportAllChanges flag for the INP (Interaction to Next Paint) and CLS (Cumulative Layout Shift) metric observers. This flag was already enabled for the LCP (Largest Contentful Paint) observer. The modification adds 2 lines to align the configuration approach across these three Core Web Vitals metrics, ensuring consistent change reporting behavior.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The title focuses on CLS but the changeset enables reportAllChanges for both INP and CLS metrics, making it incomplete. Update title to reflect all affected metrics: 'fix(web-vitals): report all changes for INP and CLS' or use a more general description.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description explains the intent to report metrics before hook registration, which relates to the changeset, though it contains a typo.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/CLS_reportallchanges

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/runtime/web-vitals/plugin.client.ts`:
- Around line 166-167: The CLS callback currently appends every metric update
with push(metric) while reportAllChanges: true, causing duplicates; change the
producer in src/runtime/web-vitals/plugin.client.ts to upsert metrics keyed by
metric.id (e.g., maintain a Map or object keyed by metric.id and replace the
entry on each callback) instead of push(metric), and update the consumer in
client/app/composables/host.ts to read the latest snapshot per metric.id
(iterate Map.values() or dedupe by id) so the DevTools sees only the current CLS
snapshot per metric instance.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 12e4362e-65ef-42b6-a0eb-1e9e632bb096

📥 Commits

Reviewing files that changed from the base of the PR and between 3648d65 and 5e9e768.

📒 Files selected for processing (1)
  • src/runtime/web-vitals/plugin.client.ts

Comment on lines +166 to +167
}, {
reportAllChanges: true,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== CLS producer =="
rg -n -C2 'onCLS|reportAllChanges|webvitals\.cls\.value\.push|callHook\(.*hints:webvitals:cls' src/runtime/web-vitals/plugin.client.ts

echo
echo "== CLS consumer/state =="
rg -n -C2 'hints:webvitals:cls|cls\.value\.push|metric\.id|delta|CLSMetricWithAttribution\[\]' \
  client/app/composables/host.ts \
  src/runtime/types.d.ts

Repository: nuxt/hints

Length of output: 2350


🌐 Web query:

web-vitals reportAllChanges metric.id documentation

💡 Result:

In the web-vitals library:

  • reportAllChanges is an option you pass as the 2nd argument to a metric function (e.g. onCLS(cb, opts)). When true, your callback is invoked whenever the metric value changes during the page lifespan (useful for debugging). It does not fire for every underlying input—only when the computed metric value increases/changes. Example: onCLS(console.log, { reportAllChanges: true }). [1]

  • metric.id is a unique string identifier for that specific metric instance. It’s intended for analytics systems to dedupe multiple reports for the same metric instance or group multiple delta updates to reconstruct totals. A new id can be created for the “same page” in cases like a back/forward cache restore (treated as a separate page visit). [1]
    (If you’re seeing this via Next.js useReportWebVitals, it exposes the same concept: id is “unique in the context of the current page load”.) [2]

Sources: [1] web-vitals README/API (GoogleChrome/web-vitals) (github.com), [2] Next.js useReportWebVitals docs (nextjs.org)

Citations:


Store CLS updates by metric.id instead of appending raw metrics once reportAllChanges is enabled.

With reportAllChanges: true, the web-vitals library invokes the CLS callback multiple times as the metric value changes during the page load. Each callback is assigned the same metric.id for the same instance; the library docs explicitly recommend using metric.id to deduplicate or group delta updates.

Currently, both producer (src/runtime/web-vitals/plugin.client.ts:133) and consumer (client/app/composables/host.ts:28) use append-only push(metric), so every CLS value change gets added as a separate entry in the array. This causes the DevTools to accumulate stale/duplicate CLS records and reprocess previously seen entries. Consider upserting the latest snapshot by metric.id or storing deltas instead of pushing raw metrics.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/runtime/web-vitals/plugin.client.ts` around lines 166 - 167, The CLS
callback currently appends every metric update with push(metric) while
reportAllChanges: true, causing duplicates; change the producer in
src/runtime/web-vitals/plugin.client.ts to upsert metrics keyed by metric.id
(e.g., maintain a Map or object keyed by metric.id and replace the entry on each
callback) instead of push(metric), and update the consumer in
client/app/composables/host.ts to read the latest snapshot per metric.id
(iterate Map.values() or dedupe by id) so the DevTools sees only the current CLS
snapshot per metric instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant