fix(dashboards): resize drifting away from cursor on large dashboards#68679
Conversation
On large dashboards, resizing a tile drifts progressively away from the cursor. react-resizable computes each resize step from props.width, which goes stale when React can't re-render between mousemove events, silently dropping deltas. Fixed upstream in 3.2.0 (react-grid-layout/react-resizable#255) by basing the calculation on the internally tracked lastSize. Transitive dep of react-grid-layout@2.2.3 (^3.1.3), so lockfile-only. Edited by hand because pnpm update re-resolves the workspace and trips trustPolicy on the unrelated @swc/core@1.11.4; validated with pnpm install --lockfile-only. Generated-By: PostHog Code Task-Id: 4d0808dc-4703-4fe7-b26e-4ece499fbb6d
|
Hey @MattPua! 👋 It looks like your git author email on this PR isn't your
You can fix it for this repo with: git config user.email "you@posthog.com"Or set it globally with |
🤖 CI report✅ Bundle size — no changeUncompressed size of every built Total: 76.96 MiB · no change No file changed by more than 1000 B. Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report ✅ Eager graph — within budgetHow much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy
🟢 Largest files eagerly shipped from
|
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 668 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 458.3 KiB | ../node_modules/.pnpm/@posthog+brand@0.3.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/driving-hogzilla.mjs |
| 302.9 KiB | ../node_modules/.pnpm/@posthog+brand@0.3.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/coffee-run.mjs |
| 275.2 KiB | ../node_modules/.pnpm/posthog-js@1.396.6/node_modules/posthog-js/dist/rrweb.js |
| 266.9 KiB | ../node_modules/.pnpm/@posthog+icons@0.37.4_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 253.2 KiB | ../node_modules/.pnpm/@posthog+brand@0.3.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/chart-hog.mjs |
| 239.2 KiB | ../node_modules/.pnpm/@posthog+brand@0.3.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/x-ray.mjs |
| 224.6 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 211.9 KiB | ../node_modules/.pnpm/posthog-js@1.396.6/node_modules/posthog-js/dist/module.js |
| 211.6 KiB | ../node_modules/.pnpm/@posthog+brand@0.3.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/money.mjs |
| 185.9 KiB | ../node_modules/.pnpm/@posthog+brand@0.3.0_react@18.3.1/node_modules/@posthog/brand/dist/generated/hoggies/svg/hogpatch.mjs |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Dist folder size — 🟢 -100.43 MiB (-6.4%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1465.42 MiB · 🟢 -100.43 MiB (-6.4%)
react-grid-layout re-renders every grid child on each drag/resize mousemove, cloning it with a fresh style object and fresh resize-handle children even for tiles that haven't moved. Memoize the four tile card components with a comparator that compares style by value and ignores handle identity, so untouched tiles bail out of the per-frame re-render. Cuts gesture render cost from all tiles to just the moving ones, which is what keeps large dashboards tracking the cursor. kea-driven updates inside the cards are unaffected, since memo only gates parent-driven renders. Generated-By: PostHog Code Task-Id: 4d0808dc-4703-4fe7-b26e-4ece499fbb6d
…utofix The repo-wide format run's oxlint --fix-dangerously rewrote the useCallback deps to include containerRef.current expressions, which fails typechecking (containerRef.current is possibly null) and got committed unnoticed. Restore the original [updateLayouts] deps. Generated-By: PostHog Code Task-Id: 4d0808dc-4703-4fe7-b26e-4ece499fbb6d
|
Reviews (1): Last reviewed commit: "fix(dashboards): restore flushPendingLay..." | Re-trigger Greptile |
Same behavior, less code: collapse the key loop into a single every() expression and drop the double casts on the memo wrappers. Generated-By: PostHog Code Task-Id: 4d0808dc-4703-4fe7-b26e-4ece499fbb6d
Generated-By: PostHog Code Task-Id: 4d0808dc-4703-4fe7-b26e-4ece499fbb6d
Problem
On big dashboards, resizing a tile drifts further and further from the mouse cursor as you drag. Small dashboards are fine.
The bug is upstream in react-resizable (used by react-grid-layout): when the grid is heavy, React can't re-render between mousemove events, so resize steps get computed from stale sizes and mouse movement is silently lost. Fixed upstream in 3.2.0 (react-resizable#237, #255).
Changes
Before:
CleanShot.2026-07-06.at.13.51.24.mp4
After:
CleanShot.2026-07-06.at.13.51.07.mp4
How did you test this code?
Automatic notifications
Docs update
None needed.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Authored with Claude Code. Root-caused by reading react-grid-layout/react-resizable internals and matching against upstream issues; ruled out CSS transforms, zoom mode, and scroll offset math along the way.
🤖 Generated with Claude Code