Skip to content

Fix bugs in lazy and stabilize it#1900

Open
marshallku wants to merge 8 commits intomainfrom
feat/stable-lazy
Open

Fix bugs in lazy and stabilize it#1900
marshallku wants to merge 8 commits intomainfrom
feat/stable-lazy

Conversation

@marshallku
Copy link
Copy Markdown
Collaborator

Overview

Fixed several bugs in lazy and removed the @experimental tag to mark it as stable.

Additional features I'm currently working on:

  • Allow lazy to return a specific component as fallback
  • Implement useLazy hook

These are considered feature additions rather than stabilization work, so they will be handled in separate PRs.

PR Checklist

  • I did below actions if need
  1. I read the Contributing Guide
  2. I added documents and tests.

@marshallku marshallku self-assigned this Feb 2, 2026
@coauthors
Copy link
Copy Markdown

coauthors Bot commented Feb 2, 2026

People can be co-author:

Candidate Reasons Count Add this as commit message
@marshallku #1900 (comment) #1900 (comment) #1900 (comment) #1900 (comment) #1900 (review) #1900 (review) #1900 (review) #1900 (review) #1900 9 Co-authored-by: marshallku <33550065+marshallku@users.noreply.github.com>
@manudeli #1900 (comment) #1900 (comment) #1900 (comment) #1900 (review) #1900 (review) #1900 (review) 6 Co-authored-by: manudeli <61593290+manudeli@users.noreply.github.com>
@codecov-commenter #1900 (comment) 1 Co-authored-by: codecov-commenter <65553080+codecov-commenter@users.noreply.github.com>

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Feb 2, 2026

🦋 Changeset detected

Latest commit: 1733815

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@suspensive/react Minor
@suspensive/react-query Minor
@suspensive/react-query-4 Minor
@suspensive/react-query-5 Minor
@suspensive/jotai Minor
@suspensive/codemods Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Feb 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
suspensive-next-streaming-react-query Ready Ready Preview, Comment Apr 3, 2026 8:00am
v2.suspensive.org Ready Ready Preview, Comment Apr 3, 2026 8:00am
v3.suspensive.org Ready Ready Preview, Comment Apr 3, 2026 8:00am
visualization.suspensive.org Ready Ready Preview, Comment Apr 3, 2026 8:00am

Request Review

Comment thread packages/react/src/lazy.ts Outdated
}

const loadNoReturn = () => load().then(noop)
const loadNoReturn = Object.assign(() => load().then(noop), { toString: () => load.toString() })
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

We check the loading state of a component using Function.toString(), but it always returns the same value when the function is set like load().then(noop).

