Next.js Discord

Discord Forum

Dynamically imported components have a noticeable lag

Unanswered
Australian Freshwater Crocodile posted this in #help-forum
Open in Discord
Australian Freshwater CrocodileOP
I have a feeling that there's no way around it, but I want to make sure.

Whenever I dynamically import a component, let's say a modal that opens if a user clicks a button, it takes like a second, before it opens. I assume it's because it's downloading this chunk on demand, but is there a way to cache the already imported component, or any insight on eliminating this lag?

12 Replies

Is this in local dev or in production? does the component load any data internally?
Australian Freshwater CrocodileOP
dev, I built and served the app, but same behavior
some of them do, some are purely static
you can pass a loading prop to the dynamic import and see if a skeleton or some global loader ux would help bridge the user experience? https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#examples
Australian Freshwater CrocodileOP
I did pass a loading component to offset the delay, but when it's a button opening a modal for example, it's not ideal to display a loading imo.
Australian Freshwater CrocodileOP
I'm not sure how things work under the hood tbh. Like, when the user clicks on the button, does my browser download this resource on demand?
I assume this is so, cuz the whole point is to make first page load faster, but why doesn't it cache it so this delay disappears when the user clicks again?
next/dynamic is a composite of React.lazy and Suspense under the hood. It should cache it (ie after the first click the interaction should be instantaneous - we use this strategy with @shadcn modals - facing a similar challenge on the initial pass through, however consecutive opens are instanteneous, which indicates that it caches that bundle
Australian Freshwater CrocodileOP
Do you have any idea what this problem might be? I will include a snippet of how I import the component
  const MainContactModal = dynamic(
    () => import('@/app/(private)/company/(Users)/MainContactModal'),
    { ssr: false }
  );
  const UserDetailsModal = dynamic(
    () => import('./UserDetailsModal').then((mod) => mod.UserDetailsModal),
    { ssr: false }
  );
  const InviteUserModal = dynamic(
    () => import('./InviteUserModal').then((mod) => mod.InviteUserModal),
    { ssr: false }
  );
...
...
<InviteUserModal
        isOpen={isUserModalOpen}
        loading={loading || invitationLoading}
        onCancel={toggleUserModal}
        onConfirm={onInviteUserClicked}
        members={members}
      />
      <UserDetailsModal
        isOpen={isUserDetailsModalOpen && !isEmpty(selectedUser)}
        user={selectedUser}
        attorneyIds={attorneyIds}
        onClose={toggleUserDetailsModal}
        isKycSubmitted={isKycSubmitted}
      />

      <MainContactModal
        loading={updateContactLoading}
        isOpen={isMainContactModalOpen}
        user={selectedUser}
        onClose={toggleMainContactModal}
        onConfirm={onConfirmMainContact}
      />
Australian Freshwater CrocodileOP
@sergiy.eth FYI, it was because I was dynamically importing components inside client components not server ones
sick! glad you figured it out