Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[experiment] updated DOM sync approach #1541

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmark/benchmarks/krausest/browser.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import render from './lib/index';

export default async function run() {
await render(document.body, true);
await render();
}
57 changes: 0 additions & 57 deletions benchmark/benchmarks/krausest/lib/components/Application.hbs

This file was deleted.

This file was deleted.

191 changes: 145 additions & 46 deletions benchmark/benchmarks/krausest/lib/components/Application.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,154 @@
import { swapRows, type Item, updateData, buildData } from '@/utils/data';
import { createCell } from '@glimmer-workspace/benchmark-env';
import { fn } from '@glimmer/runtime';
export default class Application {
cell!: ReturnType<typeof createCell>;
selectedItemCell!: ReturnType<typeof createCell>;
constructor() {
this.cell = createCell(this, 'cell', []);
this.selectedItemCell = createCell(this, 'selectedItem', null);
import type { Item } from '@/utils/data';
import { buildData, swapRows, updateData } from '@/utils/data';

import { ListComponent } from './list';
import { Cell, tagsToRevalidate } from '@/utils/reactive';
import type { ComponentReturnType } from '@/utils/component';
import { ButtonComponent } from '@/components/ButtonComponent';
import { bindUpdatingOpcode } from '@/utils/vm';
export class Application {
_items = new Cell<Item[]>([], 'items');
get items() {
return this._items.value;
}
fn = fn;
eq = (a: Item | null, b: Item | null) => {
return a === b;
};
get selectedItem() {
return this.selectedItemCell.get() as Item | null;
set items(value: Item[]) {
this._items.update(value);
}
set selectedItem(value: Item | null) {
this.selectedItemCell.set(value);
list: ListComponent;
children: ComponentReturnType[] = [];
selectedCell = new Cell(0, 'selectedCell');
buttonWrapper() {
const div = document.createElement('div');
div.className = 'col-sm-6 smallpad';
return div;
}
get items() {
return this.cell.get() as Item[];
constructor() {
/* benchmark bootstrap start */
const container = document.createElement('container');
container.className = 'container';
const jumbotron = document.createElement('div');
jumbotron.className = 'jumbotron';
const row1 = document.createElement('div');
row1.className = 'row';
const leftColumn = document.createElement('div');
leftColumn.className = 'col-md-6';
const rightColumn = document.createElement('div');
rightColumn.className = 'col-md-6';
const h1 = document.createElement('h1');
h1.textContent = 'GlimmerCore';
const row2 = document.createElement('div');
row2.className = 'row';

const btnW1 = this.buttonWrapper();
const btnW2 = this.buttonWrapper();
const btnW3 = this.buttonWrapper();
const btnW4 = this.buttonWrapper();
const btnW5 = this.buttonWrapper();
const btnW6 = this.buttonWrapper();

/**/ container.appendChild(jumbotron);
/* */ jumbotron.appendChild(row1);
/* */ row1.appendChild(leftColumn);
/* */ leftColumn.appendChild(h1);
/* */ row1.appendChild(rightColumn);
/* */ rightColumn.appendChild(row2);
/* */ row2.appendChild(btnW1);
/* */ row2.appendChild(btnW2);
/* */ row2.appendChild(btnW3);
/* */ row2.appendChild(btnW4);
/* */ row2.appendChild(btnW5);
/* */ row2.appendChild(btnW6);
/* benchmark bootstrap end */

this.children.push(
ButtonComponent(
{
onClick: () => this.create_1_000_Items(),
text: 'Create 1000 items',
id: 'run',
},
btnW1
),
ButtonComponent(
{
onClick: () => this.create_5_000_Items(),
text: 'Create 5 000 items',
id: 'runlots',
},
btnW2
),
ButtonComponent(
{
onClick: () => this.append_1_000_Items(),
text: 'Append 1000 rows',
id: 'add',
},
btnW3
),
ButtonComponent(
{
onClick: () => this.updateEvery_10th_row(),
text: 'Update every 10th row',
id: 'update',
},
btnW4
),
ButtonComponent(
{
onClick: () => this.clear(),
text: 'Clear',
id: 'clear',
},
btnW5
),
ButtonComponent(
{
onClick: () => this.swapRows(),
text: 'Swap rows',
id: 'swaprows',
},
btnW6
)
);

this.items = [];
this.list = new ListComponent({ app: this, items: this.items }, container);

/* benchmark icon preload span start */
const preloadSpan = document.createElement('span');
preloadSpan.className = 'preloadicon glyphicon glyphicon-remove';
preloadSpan.setAttribute('aria-hidden', 'true');
container.appendChild(preloadSpan);
document.body.appendChild(container);
/* benchmark icon preload span end */

tagsToRevalidate;

bindUpdatingOpcode(this._items, () => {
this.list.syncList(this.items);
});

this.children.push(this.list);
}
set items(value: Item[]) {
this.cell.set(value);
removeItem(item: Item) {
this.items = this.items.filter((i) => i.id !== item.id);
}
select = (item: Item) => {
this.selectedItem = item;
};
create = () => {
create_1_000_Items() {
this.items = buildData(1000);
};
runLots = () => {
}
append_1_000_Items() {
this.items = [...this.items, ...buildData(1000)];
}
create_5_000_Items() {
this.items = buildData(5000);
};
add = () => {
this.items = this.items.concat(buildData(1000));
};
update = () => {
this.items = updateData(this.items);
};
clear = () => {
this.items = [];
this.selectedItem = null;
};
swapRows = () => {
}
swapRows() {
this.items = swapRows(this.items);
};
remove = (item: Item) => {
this.items = this.items.filter((el) => el !== item);
if (this.selectedItem === item) {
this.selectedItem = null;
}
};
}
clear() {
this.items = [];
}
updateEvery_10th_row() {
updateData(this.items, 10);
}
}
1 change: 0 additions & 1 deletion benchmark/benchmarks/krausest/lib/components/BsButton.hbs

This file was deleted.

This file was deleted.

27 changes: 27 additions & 0 deletions benchmark/benchmarks/krausest/lib/components/ButtonComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { addEventListener } from '@/utils/component';

export function ButtonComponent(
{ onClick, text, slot, id }: { onClick: () => void; text: string; slot?: Node; id?: string },
outlet: HTMLElement
) {
const button = document.createElement('button');
button.setAttribute('class', 'btn btn-primary btn-block');
button.type = 'button';

const textNode = document.createTextNode(text);
if (id) {
button.setAttribute('id', id);
}
button.appendChild(textNode);
if (slot) {
button.appendChild(slot);
}

outlet.appendChild(button);

return {
nodes: [button],
destructors: [addEventListener(button, 'click', onClick)],
index: 0,
};
}
41 changes: 41 additions & 0 deletions benchmark/benchmarks/krausest/lib/components/LabelComponent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ifCondition } from '@/components/if';
import type { ComponentRenderTarget } from '@/utils/component';
import type { AnyCell, Cell } from '@/utils/reactive';
import { bindUpdatingOpcode } from '@/utils/vm';

export function LabelComponent({ text }: { text: string | AnyCell }, outlet: HTMLElement) {
const span = document.createElement('span');
const destructors = [];
if (typeof text !== 'string') {
destructors.push(
bindUpdatingOpcode(text, (text) => {
span.textContent = String(text);
})
);
} else {
span.textContent = text;
}
outlet.appendChild(span);
return {
nodes: [span],
destructors,
index: 0,
};
}

export function LabelWrapperComponent(
{ isVisible }: { isVisible: Cell<boolean> },
outlet: ComponentRenderTarget
) {
const hoveredDiv = document.createElement('div');
const div = document.createElement('div');

LabelComponent({ text: '🗿' }, hoveredDiv);
LabelComponent({ text: '😄' }, div);

return {
nodes: [div],
destructors: [ifCondition(isVisible, outlet, hoveredDiv, div)],
index: 0,
};
}
10 changes: 0 additions & 10 deletions benchmark/benchmarks/krausest/lib/components/Row.hbs

This file was deleted.

2 changes: 0 additions & 2 deletions benchmark/benchmarks/krausest/lib/components/Row.hbs.d.ts

This file was deleted.

20 changes: 0 additions & 20 deletions benchmark/benchmarks/krausest/lib/components/Row.ts

This file was deleted.

Loading
Loading