const reloadCount = parseInt(storedValue, 10)
if (Number.isNaN(reloadCount)) reloadStorage.removeItem(storageKey)
currentRetryCount = reloadCount
if (Number.isNaN(reloadCount)) {
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

NaN was silently killing lazy

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Feb 2, 2026

Size Change: -147 B (-0.24%)

Total Size: 59.9 kB

Filename Size Change
packages/react/dist/lazy.cjs 1.97 kB -74 B (-3.62%)
packages/react/dist/lazy.mjs 1.9 kB -73 B (-3.69%)
ℹ️ View Unchanged
Filename Size
packages/jotai/dist/Atom.cjs 317 B
packages/jotai/dist/Atom.mjs 249 B
packages/jotai/dist/AtomValue.cjs 305 B
packages/jotai/dist/AtomValue.mjs 236 B
packages/jotai/dist/index.cjs 174 B
packages/jotai/dist/index.mjs 88 B
packages/jotai/dist/SetAtom.cjs 303 B
packages/jotai/dist/SetAtom.mjs 234 B
packages/next/dist/index.cjs 305 B
packages/next/dist/index.mjs 250 B
packages/next/dist/react-******.cjs 268 B
packages/next/dist/react-******.mjs 213 B
packages/react-query-4/dist/createGetQueryClient.cjs 1.09 kB
packages/react-query-4/dist/createGetQueryClient.mjs 1.01 kB
packages/react-query-4/dist/index.cjs 446 B
packages/react-query-4/dist/index.mjs 298 B
packages/react-query-4/dist/infiniteQueryOptions.cjs 357 B
packages/react-query-4/dist/infiniteQueryOptions.mjs 292 B
packages/react-query-4/dist/IsFetching.cjs 491 B
packages/react-query-4/dist/IsFetching.mjs 413 B
packages/react-query-4/dist/Mutation.cjs 412 B
packages/react-query-4/dist/Mutation.mjs 332 B
packages/react-query-4/dist/mutationOptions.cjs 187 B
packages/react-query-4/dist/mutationOptions.mjs 134 B
packages/react-query-4/dist/PrefetchInfiniteQuery.cjs 463 B
packages/react-query-4/dist/PrefetchInfiniteQuery.mjs 387 B
packages/react-query-4/dist/PrefetchQuery.cjs 453 B
packages/react-query-4/dist/PrefetchQuery.mjs 379 B
packages/react-query-4/dist/QueriesHydration.cjs 1.66 kB
packages/react-query-4/dist/QueriesHydration.mjs 1.56 kB
packages/react-query-4/dist/QueryClientConsumer.cjs 353 B
packages/react-query-4/dist/QueryClientConsumer.mjs 277 B
packages/react-query-4/dist/queryOptions.cjs 353 B
packages/react-query-4/dist/queryOptions.mjs 286 B
packages/react-query-4/dist/SuspenseInfiniteQuery.cjs 668 B
packages/react-query-4/dist/SuspenseInfiniteQuery.mjs 580 B
packages/react-query-4/dist/SuspenseQueries.cjs 569 B
packages/react-query-4/dist/SuspenseQueries.mjs 483 B
packages/react-query-4/dist/SuspenseQuery.cjs 654 B
packages/react-query-4/dist/SuspenseQuery.mjs 568 B
packages/react-query-4/dist/usePrefetchInfiniteQuery.cjs 462 B
packages/react-query-4/dist/usePrefetchInfiniteQuery.mjs 395 B
packages/react-query-4/dist/usePrefetchQuery.cjs 452 B
packages/react-query-4/dist/usePrefetchQuery.mjs 388 B
packages/react-query-4/dist/useSuspenseInfiniteQuery.cjs 375 B
packages/react-query-4/dist/useSuspenseInfiniteQuery.mjs 305 B
packages/react-query-4/dist/useSuspenseQueries.cjs 368 B
packages/react-query-4/dist/useSuspenseQueries.mjs 299 B
packages/react-query-4/dist/useSuspenseQuery.cjs 365 B
packages/react-query-4/dist/useSuspenseQuery.mjs 298 B
packages/react-query-5/dist/createGetQueryClient.cjs 1.09 kB
packages/react-query-5/dist/createGetQueryClient.mjs 1.01 kB
packages/react-query-5/dist/index.cjs 438 B
packages/react-query-5/dist/index.mjs 294 B
packages/react-query-5/dist/infiniteQueryOptions.cjs 352 B
packages/react-query-5/dist/infiniteQueryOptions.mjs 286 B
packages/react-query-5/dist/IsFetching.cjs 445 B
packages/react-query-5/dist/IsFetching.mjs 366 B
packages/react-query-5/dist/Mutation.cjs 412 B
packages/react-query-5/dist/Mutation.mjs 332 B
packages/react-query-5/dist/mutationOptions.cjs 350 B
packages/react-query-5/dist/mutationOptions.mjs 284 B
packages/react-query-5/dist/PrefetchInfiniteQuery.cjs 466 B
packages/react-query-5/dist/PrefetchInfiniteQuery.mjs 391 B
packages/react-query-5/dist/PrefetchQuery.cjs 459 B
packages/react-query-5/dist/PrefetchQuery.mjs 383 B
packages/react-query-5/dist/QueriesHydration.cjs 1.66 kB
packages/react-query-5/dist/QueriesHydration.mjs 1.56 kB
packages/react-query-5/dist/QueryClientConsumer.cjs 351 B
packages/react-query-5/dist/QueryClientConsumer.mjs 276 B
packages/react-query-5/dist/queryOptions.cjs 347 B
packages/react-query-5/dist/queryOptions.mjs 281 B
packages/react-query-5/dist/SuspenseInfiniteQuery.cjs 668 B
packages/react-query-5/dist/SuspenseInfiniteQuery.mjs 580 B
packages/react-query-5/dist/SuspenseQueries.cjs 585 B
packages/react-query-5/dist/SuspenseQueries.mjs 498 B
packages/react-query-5/dist/SuspenseQuery.cjs 645 B
packages/react-query-5/dist/SuspenseQuery.mjs 558 B
packages/react-query-5/dist/usePrefetchInfiniteQuery.cjs 367 B
packages/react-query-5/dist/usePrefetchInfiniteQuery.mjs 300 B
packages/react-query-5/dist/usePrefetchQuery.cjs 364 B
packages/react-query-5/dist/usePrefetchQuery.mjs 294 B
packages/react-query-5/dist/useSuspenseInfiniteQuery.cjs 368 B
packages/react-query-5/dist/useSuspenseInfiniteQuery.mjs 299 B
packages/react-query-5/dist/useSuspenseQueries.cjs 363 B
packages/react-query-5/dist/useSuspenseQueries.mjs 294 B
packages/react-query-5/dist/useSuspenseQuery.cjs 359 B
packages/react-query-5/dist/useSuspenseQuery.mjs 292 B
packages/react-query/dist/index.cjs 383 B
packages/react-query/dist/index.mjs 201 B
packages/react-query/dist/v4.cjs 383 B
packages/react-query/dist/v4.mjs 201 B
packages/react-query/dist/v5.cjs 383 B
packages/react-query/dist/v5.mjs 201 B
packages/react/dist/ClientOnly.cjs 606 B
packages/react/dist/ClientOnly.mjs 536 B
packages/react/dist/DefaultProps.cjs 968 B
packages/react/dist/DefaultProps.mjs 901 B
packages/react/dist/Delay.cjs 985 B
packages/react/dist/Delay.mjs 906 B
packages/react/dist/ErrorBoundary.cjs 2.1 kB
packages/react/dist/ErrorBoundary.mjs 2.04 kB
packages/react/dist/ErrorBoundaryGroup.cjs 1.11 kB
packages/react/dist/ErrorBoundaryGroup.mjs 1.04 kB
packages/react/dist/index.cjs 342 B
packages/react/dist/index.mjs 229 B
packages/react/dist/Suspense.cjs 801 B
packages/react/dist/Suspense.mjs 716 B
packages/react/dist/useIsClient.cjs 295 B
packages/react/dist/useIsClient.mjs 233 B

compressed-size-action

Comment thread packages/react/src/lazy.ts Outdated
}

