diff --git a/modules/benchmarks/e2e_test/tree_perf.ts b/modules/benchmarks/e2e_test/tree_perf.ts
index 845b468875..95d9659ed0 100644
--- a/modules/benchmarks/e2e_test/tree_perf.ts
+++ b/modules/benchmarks/e2e_test/tree_perf.ts
@@ -8,62 +8,91 @@
import {runBenchmark, verifyNoBrowserErrors} from 'e2e_util/perf_util';
+interface Worker {
+ id: string;
+ prepare?(): void;
+ work(): void;
+}
+
+const CreateOnlyWorker: Worker = {
+ id: 'createOnly',
+ prepare: () => $('#destroyDom').click(),
+ work: () => $('#createDom').click()
+};
+
+const CreateAndDestroyWorker: Worker = {
+ id: 'createDestroy',
+ work: () => {
+ $('#createDom').click();
+ $('#destroyDom').click();
+ }
+};
+
+const UpdateWorker: Worker = {
+ id: 'update',
+ work: () => $('#createDom').click()
+};
+
describe('tree benchmark perf', () => {
afterEach(verifyNoBrowserErrors);
- it('should run for ng2', (done) => {
- runTreeBenchmark({
- id: 'deepTree.ng2',
- url: 'all/benchmarks/src/tree/ng2/index.html',
- }).then(done, done.fail);
- });
+ [CreateOnlyWorker, CreateAndDestroyWorker, UpdateWorker].forEach((worker) => {
+ describe(worker.id, () => {
- it('should run for ng2 static', (done) => {
- runTreeBenchmark({
- id: 'deepTree.ng2.static',
- url: 'all/benchmarks/src/tree/ng2_static/index.html',
- }).then(done, done.fail);
- });
+ it('should run for ng2', (done) => {
+ runTreeBenchmark({
+ id: `deepTree.ng2.${worker.id}`,
+ url: 'all/benchmarks/src/tree/ng2/index.html',
+ }).then(done, done.fail);
+ });
- it('should run for the baseline', (done) => {
- runTreeBenchmark({
- id: 'deepTree.baseline',
- url: 'all/benchmarks/src/tree/baseline/index.html',
- ignoreBrowserSynchronization: true,
- }).then(done, done.fail);
- });
+ it('should run for ng2 static', (done) => {
+ runTreeBenchmark({
+ id: `deepTree.ng2.static.${worker.id}`,
+ url: 'all/benchmarks/src/tree/ng2_static/index.html',
+ }).then(done, done.fail);
+ });
- it('should run for the baseline dom', (done) => {
- runTreeBenchmark({
- id: 'deepTree.baselineDom',
- url: 'all/benchmarks/src/tree/baseline_dom/index.html',
- ignoreBrowserSynchronization: true,
- }).then(done, done.fail);
- });
+ it('should run for ng2 switch', (done) => {
+ runTreeBenchmark({
+ id: `deepTree.ng2_switch.${worker.id}`,
+ url: 'all/benchmarks/src/tree/ng2_switch/index.html',
+ }).then(done, done.fail);
+ });
- it('should run for the incremental dom', (done) => {
- runTreeBenchmark({
- id: 'deepTree.incrementalDom',
- url: 'all/benchmarks/src/tree/incremental_dom/index.html',
- ignoreBrowserSynchronization: true,
- }).then(done, done.fail);
- });
+ it('should run for the baseline', (done) => {
+ runTreeBenchmark({
+ id: `deepTree.baseline.${worker.id}`,
+ url: 'all/benchmarks/src/tree/baseline/index.html',
+ ignoreBrowserSynchronization: true,
+ }).then(done, done.fail);
+ });
- it('should run for polymer binary tree', (done) => {
- runTreeBenchmark({
- id: 'deepTree.polymer',
- url: 'all/benchmarks/src/tree/polymer/index.html',
- ignoreBrowserSynchronization: true,
- }).then(done, done.fail);
- });
+ it('should run for incremental-dom', (done) => {
+ runTreeBenchmark({
+ id: `deepTree.incremental_dom.${worker.id}`,
+ url: 'all/benchmarks/src/tree/incremental_dom/index.html',
+ ignoreBrowserSynchronization: true,
+ }).then(done, done.fail);
+ });
- it('should run for polymer leaves', (done) => {
- runTreeBenchmark({
- id: 'deepTree.polymerLeaves',
- url: 'all/benchmarks/src/tree/polymer_leaves/index.html',
- ignoreBrowserSynchronization: true,
- }).then(done, done.fail);
+ it('should run for polymer binary tree', (done) => {
+ runTreeBenchmark({
+ id: `deepTree.polymer.${worker.id}`,
+ url: 'all/benchmarks/src/tree/polymer/index.html',
+ ignoreBrowserSynchronization: true,
+ }).then(done, done.fail);
+ });
+
+ it('should run for polymer leaves', (done) => {
+ runTreeBenchmark({
+ id: `deepTree.polymer_leaves.${worker.id}`,
+ url: 'all/benchmarks/src/tree/polymer_leaves/index.html',
+ ignoreBrowserSynchronization: true,
+ }).then(done, done.fail);
+ });
+ });
});
function runTreeBenchmark(
diff --git a/modules/benchmarks/e2e_test/tree_spec.ts b/modules/benchmarks/e2e_test/tree_spec.ts
index 2eba0d9525..13bb9bac57 100644
--- a/modules/benchmarks/e2e_test/tree_spec.ts
+++ b/modules/benchmarks/e2e_test/tree_spec.ts
@@ -24,6 +24,12 @@ describe('tree benchmark spec', () => {
});
});
+ it('should work for ng2 switch', () => {
+ testTreeBenchmark({
+ url: 'all/benchmarks/src/tree/ng2_switch/index.html',
+ });
+ });
+
it('should work for the baseline', () => {
testTreeBenchmark({
url: 'all/benchmarks/src/tree/baseline/index.html',
@@ -31,14 +37,7 @@ describe('tree benchmark spec', () => {
});
});
- it('should work for the baseline dom', () => {
- testTreeBenchmark({
- url: 'all/benchmarks/src/tree/baseline_dom/index.html',
- ignoreBrowserSynchronization: true,
- });
- });
-
- it('should work for the incremental dom', () => {
+ it('should work for incremental dom', () => {
testTreeBenchmark({
url: 'all/benchmarks/src/tree/incremental_dom/index.html',
ignoreBrowserSynchronization: true,
@@ -60,9 +59,15 @@ describe('tree benchmark spec', () => {
});
function testTreeBenchmark(openConfig: {url: string, ignoreBrowserSynchronization?: boolean}) {
- openBrowser(openConfig);
+ openBrowser({
+ url: openConfig.url,
+ ignoreBrowserSynchronization: openConfig.ignoreBrowserSynchronization,
+ params: [{name: 'depth', value: 4}],
+ });
$('#createDom').click();
expect($('#root').getText()).toContain('0');
+ $('#createDom').click();
+ expect($('#root').getText()).toContain('A');
$('#destroyDom').click();
expect($('#root').getText()).toEqual('');
}
diff --git a/modules/benchmarks/src/tree/baseline/index.html b/modules/benchmarks/src/tree/baseline/index.html
index 71af2520e0..b531ca02ac 100644
--- a/modules/benchmarks/src/tree/baseline/index.html
+++ b/modules/benchmarks/src/tree/baseline/index.html
@@ -2,26 +2,26 @@
-Params
-
+ Params
+
-Baseline tree benchmark
-
-
-
-
-
-
+ Baseline Tree Benchmark
+
+
+
+
+
+
-
-
-
+
+
+
-
+
\ No newline at end of file
diff --git a/modules/benchmarks/src/tree/baseline/index.ts b/modules/benchmarks/src/tree/baseline/index.ts
index 9e90915ee7..58a3927cf1 100644
--- a/modules/benchmarks/src/tree/baseline/index.ts
+++ b/modules/benchmarks/src/tree/baseline/index.ts
@@ -1,19 +1,18 @@
import {bindAction, profile} from '../../util';
import {TreeNode, buildTree, emptyTree} from '../util';
-import {BaseLineTreeComponent} from './tree';
+import {TreeComponent} from './tree';
export function main() {
- var app: BaseLineTreeComponent;
+ var tree: TreeComponent;
- function destroyDom() { app.update(emptyTree); }
+ function destroyDom() { tree.data = emptyTree; }
- function createDom() { app.update(buildTree()); }
+ function createDom() { tree.data = buildTree(); }
function noop() {}
function init() {
- const tree: any = document.querySelector('tree');
- app = new BaseLineTreeComponent(tree);
+ tree = new TreeComponent(document.querySelector('tree'));
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
diff --git a/modules/benchmarks/src/tree/baseline/tree.ts b/modules/benchmarks/src/tree/baseline/tree.ts
index 3e500ecd06..98c330ca61 100644
--- a/modules/benchmarks/src/tree/baseline/tree.ts
+++ b/modules/benchmarks/src/tree/baseline/tree.ts
@@ -1,74 +1,61 @@
-import {__platform_browser_private__} from '@angular/platform-browser';
import {TreeNode} from '../util';
-// Note: We are using the DomAdapter also in the Baseline
-// so that Ng2 can actually reach the baseline. Once Ng2 is able to generate
-// code that does not use the DomAdapter any more, we should remove this.
-__platform_browser_private__.initDomAdapter();
-const getDOM = __platform_browser_private__.getDOM;
+export class TreeComponent {
+ private _renderNodes: any[];
-const BASELINE_TREE_TEMPLATE = document.createElement('template');
-BASELINE_TREE_TEMPLATE.innerHTML =
- '_';
-const BASELINE_IF_TEMPLATE = document.createElement('template');
-BASELINE_IF_TEMPLATE.innerHTML = '';
+ constructor(private _rootEl: any) {}
-export class BaseLineTreeComponent {
- value: BaseLineInterpolation;
- left: BaseLineIf;
- right: BaseLineIf;
- constructor(public element: HTMLElement) {
- var clone = getDOM().clone(BASELINE_TREE_TEMPLATE.content.firstChild);
- getDOM().appendChild(element, clone);
-
- var child = clone.firstChild;
- this.value = new BaseLineInterpolation(child);
- child = getDOM().nextSibling(child);
- this.left = new BaseLineIf(child);
- child = getDOM().nextSibling(child);
- this.right = new BaseLineIf(child);
- }
- update(value: TreeNode) {
- this.value.update(value.value);
- this.left.update(value.left);
- this.right.update(value.right);
- }
-}
-
-export class BaseLineInterpolation {
- value: string;
- constructor(public textNode: Node) { this.value = null; }
- update(value: string) {
- if (this.value !== value) {
- this.value = value;
- getDOM().setText(this.textNode, value + ' ');
+ set data(data: TreeNode) {
+ if (!data.left) {
+ this._destroy();
+ } else if (this._renderNodes) {
+ this._update(data, 0);
+ } else {
+ this._create(this._rootEl, data, 0);
}
}
-}
-export class BaseLineIf {
- condition: boolean;
- component: BaseLineTreeComponent;
- constructor(public anchor: Node) {
- this.condition = false;
- this.component = null;
+ private _create(parentNode: any, dataNode: TreeNode, index: number) {
+ if (!this._renderNodes) {
+ this._renderNodes = new Array(dataNode.transitiveChildCount);
+ }
+
+ const span = document.createElement('span');
+ if (dataNode.depth % 2 === 0) {
+ span.style.backgroundColor = 'grey';
+ }
+ parentNode.appendChild(span);
+ this._renderNodes[index] = span;
+ this._updateNode(span, dataNode);
+
+ if (dataNode.left) {
+ const leftTree = document.createElement('tree');
+ parentNode.appendChild(leftTree);
+ this._create(leftTree, dataNode.left, index + 1);
+ }
+ if (dataNode.right) {
+ const rightTree = document.createElement('tree');
+ parentNode.appendChild(rightTree);
+ this._create(rightTree, dataNode.right, index + dataNode.left.transitiveChildCount + 1);
+ }
}
- update(value: TreeNode) {
- var newCondition = !!value;
- if (this.condition !== newCondition) {
- this.condition = newCondition;
- if (this.component) {
- getDOM().remove(this.component.element);
- this.component = null;
- }
- if (this.condition) {
- var element = getDOM().firstChild((getDOM().clone(BASELINE_IF_TEMPLATE)).content);
- this.anchor.parentNode.insertBefore(element, getDOM().nextSibling(this.anchor));
- this.component = new BaseLineTreeComponent(getDOM().firstChild(element));
- }
+
+ private _updateNode(renderNode: any, dataNode: TreeNode) {
+ renderNode.textContent = ` ${dataNode.value} `;
+ }
+
+ private _update(dataNode: TreeNode, index: number) {
+ this._updateNode(this._renderNodes[index], dataNode);
+ if (dataNode.left) {
+ this._update(dataNode.left, index + 1);
}
- if (this.component) {
- this.component.update(value);
+ if (dataNode.right) {
+ this._update(dataNode.right, index + dataNode.left.transitiveChildCount + 1);
}
}
+
+ private _destroy() {
+ while (this._rootEl.lastChild) this._rootEl.lastChild.remove();
+ this._renderNodes = null;
+ }
}
diff --git a/modules/benchmarks/src/tree/baseline_dom/index.ts b/modules/benchmarks/src/tree/baseline_dom/index.ts
deleted file mode 100644
index 179a29c706..0000000000
--- a/modules/benchmarks/src/tree/baseline_dom/index.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import {bindAction, profile} from '../../util';
-import {TreeNode, buildTree, emptyTree} from '../util';
-import {createTreeTemplate, destroyTreeTemplate} from './tree';
-
-export function main() {
- var app: any;
-
- function destroyDom() { destroyTreeTemplate(app); }
-
- function createDom() { createTreeTemplate(app, buildTree()); }
-
- function noop() {}
-
- function init() {
- app = document.querySelector('tree');
-
- bindAction('#destroyDom', destroyDom);
- bindAction('#createDom', createDom);
-
- bindAction('#updateDomProfile', profile(createDom, noop, 'update'));
- bindAction('#createDomProfile', profile(createDom, destroyDom, 'create'));
- }
-
- init();
-}
diff --git a/modules/benchmarks/src/tree/baseline_dom/tree.ts b/modules/benchmarks/src/tree/baseline_dom/tree.ts
deleted file mode 100644
index 2c6567b2b8..0000000000
--- a/modules/benchmarks/src/tree/baseline_dom/tree.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import {TreeNode} from '../util';
-
-// template:
-// {{data.value}}
-export function createTreeTemplate(parentEl: any, data: TreeNode) {
- const rootSpan = document.createElement('span');
- parentEl.appendChild(rootSpan);
- rootSpan.appendChild(document.createTextNode(` ${data.value} `));
-
- if (data.left) {
- const leftTreeSpan = document.createElement('span');
- rootSpan.appendChild(leftTreeSpan);
- const leftTree = document.createElement('tree');
- leftTreeSpan.appendChild(leftTree);
- createTreeTemplate(leftTree, data.left);
- }
- if (data.right) {
- const rightTreeSpan = document.createElement('span');
- rootSpan.appendChild(rightTreeSpan);
- const rightTree = document.createElement('tree');
- rightTreeSpan.appendChild(rightTree);
- createTreeTemplate(rightTree, data.right);
- }
-}
-
-export function destroyTreeTemplate(el: any) {
- while (el.firstChild) el.removeChild(el.firstChild);
-}
diff --git a/modules/benchmarks/src/tree/incremental_dom/index.html b/modules/benchmarks/src/tree/incremental_dom/index.html
index 8cd5386fab..99335bd3e4 100644
--- a/modules/benchmarks/src/tree/incremental_dom/index.html
+++ b/modules/benchmarks/src/tree/incremental_dom/index.html
@@ -10,7 +10,7 @@
- Baseline tree benchmark
+ Incremental-Dom Tree Benchmark
diff --git a/modules/benchmarks/src/tree/incremental_dom/index.ts b/modules/benchmarks/src/tree/incremental_dom/index.ts
index dffb8c8ce2..70ffe285e3 100644
--- a/modules/benchmarks/src/tree/incremental_dom/index.ts
+++ b/modules/benchmarks/src/tree/incremental_dom/index.ts
@@ -1,19 +1,19 @@
import {bindAction, profile} from '../../util';
import {TreeNode, buildTree, emptyTree} from '../util';
-import {render} from './tree';
+import {TreeComponent} from './tree';
const {patch} = require('incremental-dom');
export function main() {
- var app: any;
+ var tree: TreeComponent;
- function destroyDom() { patch(app, () => render(emptyTree)); }
+ function destroyDom() { tree.data = emptyTree; }
- function createDom() { patch(app, () => render(buildTree())); }
+ function createDom() { tree.data = buildTree(); }
function noop() {}
function init() {
- app = document.querySelector('tree');
+ tree = new TreeComponent(document.querySelector('tree'));
bindAction('#destroyDom', destroyDom);
bindAction('#createDom', createDom);
diff --git a/modules/benchmarks/src/tree/incremental_dom/tree.ts b/modules/benchmarks/src/tree/incremental_dom/tree.ts
index 808ccfd676..86ca2e3e30 100644
--- a/modules/benchmarks/src/tree/incremental_dom/tree.ts
+++ b/modules/benchmarks/src/tree/incremental_dom/tree.ts
@@ -1,26 +1,29 @@
import {TreeNode} from '../util';
-const {elementOpen, elementClose, text} = require('incremental-dom');
+const {patch, elementOpen, elementClose, elementOpenStart, elementOpenEnd, text, attr} =
+ require('incremental-dom');
-// template:
-// {{data.value}}
-export function render(data: TreeNode) {
- elementOpen('span', '', null);
- text(` ${data.value} `);
- if (data.left) {
- elementOpen('span', '', null);
- elementOpen('tree', '', null);
- render(data.left);
- elementClose('tree');
+export class TreeComponent {
+ constructor(private _rootEl: any) {}
+
+ set data(data: TreeNode) { patch(this._rootEl, () => this._render(data)); }
+
+ private _render(data: TreeNode) {
+ elementOpenStart('span', '', null);
+ if (data.depth % 2 === 0) {
+ attr('style', 'background-color: grey');
+ }
+ elementOpenEnd();
+ text(` ${data.value} `);
elementClose('span');
+ if (data.left) {
+ elementOpen('tree', '', null);
+ this._render(data.left);
+ elementClose('tree');
+ }
+ if (data.right) {
+ elementOpen('tree', '', null);
+ this._render(data.right);
+ elementClose('tree');
+ }
}
- if (data.right) {
- elementOpen('span', '', null);
- elementOpen('tree', '', null);
- render(data.right);
- elementClose('tree');
- elementClose('span');
- }
- elementClose('span');
}
diff --git a/modules/benchmarks/src/tree/ng2/index.html b/modules/benchmarks/src/tree/ng2/index.html
index 231eb44f3e..e64dc34021 100644
--- a/modules/benchmarks/src/tree/ng2/index.html
+++ b/modules/benchmarks/src/tree/ng2/index.html
@@ -2,26 +2,26 @@
-Params
-
+ Params
+
-Angular2 tree benchmark
-
-
-
-
-
-
+ Ng2 Tree Benchmark
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
\ No newline at end of file
+