refactor: uses unhead/server to optimize head#464
Open
Barbapapazes wants to merge 1 commit into
Open
Conversation
Member
|
can you check adding |
Author
in addition to the current change? |
Member
|
I think we don't need to switch to unhead server, |
This comment was marked as off-topic.
This comment was marked as off-topic.
Author
|
The usage of |
Author
Side note to remove JSDOM
diff --git a/src/node/build.ts b/src/node/build.ts
index dd05ce6..4c994ab 100644
--- a/src/node/build.ts
+++ b/src/node/build.ts
@@ -10,7 +10,7 @@ import fs from 'node:fs/promises'
import { dirname, isAbsolute, join, parse, resolve } from 'node:path'
import process from 'node:process'
import { pathToFileURL } from 'node:url'
-import { transformHtmlTemplate } from '@unhead/vue/server'
+import { createHead, transformHtmlTemplate, VueHeadClient } from '@unhead/vue/server'
import { blue, cyan, dim, gray, green, red } from 'ansis'
import { JSDOM } from 'jsdom'
import PQueue from 'p-queue'
@@ -177,26 +177,20 @@ export async function build(ssgOptions: Partial<ViteSSGOptions> = {}, viteConfig
initialState: transformState(initialState),
})
- // create jsdom from renderedHTML
- const jsdom = new JSDOM(renderedHTML)
-
// render current page's preloadLinks
- renderPreloadLinks(jsdom.window.document, ctx.modules || new Set<string>(), ssrManifest)
+ const links = renderPreloadLinks(ctx.modules || new Set<string>(), ssrManifest)
+ const vueHead = head || createHead() as VueHeadClient
+ vueHead.push({
+ link: links,
+ })
+ const html = await transformHtmlTemplate(vueHead, renderedHTML)
- const html = jsdom.serialize()
let transformed = (await onPageRendered?.(route, html, appCtx)) || html
if (beasties)
transformed = await beasties.process(transformed)
- let optimized = html
- // Under the hood, Unhead uses capo.js to optimize the head tags
- // @see https://unhead.unjs.io/docs/typescript/head/guides/get-started/installation#_3-setup-server-side-rendering-optional
- // @see https://unhead.unjs.io/docs/typescript/head/guides/core-concepts/positions#sort-order
- // @see https://rviscomi.github.io/capo.js/user/rules/
- if (head)
- optimized = await transformHtmlTemplate(head as Unhead, transformed)
-
- const formatted = await formatHtml(optimized, formatting)
+ const formatted = await formatHtml(transformed, formatting)
const relativeRouteFile = `${(route.endsWith('/')
? `${route}index`
diff --git a/src/node/preload-links.ts b/src/node/preload-links.ts
index af3293a..7896093 100644
--- a/src/node/preload-links.ts
+++ b/src/node/preload-links.ts
@@ -1,60 +1,28 @@
+import { ResolvableLink } from '@unhead/vue';
import type { Manifest } from './build'
-export function renderPreloadLinks(document: Document, modules: Set<string>, ssrManifest: Manifest) {
- const seen = new Set()
-
- const preloadLinks: string[] = []
+export function renderPreloadLinks(modules: Set<string>, ssrManifest: Manifest): ResolvableLink[] {
+ const links: ResolvableLink[] = []
// preload modules
Array.from(modules).forEach((id) => {
const files = ssrManifest[id] || []
files.forEach((file) => {
- if (!preloadLinks.includes(file))
- preloadLinks.push(file)
- })
- })
-
- if (preloadLinks) {
- preloadLinks.forEach((file) => {
- if (!seen.has(file)) {
- seen.add(file)
- renderPreloadLink(document, file)
+ if (file.endsWith('.js')) {
+ links.push({
+ rel: 'modulepreload',
+ crossorigin: '',
+ href: file,
+ })
+ }
+ else if (file.endsWith('.css')) {
+ links.push({
+ rel: 'stylesheet',
+ href: file,
+ })
}
})
- }
-}
-
-function renderPreloadLink(document: Document, file: string) {
- if (file.endsWith('.js')) {
- appendLink(document, {
- rel: 'modulepreload',
- crossOrigin: '',
- href: file,
- })
- }
- else if (file.endsWith('.css')) {
- appendLink(document, {
- rel: 'stylesheet',
- href: file,
- })
- }
-}
-
-function createLink(document: Document) {
- return document.createElement('link')
-}
-
-function setAttrs(el: Element, attrs: Record<string, any>) {
- const keys = Object.keys(attrs)
- for (const key of keys)
- el.setAttribute(key, attrs[key])
-}
+ })
-function appendLink(document: Document, attrs: Record<string, any>) {
- const exits = document.head.querySelector(`link[href='${attrs.file}']`)
- if (exits)
- return
- const link = createLink(document)
- setAttrs(link, attrs)
- document.head.appendChild(link)
+ return links
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hello 👋,
Currently, Vite SSG generates the head using a client-side hook from Unhead (
renderDOMHead).This means the head isn’t fully optimized for performance when the browser loads the page.
I refactored the generation process to use
transformHtmlTemplate, which uses capo.js under the hood to optimize the page (see capo.js rules).For example, the output of examples/multiple-pages/dist/index.html goes from:
to
Patch