Skip to content

fix(dashboards): resize drifting away from cursor on large dashboards#68679

Merged
MattPua merged 5 commits into
masterfrom
posthog-code/fix-dashboard-resize-drift
Jul 6, 2026
Merged

fix(dashboards): resize drifting away from cursor on large dashboards#68679
MattPua merged 5 commits into
masterfrom
posthog-code/fix-dashboard-resize-drift

Conversation

@MattPua

@MattPua MattPua commented Jul 6, 2026

Copy link
Copy Markdown
Member

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
  • Bump react-resizable 3.1.3 → 3.2.0 in the lockfile (transitive dep, already in range, no package.json change)
  • Memoize dashboard tile cards so only the tile being moved or resized re-renders on each mousemove, instead of every tile on the dashboard

How did you test this code?

  • hogli/jest and TypeScript checks pass; verified the 3.2.0 tarball contains the upstream fix
  • Needs a manual check on a big dashboard before marking ready (resize tracking, drag smoothness, charts still updating)

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

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

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
@MattPua MattPua self-assigned this Jul 6, 2026
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Hey @MattPua! 👋

It looks like your git author email on this PR isn't your @posthog.com address (matthewpua@gmail.com). Since you're on the PostHog team, it's worth pointing your local git author email at your @posthog.com address. Why it matters:

  • Consistent work identity in git history — internal tooling that attributes commits to team members keys off your @posthog.com address.
  • Keeps team contributions easy to tell apart from external community ones when scanning history.

You can fix it for this repo with:

git config user.email "you@posthog.com"

Or set it globally with git config --global user.email "you@posthog.com". No need to redo this PR — just a nudge for next time. 🙂

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Bundle size — no change

Uncompressed size of every built .js bundle, compared against the base branch.

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 budget

How 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 import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.20 MiB · 22 files no change ███░░░░░░░ 28.0% of 4.29 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
11.56 MiB · 2,948 files no change █████████░ 89.8% of 12.87 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
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%)

Playwright — all passed

All tests passed.

View test results →

MattPua added 2 commits July 6, 2026 11:24
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
@MattPua MattPua changed the base branch from master to posthog-code/bump-swc-core-provenance July 6, 2026 16:21
@MattPua MattPua requested a review from a team July 6, 2026 17:55
@MattPua MattPua marked this pull request as ready for review July 6, 2026 17:55
Comment thread frontend/src/scenes/dashboard/DashboardItems.tsx Outdated
@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(dashboards): restore flushPendingLay..." | Re-trigger Greptile

Comment thread frontend/src/scenes/dashboard/DashboardItems.tsx Outdated
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
Base automatically changed from posthog-code/bump-swc-core-provenance to master July 6, 2026 18:03
Generated-By: PostHog Code
Task-Id: 4d0808dc-4703-4fe7-b26e-4ece499fbb6d
@trunk-io

trunk-io Bot commented Jul 6, 2026

Copy link
Copy Markdown

Static BadgeStatic BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

@MattPua MattPua merged commit bffedb7 into master Jul 6, 2026
219 checks passed
@MattPua MattPua deleted the posthog-code/fix-dashboard-resize-drift branch July 6, 2026 18:54
@deployment-status-posthog

deployment-status-posthog Bot commented Jul 6, 2026

Copy link
Copy Markdown

Deploy status

Environment Status Deployed At Workflow
dev ✅ Deployed 2026-07-06 19:23 UTC Run
prod-us ✅ Deployed 2026-07-06 19:41 UTC Run
prod-eu ✅ Deployed 2026-07-06 19:47 UTC Run

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.

2 participants