const loadNoReturn = () => load().then(noop)
const loadNoReturn = Object.assign(() => load().then(noop), { toString: () => load.toString() })
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
const loadNoReturn = Object.assign(() => load().then(noop), { toString: () => load.toString() })
const loadNoReturn = load

Then How about this? We can just pass load directly too.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

load actually returns a value, so it'll break type system.

Copy link
Copy Markdown
Member

@manudeli manudeli Feb 5, 2026

Choose a reason for hiding this comment

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

it'll break type system.

But it's not BREAKING CHANGE because lazy was an experimental interface yet. so I want you just care about which one is better implementation

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@marshallku re-alert you

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I just simplified it!

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Feb 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.05%. Comparing base (568b4c5) to head (e037282).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1900   +/-   ##
=======================================
  Coverage   94.04%   94.05%           
=======================================
  Files          41       41           
  Lines         655      656    +1     
  Branches      166      167    +1     
=======================================
+ Hits          616      617    +1     
  Misses         36       36           
  Partials        3        3           
Components Coverage Δ
@suspensive/react 100.00% <100.00%> (ø)
@suspensive/react-query 100.00% <ø> (ø)
@suspensive/react-query-4 100.00% <ø> (ø)
@suspensive/react-query-5 100.00% <ø> (ø)
@suspensive/jotai 100.00% <ø> (ø)
@suspensive/codemods 81.60% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants