perf(fast-element): improve synthetic view creation speed (#2680)
This commit is contained in:
Родитель
1957c6fd98
Коммит
2e2b549475
|
@ -1,16 +1,21 @@
|
|||
import { Callable } from "./interfaces";
|
||||
const markerClass = "fph fm";
|
||||
|
||||
export const DOM = {
|
||||
pendingUpdates: [] as Callable[],
|
||||
|
||||
createTextMarker() {
|
||||
const marker = document.createElement("fm");
|
||||
this.makeIntoInstructionTarget(marker);
|
||||
const marker = document.createElement("template");
|
||||
marker.className = markerClass;
|
||||
return marker;
|
||||
},
|
||||
|
||||
isMarker(node: HTMLElement): boolean {
|
||||
return node.tagName === "TEMPLATE" && node.className === "fph";
|
||||
isMarker(node: Node): boolean {
|
||||
return (
|
||||
node.nodeType === 1 &&
|
||||
(node as HTMLElement).tagName === "TEMPLATE" &&
|
||||
(node as HTMLElement).className === markerClass
|
||||
);
|
||||
},
|
||||
|
||||
makeIntoInstructionTarget(element: HTMLElement) {
|
||||
|
@ -33,7 +38,7 @@ export const DOM = {
|
|||
},
|
||||
|
||||
createLocationPlaceholder(instructionIndex: number) {
|
||||
return `<template i="${instructionIndex}" class="fph"></template><!---->`;
|
||||
return `<template i="${instructionIndex}" class="${markerClass}"></template><!---->`;
|
||||
},
|
||||
|
||||
queueUpdate(callable: Callable) {
|
||||
|
|
|
@ -54,14 +54,12 @@ export class TemplateCompiler {
|
|||
if (DOM.isMarker(node as HTMLElement)) {
|
||||
return this.compileBlock(
|
||||
node as HTMLElement,
|
||||
parentNode,
|
||||
directives,
|
||||
instructions
|
||||
);
|
||||
} else {
|
||||
return this.compileElement(
|
||||
node as HTMLElement,
|
||||
parentNode,
|
||||
directives,
|
||||
instructions
|
||||
);
|
||||
|
@ -113,7 +111,6 @@ export class TemplateCompiler {
|
|||
|
||||
private compileElement(
|
||||
node: HTMLElement,
|
||||
parentNode: Node,
|
||||
directives: Directive[],
|
||||
instructions: ITargetedInstruction[]
|
||||
): MaybeNode {
|
||||
|
@ -156,13 +153,11 @@ export class TemplateCompiler {
|
|||
|
||||
private compileBlock(
|
||||
node: HTMLElement,
|
||||
parentNode: Node,
|
||||
directives: Directive[],
|
||||
instructions: ITargetedInstruction[]
|
||||
): MaybeNode {
|
||||
const instructionIndex = parseInt(node.getAttribute("i")!);
|
||||
const directive = directives[instructionIndex];
|
||||
DOM.makeIntoInstructionTarget(node);
|
||||
instructions.push(directive);
|
||||
return node.nextSibling!;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,12 @@ export class HTMLTemplate extends Directive implements ITemplate {
|
|||
private instructions: ITargetedInstruction[]
|
||||
) {
|
||||
super();
|
||||
|
||||
const fragment = templateElement.content;
|
||||
|
||||
if (DOM.isMarker(fragment.firstChild!)) {
|
||||
fragment.insertBefore(DOM.createLocation(), fragment.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
public create(synthetic: boolean) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { IBehavior } from "./behaviors/behavior";
|
||||
import { DOM } from "./dom";
|
||||
|
||||
export interface IView {
|
||||
bind(source: unknown): void;
|
||||
|
@ -25,12 +24,9 @@ export class HTMLView implements IView, IElementView, ISyntheticView {
|
|||
private behaviors: IBehavior[],
|
||||
private isSynthetic: boolean = false
|
||||
) {
|
||||
if (this.isSynthetic) {
|
||||
fragment.insertBefore(
|
||||
(this.start = DOM.createLocation()),
|
||||
fragment.firstChild
|
||||
);
|
||||
fragment.appendChild((this.end = DOM.createLocation()));
|
||||
if (isSynthetic) {
|
||||
this.start = fragment.firstChild!;
|
||||
this.end = fragment.lastChild!;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,10 +67,18 @@ export class HTMLView implements IView, IElementView, ISyntheticView {
|
|||
}
|
||||
|
||||
bind(source: unknown) {
|
||||
this.behaviors.forEach(x => x.bind(source));
|
||||
const behaviors = this.behaviors;
|
||||
|
||||
for (let i = 0, ii = behaviors.length; i < ii; ++i) {
|
||||
behaviors[i].bind(source);
|
||||
}
|
||||
}
|
||||
|
||||
unbind() {
|
||||
this.behaviors.forEach(x => x.unbind());
|
||||
const behaviors = this.behaviors;
|
||||
|
||||
for (let i = 0, ii = behaviors.length; i < ii; ++i) {
|
||||
behaviors[i].unbind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче