Skip to content

feat(ui): Keep stable references to lazy components #69740

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 26, 2024

Conversation

scttcper
Copy link
Member

@scttcper scttcper commented Apr 26, 2024

This pr pulls the lazy() call out of the render path.

In concurrent mode, a spinner is sometimes shown on route change even though the component has already been loaded. We should try to keep stable references to lazy(() => import('./whatever')); to benefit from the caching react lazy does and avoid the tick from .then() that is needed to resolve a fresh promise, even if webpack has cached the result already.

From the docs

Call lazy outside your components to declare a lazy-loaded React component:

example: go to the subscription page https://sentry.sentry.io/settings/billing/overview/ and flick between the tabs

before - spinner every time you switch tabs even after the component is loaded

CleanShot.2024-04-25.at.20.20.20.mp4

after - spinner or flicker only when the bundle is loaded the first time. this could be prefetched

CleanShot.2024-04-25.at.20.15.51.mp4

part of https://github.com/getsentry/frontend-tsc/issues/63

In concurrent mode a spinner is sometimes shown on route change even though the component has already been loaded. We should try to keep stable references to `lazy(() => import('./whatever'));` to benefit from the caching react lazy does and avoid the tick from .then() that is needed to resolve a fresh promise, even if webpack has cached the result already.

https://react.dev/reference/react/lazy

for an example spinner in concurrent mode go to the subscription page https://sentry.sentry.io/settings/billing/overview/ and flick between the tabs
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Apr 26, 2024
@@ -39,11 +40,12 @@ const SafeLazyLoad = errorHandler(LazyLoad);
export function makeLazyloadComponent<C extends React.ComponentType<any>>(
resolve: () => Promise<{default: C}>
) {
const LazyComponent = lazy<C>(() => retryableImport(resolve));
Copy link
Member Author

Choose a reason for hiding this comment

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

pulling this outside the RouteLazyLoad ensures that as long as makeLazyloadComponent isn't called multiple times this should be stable

@scttcper scttcper requested review from evanpurkhiser and a team April 26, 2024 16:26
@scttcper scttcper marked this pull request as ready for review April 26, 2024 16:26
@scttcper scttcper requested a review from a team as a code owner April 26, 2024 16:26
...props
}: Props<C>) {
const LazyComponent = useMemo(
() => lazy<C>(() => retryableImport(component)),
Copy link
Member Author

@scttcper scttcper Apr 26, 2024

Choose a reason for hiding this comment

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

this is what i'm trying to avoid, a new lazy() every time the component is mounted

Copy link
Member

@ryan953 ryan953 left a comment

Choose a reason for hiding this comment

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

const LazyComponent = lazy(() => import('./myComponent')) makes the most sense.

@scttcper scttcper merged commit 62642ab into master Apr 26, 2024
41 of 42 checks passed
@scttcper scttcper deleted the scttcper/stable-lazy-load branch April 26, 2024 18:36
scttcper added a commit that referenced this pull request Apr 26, 2024
final follow up to #69740 prefer stable references to lazy()
Copy link

sentry-io bot commented Apr 30, 2024

Suspect Issues

This pull request was deployed and Sentry observed the following issues:

  • ‼️ TypeError: Cannot read properties of undefined (reading 'results') Object.getNextPageParam(app/utils/queryClient) View Issue
  • ‼️ TypeError: Cannot read properties of undefined (reading '__ec_inner_36') /releases/:release/ View Issue
  • ‼️ TypeError: Cannot read properties of undefined (reading 'coord') /releases/:release/ View Issue
  • ‼️ TypeError: Cannot read properties of undefined (reading '__ec_inner_39') /releases/:release/ View Issue
  • ‼️ TypeError: Cannot read properties of undefined (reading 'results') /feedback/ View Issue

Did you find this useful? React with a 👍 or 👎

@github-actions github-actions bot locked and limited conversation to collaborators May 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants