You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NextJS中配置Loadable Components的服务端渲染(SSR)?

在Next.js中配置Loadable Components实现SSR的问题

背景

我们在构建新的Next.js应用时,需要使用Loadable Components。虽然知道Next.js原生支持dynamic import,但现有成熟代码库中大量使用Loadable Components,替换为原生dynamic import成本太高,不现实。

问题复现

我创建了示例场景来演示问题,核心代码如下(在pages/index.tsx中通过Loadable拆分Layout组件):

import * as React from 'react';
import Link from 'next/link';
import loadable from '@loadable/component';

const LayoutLoadable = loadable(() => import('../components/Layout'));

const IndexPage = () => (
  <LayoutLoadable title="Home | Next.js + TypeScript Example">
    <h1>Hello Next.js 👋</h1>
    <p>
      <Link href="/about">
        <a>About</a>
      </Link>
    </p>
  </LayoutLoadable>
);

export default IndexPage;

运行命令:yarn && yarn dev(或等效npm命令)

访问http://localhost:3000/时,页面body仅包含根挂载div,SSR未正常工作:

<body>
    <div id="__next" data-reactroot=""></div>
    <script src="/_next/static/chunks/react-refresh.js?ts=1663916845500"></script>
    <script id="__NEXT_DATA__" type="application/json">
      {
        "props": { "pageProps": {} },
        "page": "/",
        "query": {},
        "buildId": "development",
        "nextExport": true,
        "autoExport": true,
        "isFallback": false,
        "scriptLoader": []
      }
    </script>
  </body>

不过客户端可以正常完成hydration并显示内容,说明客户端渲染逻辑是正常的。

如果改为普通导入Layout组件:

import * as React from 'react';
import Link from 'next/link';
import Layout from '../components/Layout';

const IndexPage = () => (
  <Layout title="Home | Next.js + TypeScript Example">
    <h1>Hello Next.js 👋</h1>
    <p>
      <Link href="/about">
        <a>About</a>
      </Link>
    </p>
  </Layout>
);

export default IndexPage;

则SSR正常工作,body包含完整渲染的HTML内容:

<body>
    <div id="__next" data-reactroot="">
      <div>
        <header>
          <nav>
            <a href="/">Home</a>
            <!-- --><!-- --><a href="/about">About</a>
            <!-- --><!-- --><a href="/users">Users List</a>
            <!-- --><!-- -->| <a href="/api/users">Users API</a>
          </nav>
        </header>
        <h1>Hello Next.js 👋</h1>
        <p><a href="/about">About</a></p>
        <footer>
          <hr />
          <span>I&#x27;m here to stay (Footer)</span>
        </footer>
      </div>
    </div>
    <script src="/_next/static/chunks/react-refresh.js?ts=1663917155976"></script>
    <script id="__NEXT_DATA__" type="application/json">
      {
        "props": { "pageProps": {} },
        "page": "/",
        "query": {},
        "buildId": "development",
        "nextExport": true,
        "autoExport": true,
        "isFallback": false,
        "scriptLoader": []
      }
    </script>
  </body>

已尝试的配置

我参考Loadable Components的SSR文档,在自定义_document.tsx中做了如下配置:

import Document, { Html, Head, Main, NextScript } from 'next/document';
import * as React from 'react';
import { ChunkExtractor } from '@loadable/server';
import path from 'path';

export default class AppDocument extends Document {
  render() {
    const statsFile = path.resolve('.next/loadable-stats.json');

    const chunkExtractor = new ChunkExtractor({
      statsFile,
    });

    return chunkExtractor.collectChunks(
      <Html>
        <Head />
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

但该配置未生效,推测原因是Next.js内部自行处理renderToString(jsx),导致无法在合适位置应用Loadable的SSR配置。

请问有没有人成功在Next.js中配置Loadable Components的SSR?我找不到正确的配置位置。


内容的提问来源于stack exchange,提问作者andrew_scfc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:10:20