perf(fast-element): improve synthetic view creation speed (#2680)

This commit is contained in:
Rob Eisenberg 2020-02-18 10:05:23 -08:00 коммит произвёл GitHub
Родитель 1957c6fd98
Коммит 2e2b549475
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 29 добавлений и 19 удалений

Просмотреть файл

@ -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();
}
}
}