fix(client): only update head if needed (#3017)

pull/3034/head
Divyansh Singh 2 years ago committed by GitHub
parent a2911030aa
commit f2fc3dc51b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,7 +8,7 @@ import {
import type { Route } from '../router' import type { Route } from '../router'
export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) { export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) {
let managedHeadTags: HTMLElement[] = [] let managedHeadElements: (HTMLElement | undefined)[] = []
let isFirstUpdate = true let isFirstUpdate = true
const updateHeadTags = (newTags: HeadConfig[]) => { const updateHeadTags = (newTags: HeadConfig[]) => {
@ -19,13 +19,25 @@ export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) {
return return
} }
managedHeadTags.forEach((el) => document.head.removeChild(el)) const newElements: (HTMLElement | undefined)[] =
managedHeadTags = [] newTags.map(createHeadElement)
newTags.forEach((headConfig) => {
const el = createHeadElement(headConfig) managedHeadElements.forEach((oldEl, oldIndex) => {
document.head.appendChild(el) const matchedIndex = newElements.findIndex(
managedHeadTags.push(el) (newEl) => newEl?.isEqualNode(oldEl ?? null)
)
if (matchedIndex !== -1) {
delete newElements[matchedIndex]
} else {
oldEl?.remove()
delete managedHeadElements[oldIndex]
}
}) })
newElements.forEach((el) => el && document.head.appendChild(el))
managedHeadElements = [...managedHeadElements, ...newElements].filter(
Boolean
)
} }
watchEffect(() => { watchEffect(() => {
@ -35,14 +47,19 @@ export function useUpdateHead(route: Route, siteDataByRouteRef: Ref<SiteData>) {
const frontmatterHead = (pageData && pageData.frontmatter.head) || [] const frontmatterHead = (pageData && pageData.frontmatter.head) || []
// update title and description // update title and description
document.title = createTitle(siteData, pageData) const title = createTitle(siteData, pageData)
if (title !== document.title) {
document.title = title
}
const description = pageDescription || siteData.description const description = pageDescription || siteData.description
let metaDescriptionElement = document.querySelector( let metaDescriptionElement = document.querySelector(
`meta[name=description]` `meta[name=description]`
) )
if (metaDescriptionElement) { if (metaDescriptionElement) {
if (metaDescriptionElement.getAttribute('content') !== description) {
metaDescriptionElement.setAttribute('content', description) metaDescriptionElement.setAttribute('content', description)
}
} else { } else {
createHeadElement(['meta', { name: 'description', content: description }]) createHeadElement(['meta', { name: 'description', content: description }])
} }

Loading…
Cancel
Save