---
title: Lazy Loading
description: Configure lazy loading on collection outputs.
---

## Introduction

By default, all Markdown and MDX files need to be pre-compiled first. The same constraint also applies to the development server.

This may result in longer dev server start times for large docs sites. You can enable Async or Dynamic mode on doc collections to improve this.

## Async Mode

Async mode will generate collection outputs using async imports.

```ts tab="Docs Collection"
import { defineDocs } from 'fumadocs-mdx/config';

export const docs = defineDocs({
  dir: 'content/docs',
  docs: {
    // [!code ++]
    async: true,
  },
});
```

```ts tab="Doc Collection"
import { defineCollections } from 'fumadocs-mdx/config';

export const doc = defineCollections({
  type: 'doc',
  dir: 'content/docs',
  // [!code ++]
  async: true,
});
```

Depending on your bundler, this may reduce compilation time significantly on development server.

<Callout title="For Next.js">
  Turbopack doesn't support lazy bundling at the moment, async mode will only improve server
  performance.
</Callout>

## Dynamic Mode

Dynamic mode works by performing **on-demand compilation**, then execute the output on runtime.

It is recommended to install & externalize `shiki`:

```npm
npm i shiki
```

Enable dynamic mode in collections like:

```ts tab="Docs Collection"
import { defineDocs } from 'fumadocs-mdx/config';

export const docs = defineDocs({
  dir: 'content/docs',
  docs: {
    // [!code ++]
    dynamic: true,
  },
});
```

```ts tab="Doc Collection"
import { defineCollections } from 'fumadocs-mdx/config';

export const doc = defineCollections({
  type: 'doc',
  dir: 'content/docs',
  // [!code ++]
  dynamic: true,
});
```

Then, follow [Dynamic Entry](/docs/mdx/entry/dynamic) to access the collection from dynamic entry instead.

<Callout title="Constraints" type='warn'>

Dynamic mode comes with some limitations on MDX features.

- **No import/export allowed in MDX files.** For MDX components, pass them from the `components` prop instead.
- **Images must be referenced with URL (e.g. `/images/test.png`).** Don't use **file paths** like `./image.png`. You should locate your images in the `public` folder and reference them with URLs.

</Callout>

## Usage

Frontmatter properties are still available on `page` object, but you need to invoke the `load()` async function to load the compiled content (and its exports).

For example:

```tsx title="page.tsx"
import { source } from '@/lib/source';
import { getMDXComponents } from '@/components/mdx';

const page = source.getPage(['...']);

if (page) {
  // frontmatter properties are available
  console.log(page.data);

  // Markdown content requires await
  const { body: MdxContent, toc } = await page.data.load();

  console.log(toc);

  return <MdxContent components={getMDXComponents()} />;
}
```

When using Async or Dynamic mode, we highly recommend to use third-party services to implement search, which usually have better capability to handle massive amount of content to index.
