Skip to content

fix(web): Safari work items crash from requestIdleCallback#8975

Open
rbshh wants to merge 4 commits intomakeplane:previewfrom
rbshh:preview
Open

fix(web): Safari work items crash from requestIdleCallback#8975
rbshh wants to merge 4 commits intomakeplane:previewfrom
rbshh:preview

Conversation

@rbshh
Copy link
Copy Markdown
Contributor

@rbshh rbshh commented Apr 29, 2026

Description

RenderIfVisible calls window.requestIdleCallback when recording row heights after visible render. Safari (+WebKit) lacks this API.

A polyfill existed in core/lib/polyfills/index.ts but was never imported, so the runtime still threw.

Changes

  • Import client polyfills from entry.client.tsx before hydration.
  • Export scheduleIdleCallback() that applies the idle polyfill idempotently and delegates.
  • Replace direct window.requestIdleCallback usage in render-if-visible-HOC.tsx with scheduleIdleCallback.
  • Fix incorrect typeof window !== undefined check (use "undefined").

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

image

Test Scenarios

  • Open a project Work Items /{WORKSPACE/projects/{PROJECT_ID}/issues/ on Safari (or WebKit without requestIdleCallback).
  • Scroll and expand rows; confirm no console error and layout still correct.

References

Closes #8904
Closes #8871
Related to #5689 (the original polyfill PR — this completes its intent for lazy-loaded chunks)

Could be duplicate of PR #8937

Summary by CodeRabbit

  • Refactor
    • Initialize polyfills during client startup to improve browser compatibility.
    • Unify idle-callback scheduling across render paths to defer visibility updates and placeholder measurements, reducing main-thread work and smoothing rendering.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

📝 Walkthrough

Walkthrough

Polyfill initialization for requestIdleCallback/cancelIdleCallback was centralized into a reusable helper (scheduleIdleCallback) and imported at client startup; the render-if-visible HOC now uses this helper, adjusts its IntersectionObserver gating and cleanup, and tweaks effect dependencies.

Changes

Cohort / File(s) Summary
Polyfill Infrastructure
apps/web/core/lib/polyfills/index.ts
Adds ensureRequestIdleCallbackPolyfilled() and exports scheduleIdleCallback(callback, options) which idempotently installs polyfills and safely schedules idle callbacks (returns 0 on SSR).
Client Startup
apps/web/app/entry.client.tsx
Imports the polyfills module before calling startTransition/hydrateRoot so polyfills are available during client startup.
Component Integration
apps/web/core/components/core/render-if-visible-HOC.tsx
Replaces direct window.requestIdleCallback usage with scheduleIdleCallback; changes IntersectionObserver gating to typeof window !== "undefined" && useIdletime, removes children from effect deps, and simplifies observer cleanup to disconnect().

Sequence Diagram(s)

sequenceDiagram
    participant ClientEntry as Client Entry
    participant Polyfill as scheduleIdleCallback (polyfills)
    participant Browser as Browser Window
    participant HOC as RenderIfVisible HOC

    ClientEntry->>Polyfill: import (ensure polyfills installed)
    Polyfill->>Browser: install requestIdleCallback / cancelIdleCallback if missing
    ClientEntry->>Browser: startTransition / hydrateRoot

    HOC->>Polyfill: scheduleIdleCallback(callback, options)
    Polyfill->>Browser: forward to window.requestIdleCallback or noop (SSR)
    Browser-->>HOC: idle callback invoked
    HOC-->>Browser: IntersectionObserver observes element
    Browser-->>HOC: intersection events -> HOC schedules idle work via polyfill
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped in at boot with a cheer,
tucked polyfills gently near my ear.
I wait for idle, then give a nudge,
so renders wake without a grudge.
A little hop, performance clear. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main issue: fixing a Safari crash caused by the missing requestIdleCallback API.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description is comprehensive and includes all required template sections with detailed information about changes, type of change, test scenarios, and references to related issues.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown
Contributor

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/core/components/core/render-if-visible-HOC.tsx (1)

50-76: ⚠️ Potential issue | 🟡 Minor

Add useIdletime to the observer effect dependencies.

useIdletime is read in Line 55, but it’s missing from the dependency array in Line 76. If that prop toggles at runtime, observer behavior can stay stale.

💡 Suggested fix
-  }, [intersectionRef, children, root, verticalOffset, horizontalOffset]);
+  }, [intersectionRef, children, root, verticalOffset, horizontalOffset, useIdletime]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/core/components/core/render-if-visible-HOC.tsx` around lines 50 -
76, The effect in useEffect that creates the IntersectionObserver reads the
useIdletime variable but does not include it in the dependency array; update the
dependency array for that effect (the useEffect that references intersectionRef,
children, root, verticalOffset, horizontalOffset) to also include useIdletime so
changes to useIdletime will recreate the observer and ensure
scheduleIdleCallback/setShouldVisible behavior stays in sync.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@apps/web/core/components/core/render-if-visible-HOC.tsx`:
- Around line 50-76: The effect in useEffect that creates the
IntersectionObserver reads the useIdletime variable but does not include it in
the dependency array; update the dependency array for that effect (the useEffect
that references intersectionRef, children, root, verticalOffset,
horizontalOffset) to also include useIdletime so changes to useIdletime will
recreate the observer and ensure scheduleIdleCallback/setShouldVisible behavior
stays in sync.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 473b3685-585e-46ec-a97e-9a6c5ba638fb

📥 Commits

Reviewing files that changed from the base of the PR and between a62fe8a and 56de1f7.

📒 Files selected for processing (3)
  • apps/web/app/entry.client.tsx
  • apps/web/core/components/core/render-if-visible-HOC.tsx
  • apps/web/core/lib/polyfills/index.ts

Copy link
Copy Markdown
Contributor

@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 `@apps/web/core/components/core/render-if-visible-HOC.tsx`:
- Line 77: The effect that creates the IntersectionObserver (the useEffect
associated with intersectionRef and variables root, verticalOffset,
horizontalOffset, useIdletime) incorrectly includes children in its dependency
array causing unnecessary re-creation; remove children from the dependency list
so the observer only depends on intersectionRef, root, verticalOffset,
horizontalOffset, and useIdletime (or add an eslint-disable-next-line comment if
a linter complains) and ensure the observer creation/cleanup logic in the same
function remains unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d95ce9a9-4dd3-4de4-a793-d06d5c73ae9a

📥 Commits

Reviewing files that changed from the base of the PR and between 56de1f7 and 1114484.

📒 Files selected for processing (2)
  • apps/web/core/components/core/render-if-visible-HOC.tsx
  • apps/web/core/lib/polyfills/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/core/lib/polyfills/index.ts

Comment thread apps/web/core/components/core/render-if-visible-HOC.tsx Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@rbshh
Copy link
Copy Markdown
Contributor Author

rbshh commented Apr 30, 2026

@sriramveeraghanta can we prioritize this? I believe it's a something critical for Safari Users.

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.

[bug]: WebKit-based browser Kanban view crash. [bug]: Board view occurs error, which then prevents me from accessing Issues at all (Safari only)

1 participant