diff --git a/packages/runtime-core/src/renderer.ts b/packages/runtime-core/src/renderer.ts
index 04bebdb1..0a215a14 100644
--- a/packages/runtime-core/src/renderer.ts
+++ b/packages/runtime-core/src/renderer.ts
@@ -124,7 +124,9 @@ export interface RendererOptions<
content: string,
parent: HostElement,
anchor: HostNode | null,
- isSVG: boolean
+ isSVG: boolean,
+ start?: HostNode | null,
+ end?: HostNode | null
): [HostNode, HostNode]
}
@@ -511,7 +513,9 @@ function baseCreateRenderer(
n2.children as string,
container,
anchor,
- isSVG
+ isSVG,
+ n2.el,
+ n2.anchor
)
}
diff --git a/packages/runtime-dom/__tests__/nodeOps.spec.ts b/packages/runtime-dom/__tests__/nodeOps.spec.ts
index 1944bf0e..dcab9a0a 100644
--- a/packages/runtime-dom/__tests__/nodeOps.spec.ts
+++ b/packages/runtime-dom/__tests__/nodeOps.spec.ts
@@ -82,5 +82,28 @@ describe('runtime-dom: node-ops', () => {
expect((first as Element).namespaceURI).toMatch('svg')
expect((last as Element).namespaceURI).toMatch('svg')
})
+
+ test('cached insertion', () => {
+ const content = `
one
two
three`
+ const existing = `existing
`
+ const parent = document.createElement('div')
+ parent.innerHTML = existing
+ const anchor = parent.firstChild
+
+ const cached = document.createElement('div')
+ cached.innerHTML = content
+
+ const nodes = nodeOps.insertStaticContent!(
+ content,
+ parent,
+ anchor,
+ false,
+ cached.firstChild,
+ cached.lastChild
+ )
+ expect(parent.innerHTML).toBe(content + existing)
+ expect(nodes[0]).toBe(parent.firstChild)
+ expect(nodes[1]).toBe(parent.childNodes[parent.childNodes.length - 2])
+ })
})
})
diff --git a/packages/runtime-dom/src/nodeOps.ts b/packages/runtime-dom/src/nodeOps.ts
index de13d8f1..c3a4f4ba 100644
--- a/packages/runtime-dom/src/nodeOps.ts
+++ b/packages/runtime-dom/src/nodeOps.ts
@@ -4,7 +4,7 @@ export const svgNS = 'http://www.w3.org/2000/svg'
const doc = (typeof document !== 'undefined' ? document : null) as Document
-const staticTemplateCache = new Map()
+const templateContainer = doc && doc.createElement('template')
export const nodeOps: Omit, 'patchProp'> = {
insert: (child, parent, anchor) => {
@@ -73,14 +73,19 @@ export const nodeOps: Omit, 'patchProp'> = {
// Reason: innerHTML.
// Static content here can only come from compiled templates.
// As long as the user only uses trusted templates, this is safe.
- insertStaticContent(content, parent, anchor, isSVG) {
+ insertStaticContent(content, parent, anchor, isSVG, start, end) {
// before | first ... last | anchor
const before = anchor ? anchor.previousSibling : parent.lastChild
- let template = staticTemplateCache.get(content)
- if (!template) {
- const t = doc.createElement('template')
- t.innerHTML = isSVG ? `` : content
- template = t.content
+ if (start && end) {
+ // cached
+ while (true) {
+ parent.insertBefore(start!.cloneNode(true), anchor)
+ if (start === end || !(start = start!.nextSibling)) break
+ }
+ } else {
+ // fresh insert
+ templateContainer.innerHTML = isSVG ? `` : content
+ const template = templateContainer.content
if (isSVG) {
// remove outer svg wrapper
const wrapper = template.firstChild!
@@ -89,9 +94,8 @@ export const nodeOps: Omit, 'patchProp'> = {
}
template.removeChild(wrapper)
}
- staticTemplateCache.set(content, template)
+ parent.insertBefore(template, anchor)
}
- parent.insertBefore(template.cloneNode(true), anchor)
return [
// first
before ? before.nextSibling! : parent.firstChild!,