@@ -3,25 +3,51 @@ import { HeadConfig, SiteData } from '../../shared'
3
3
import { Route } from '../router'
4
4
5
5
export function useUpdateHead ( route : Route , siteDataByRouteRef : Ref < SiteData > ) {
6
- const metaTags : HTMLElement [ ] = Array . from ( document . querySelectorAll ( 'meta' ) )
7
-
6
+ let metaTagEls : HTMLElement [ ] = Array . from ( document . querySelectorAll ( 'meta' ) )
8
7
let isFirstUpdate = true
8
+
9
9
const updateHeadTags = ( newTags : HeadConfig [ ] ) => {
10
10
if ( import . meta. env . PROD && isFirstUpdate ) {
11
11
// in production, the initial meta tags are already pre-rendered so we
12
12
// skip the first update.
13
13
isFirstUpdate = false
14
14
return
15
15
}
16
- metaTags . forEach ( ( el ) => document . head . removeChild ( el ) )
17
- metaTags . length = 0
18
- if ( newTags && newTags . length ) {
19
- newTags . forEach ( ( headConfig ) => {
20
- const el = createHeadElement ( headConfig )
21
- document . head . appendChild ( el )
22
- metaTags . push ( el )
23
- } )
16
+
17
+ const newEls : HTMLElement [ ] = [ ]
18
+ const commonLength = Math . min ( metaTagEls . length , newTags . length )
19
+ for ( let i = 0 ; i < commonLength ; i ++ ) {
20
+ let el = metaTagEls [ i ]
21
+ const [ tag , attrs ] = newTags [ i ]
22
+ if ( el . tagName . toLocaleLowerCase ( ) === tag ) {
23
+ for ( const key in attrs ) {
24
+ if ( el . getAttribute ( key ) !== attrs [ key ] ) {
25
+ el . setAttribute ( key , attrs [ key ] )
26
+ }
27
+ }
28
+ for ( let i = 0 ; i < el . attributes . length ; i ++ ) {
29
+ const name = el . attributes [ i ] . name
30
+ if ( ! ( name in attrs ) ) {
31
+ el . removeAttribute ( name )
32
+ }
33
+ }
34
+ } else {
35
+ document . head . removeChild ( el )
36
+ el = createHeadElement ( newTags [ i ] )
37
+ document . head . append ( el )
38
+ }
39
+ newEls . push ( el )
24
40
}
41
+
42
+ metaTagEls
43
+ . slice ( commonLength )
44
+ . forEach ( ( el ) => document . head . removeChild ( el ) )
45
+ newTags . slice ( commonLength ) . forEach ( ( headConfig ) => {
46
+ const el = createHeadElement ( headConfig )
47
+ document . head . appendChild ( el )
48
+ newEls . push ( el )
49
+ } )
50
+ metaTagEls = newEls
25
51
}
26
52
27
53
watchEffect ( ( ) => {
0 commit comments