ContentLayer:在Next.js上优化GetStaticProps
#javascript #node #nextjs #markdown

TL:DR

删除在getStaticProps上不呈现的不必要数据。

为什么?

当您将ContentLayer数据传递到Next.js的getStaticProps时,默认情况下将包括RAW MARKDOWN,这是多余的,对于负载速度是不好的。

import { allPosts, Post } from 'contentlayer/generated';

export async function getStaticProps() {
  const posts: Post[] = allPosts;
  return {
    props: {
      posts,
    }
  };
}

html结果。

<script id="__NEXT_DATA__" type="application/json">
  {
    "props": {
      "pageProps": {
        "posts": [
          {
            "title": "Change me!",
            "date": "2022-03-11T00:00:00.000Z",
            "body": {
              "raw": "\nWhen you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen.\n",
              "html": "<p>When you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen.</p>"
            },
            "_id": "change-me.md",
            "_raw": {
              "sourceFilePath": "change-me.md",
              "sourceFileName": "change-me.md",
              "sourceFileDir": ".",
              "contentType": "markdown",
              "flattenedPath": "change-me"
            },
            "type": "Post",
            "url": "/posts/change-me"
          },
          {
            "title": "Click me!",
            "date": "2022-02-28T00:00:00.000Z",
            "body": {
              "raw": "\nBlog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer.\n",
              "html": "<p>Blog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer.</p>"
            },
            "_id": "click-me.md",
            "_raw": {
              "sourceFilePath": "click-me.md",
              "sourceFileName": "click-me.md",
              "sourceFileDir": ".",
              "contentType": "markdown",
              "flattenedPath": "click-me"
            },
            "type": "Post",
            "url": "/posts/click-me"
          },
          {
            "title": "What is Contentlayer?",
            "date": "2022-02-22T00:00:00.000Z",
            "body": {
              "raw": "\n**Contentlayer makes working with content easy.** It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application.\n",
              "html": "<p><strong>Contentlayer makes working with content easy.</strong> It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application.</p>"
            },
            "_id": "what-is-contentlayer.md",
            "_raw": {
              "sourceFilePath": "what-is-contentlayer.md",
              "sourceFileName": "what-is-contentlayer.md",
              "sourceFileDir": ".",
              "contentType": "markdown",
              "flattenedPath": "what-is-contentlayer"
            },
            "type": "Post",
            "url": "/posts/what-is-contentlayer"
          }
        ]
      },
      "__N_SSG": true
    },
    "page": "/",
    "query": {},
    "buildId": "lJqgQzHmHoKqCJDQ-Nldm",
    "isFallback": false,
    "gsp": true,
    "scriptLoader": []
  }
</script>

优化

克隆数据 1 并删除不必要的东西。

import { allPosts, Post } from 'contentlayer/generated';

export async function getStaticProps() {
  const posts: Post[] = allPosts.map((post) => {
    const copy = structuredClone(post);
    copy.body.raw = "";
    copy._raw.sourceFilePath = "";
    copy._raw.sourceFileName = "";
    copy._raw.sourceFileDir = "";
    copy._raw.flattenedPath = "";
    return copy;
  });
  return {
    props: {
      posts,
    }
  };
}

为什么要克隆?

contentlayer使用真实json的单一来源,修改数据可能会在两个或更多位置上需要一个数据时导致种族条件。

single source of truth diagram

html结果。

<script id="__NEXT_DATA__" type="application/json">
  {
    "props": {
      "pageProps": {
        "posts": [
          {
            "title": "Change me!",
            "date": "2022-03-11T00:00:00.000Z",
            "body": {
              "raw": "",
              "html": "<p>When you change a source file, Contentlayer automatically updates the content cache, which prompts Next.js to reload the content on screen.</p>"
            },
            "_id": "change-me.md",
            "_raw": {
              "sourceFilePath": "",
              "sourceFileName": "",
              "sourceFileDir": "",
              "contentType": "markdown",
              "flattenedPath": ""
            },
            "type": "Post",
            "url": "/posts/change-me"
          },
          {
            "title": "Click me!",
            "date": "2022-02-28T00:00:00.000Z",
            "body": {
              "raw": "",
              "html": "<p>Blog posts have their own pages. The content source is a markdown file, parsed to HTML by Contentlayer.</p>"
            },
            "_id": "click-me.md",
            "_raw": {
              "sourceFilePath": "",
              "sourceFileName": "",
              "sourceFileDir": "",
              "contentType": "markdown",
              "flattenedPath": ""
            },
            "type": "Post",
            "url": "/posts/click-me"
          },
          {
            "title": "What is Contentlayer?",
            "date": "2022-02-22T00:00:00.000Z",
            "body": {
              "raw": "",
              "html": "<p><strong>Contentlayer makes working with content easy.</strong> It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application.</p>"
            },
            "_id": "what-is-contentlayer.md",
            "_raw": {
              "sourceFilePath": "",
              "sourceFileName": "",
              "sourceFileDir": "",
              "contentType": "markdown",
              "flattenedPath": ""
            },
            "type": "Post",
            "url": "/posts/what-is-contentlayer"
          }
        ]
      },
      "__N_SSG": true
    },
    "page": "/",
    "query": {},
    "buildId": "toHJpUjQDJpnE6IPRFO4s",
    "isFallback": false,
    "gsp": true,
    "scriptLoader": []
  }
</script>

  1. structuredClone() - Web APIs | MDN