Skip to content

Commit

Permalink
perf: keep document-drive state in shallowRef and prefetch pages/co…
Browse files Browse the repository at this point in the history
…mponents (#2118)
  • Loading branch information
danielroe committed Jun 27, 2023
1 parent d7bccdc commit b88cc2f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
8 changes: 4 additions & 4 deletions src/runtime/composables/content.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { withoutTrailingSlash } from 'ufo'
import type { NavItem, ParsedContent } from '../types'
import { computed, useState, useRoute } from '#imports'
import { computed, shallowReactive, shallowRef, useState, useRoute } from '#imports'

export const useContentState = () => {
/**
* Map of loaded pages.
*/
const pages = useState<Record<string, ParsedContent>>('dd-pages', () => ({}))
const pages = useState<Record<string, ParsedContent>>('dd-pages', () => shallowRef(shallowReactive({})))

/**
* Previous and next page data.
* Format: [prev, next]
*/
const surrounds = useState<Record<string, Omit<ParsedContent, 'body'>>>('dd-surrounds', () => ({}))
const surrounds = useState<Record<string, Omit<ParsedContent, 'body'>>>('dd-surrounds', () => shallowRef(shallowReactive({})))

/**
* Navigation tree from root of app.
Expand All @@ -23,7 +23,7 @@ export const useContentState = () => {
* Globally loaded content files.
* Format: { [key: string]: ParsedContent }
*/
const globals = useState<Record<string, ParsedContent>>('dd-globals', () => ({}))
const globals = useState<Record<string, ParsedContent>>('dd-globals', () => shallowRef(shallowReactive({})))

return {
pages,
Expand Down
42 changes: 39 additions & 3 deletions src/runtime/plugins/documentDriven.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router'
// @ts-ignore
import { withoutTrailingSlash, hasProtocol } from 'ufo'
import type { NavItem, ParsedContent } from '../types'
import { pascalCase } from 'scule'
import type { MarkdownNode, NavItem, ParsedContent } from '../types'
import type { ModuleOptions } from '../../module'
import { useContentState } from '../composables/content'
import { useContentHelpers } from '../composables/helpers'
import { fetchContentNavigation } from '../composables/navigation'
import { queryContent } from '../composables/query'
import { useRuntimeConfig, addRouteMiddleware, callWithNuxt, navigateTo, useRoute, defineNuxtPlugin } from '#app'
import { componentNames } from '#components'
import { useRuntimeConfig, addRouteMiddleware, callWithNuxt, navigateTo, useRoute, defineNuxtPlugin, prefetchComponents, useRouter } from '#app'
// @ts-ignore
import layouts from '#build/layouts'

Expand Down Expand Up @@ -251,6 +252,25 @@ export default defineNuxtPlugin((nuxt) => {
})
}

// Prefetch page content
if (process.client) {
const router = useRouter()
nuxt.hook('link:prefetch', (link) => {
if (!(link in pages.value) && !hasProtocol(link)) {
const route = router.resolve(link)
if (route.matched.length > 0) {
refresh(route)
}
}
})
// @ts-expect-error hook is not typed
nuxt.hooks.hook('content:document-driven:finish', ({ page }) => {
if (page?.body?.children) {
prefetchBodyComponents(page.body.children)
}
})
}

// Route middleware
addRouteMiddleware(async (to, from) => {
// TODO: Remove this (https://github.com/nuxt/framework/pull/5274)
Expand Down Expand Up @@ -284,3 +304,19 @@ export default defineNuxtPlugin((nuxt) => {
// @ts-ignore - Refresh on client-side
nuxt.hook('app:data:refresh', async () => process.client && await refresh(useRoute(), true))
})

function prefetchBodyComponents (nodes: MarkdownNode[]) {
for (const node of nodes) {
if (node.children) {
prefetchBodyComponents(node.children)
}
if (node.type === 'element' && node.tag) {
const el = pascalCase(node.tag)
for (const name of ['Prose' + el, el]) {
if (componentNames.includes(name)) {
prefetchComponents(name)
}
}
}
}
}

0 comments on commit b88cc2f

Please sign in to comment.