Skip to content

Commit 9e807dd

Browse files
committed
optimize init
1 parent ff263c7 commit 9e807dd

File tree

8 files changed

+398
-3613
lines changed

8 files changed

+398
-3613
lines changed

frameworks/keyed/million/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6-
<link href="/css/currentStyle.css" rel="stylesheet">
6+
<link href="/css/currentStyle.css" rel="stylesheet" />
77
<title>Million.js</title>
88
</head>
99
<body>
1010
<div id="main"></div>
11-
<script type="module" src="/src/main.jsx"></script>
11+
<script type="module" src="/src/main.js"></script>
1212
</body>
13-
</html>
13+
</html>

frameworks/keyed/million/src/main.js

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
import {
2+
Block,
3+
fragment,
4+
stringToDOM,
5+
} from '/Users/aidenybai/Projects/aidenybai/million/packages/block/index';
6+
7+
const adjectives = [
8+
'pretty',
9+
'large',
10+
'big',
11+
'small',
12+
'tall',
13+
'short',
14+
'long',
15+
'handsome',
16+
'plain',
17+
'quaint',
18+
'clean',
19+
'elegant',
20+
'easy',
21+
'angry',
22+
'crazy',
23+
'helpful',
24+
'mushy',
25+
'odd',
26+
'unsightly',
27+
'adorable',
28+
'important',
29+
'inexpensive',
30+
'cheap',
31+
'expensive',
32+
'fancy',
33+
];
34+
const colors = [
35+
'red',
36+
'yellow',
37+
'blue',
38+
'green',
39+
'pink',
40+
'brown',
41+
'purple',
42+
'brown',
43+
'white',
44+
'black',
45+
'orange',
46+
];
47+
const nouns = [
48+
'table',
49+
'chair',
50+
'house',
51+
'bbq',
52+
'desk',
53+
'car',
54+
'pony',
55+
'cookie',
56+
'sandwich',
57+
'burger',
58+
'pizza',
59+
'mouse',
60+
'keyboard',
61+
];
62+
63+
const random = (max) => Math.round(Math.random() * 1000) % max;
64+
65+
let nextId = 1;
66+
let list = [];
67+
let selected = 0;
68+
let main;
69+
70+
const clear = () => {
71+
list = [];
72+
main.children = [];
73+
main.remove();
74+
};
75+
76+
const buildData = (count) => {
77+
const data = new Array(count);
78+
for (let i = 0; i < count; ++i) {
79+
data[i] = {
80+
id: nextId++,
81+
label: `${adjectives[random(adjectives.length)]} ${
82+
colors[random(colors.length)]
83+
} ${nouns[random(nouns.length)]}`,
84+
};
85+
}
86+
return data;
87+
};
88+
89+
const create1k = () => {
90+
if (list.length) clear();
91+
list = buildData(1000);
92+
update();
93+
return false;
94+
};
95+
96+
const create10k = () => {
97+
if (list.length) clear();
98+
list = buildData(10000);
99+
update();
100+
return false;
101+
};
102+
103+
const append1k = () => {
104+
list = list.concat(buildData(1000));
105+
update();
106+
return false;
107+
};
108+
109+
const updateEvery10 = () => {
110+
let i = 0;
111+
while (i < list.length) {
112+
list[i].label = `${list[i].label} !!!`;
113+
i += 10;
114+
}
115+
update();
116+
return false;
117+
};
118+
119+
const swapRows = () => {
120+
if (list.length > 998) {
121+
const item = list[1];
122+
list[1] = list[998];
123+
list[998] = item;
124+
}
125+
update();
126+
return false;
127+
};
128+
129+
const select = (id) => {
130+
selected = id;
131+
update();
132+
};
133+
134+
const remove = (id) => {
135+
list.splice(
136+
list.findIndex((item) => item.id === id),
137+
1
138+
);
139+
update();
140+
};
141+
142+
const Row = (() => {
143+
const root = stringToDOM(
144+
'<tr><td class="col-md-1"></td><td class="col-md-4"><a></a></td><td class="col-md-1"><a><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td><td class="col-md-6"></td></tr>'
145+
);
146+
const edits = [
147+
{
148+
path: [0],
149+
edits: [
150+
{
151+
type: 2,
152+
hole: 'id',
153+
index: 0,
154+
},
155+
],
156+
inits: [],
157+
},
158+
{
159+
path: [1, 0],
160+
edits: [
161+
{
162+
type: 3,
163+
listener: 'select',
164+
name: 'onClick',
165+
hole: 'select',
166+
},
167+
{
168+
type: 2,
169+
hole: 'label',
170+
index: 0,
171+
},
172+
],
173+
inits: [],
174+
},
175+
{
176+
path: [2, 0],
177+
edits: [
178+
{
179+
type: 3,
180+
listener: 'remove',
181+
name: 'onClick',
182+
hole: 'remove',
183+
},
184+
],
185+
inits: [],
186+
},
187+
{
188+
path: [],
189+
edits: [
190+
{
191+
type: 0,
192+
hole: 'className',
193+
name: 'class',
194+
},
195+
],
196+
inits: [],
197+
},
198+
];
199+
const shouldUpdate = (oldProps, newProps) => {
200+
return oldProps.$key !== newProps.$key;
201+
};
202+
return (props, key) => {
203+
return new Block(root, edits, props, key, shouldUpdate);
204+
};
205+
})();
206+
207+
function render(oldCache, newCache) {
208+
return fragment(
209+
list.map((item) => {
210+
const isSelected = selected === item.id;
211+
const cachedItem = oldCache[item.id];
212+
const $key = item.label + String(isSelected);
213+
if (cachedItem?.props.$key === $key) {
214+
return (newCache[item.id] = cachedItem);
215+
}
216+
217+
const row = Row(
218+
{
219+
id: item.id,
220+
label: item.label,
221+
className: isSelected ? 'danger' : '',
222+
remove: () => {
223+
remove(item.id);
224+
return false;
225+
},
226+
select: () => {
227+
select(item.id);
228+
return false;
229+
},
230+
$key,
231+
},
232+
String(item.id)
233+
);
234+
newCache[item.id] = row;
235+
return row;
236+
})
237+
);
238+
}
239+
240+
new Block(
241+
stringToDOM(
242+
'<div class="container"><div class="jumbotron"><div class="row"><div class="col-md-6"><h1>Million</h1></div><div class="col-md-6"><div class="row"><div class="col-sm-6 smallpad"><button type="button" class="btn btn-primary btn-block" id="run">Create 1,000 rows</button></div><div class="col-sm-6 smallpad"><button type="button" class="btn btn-primary btn-block" id="runlots">Create 10,000 rows</button></div><div class="col-sm-6 smallpad"><button type="button" class="btn btn-primary btn-block" id="add">Append 1,000 rows</button></div><div class="col-sm-6 smallpad"><button type="button" class="btn btn-primary btn-block" id="update">Update every 10th row</button></div><div class="col-sm-6 smallpad"><button type="button" class="btn btn-primary btn-block" id="clear">Clear</button></div><div class="col-sm-6 smallpad"><button type="button" class="btn btn-primary btn-block" id="swaprows">Swap Rows</button></div></div></div></div></div><table class="table table-hover table-striped test-data"><tbody></tbody></table><span class="preloadicon glyphicon glyphicon-remove" aria-hidden="true"></span></div>'
243+
),
244+
[
245+
{
246+
path: [0, 0, 1, 0, 0, 0],
247+
edits: [
248+
{
249+
type: 3,
250+
name: 'onClick',
251+
listener: create1k,
252+
},
253+
],
254+
inits: [],
255+
},
256+
{
257+
path: [0, 0, 1, 0, 1, 0],
258+
edits: [
259+
{
260+
type: 3,
261+
name: 'onClick',
262+
listener: create10k,
263+
},
264+
],
265+
inits: [],
266+
},
267+
{
268+
path: [0, 0, 1, 0, 2, 0],
269+
edits: [
270+
{
271+
type: 3,
272+
name: 'onClick',
273+
listener: append1k,
274+
},
275+
],
276+
inits: [],
277+
},
278+
{
279+
path: [0, 0, 1, 0, 3, 0],
280+
edits: [
281+
{
282+
type: 3,
283+
name: 'onClick',
284+
listener: updateEvery10,
285+
},
286+
],
287+
inits: [],
288+
},
289+
{
290+
path: [0, 0, 1, 0, 4, 0],
291+
edits: [
292+
{
293+
type: 3,
294+
name: 'onClick',
295+
listener: () => {
296+
clear();
297+
update();
298+
return false;
299+
},
300+
},
301+
],
302+
inits: [],
303+
},
304+
{
305+
path: [0, 0, 1, 0, 5, 0],
306+
edits: [
307+
{
308+
type: 3,
309+
name: 'onClick',
310+
listener: swapRows,
311+
},
312+
],
313+
inits: [],
314+
},
315+
{
316+
path: [1, 0],
317+
edits: [
318+
{
319+
type: 2,
320+
hole: 'rows',
321+
index: 0,
322+
},
323+
],
324+
inits: [],
325+
},
326+
],
327+
{ rows: (main = fragment([])) },
328+
undefined,
329+
undefined
330+
).mount(document.getElementById('main'));
331+
332+
let oldCache = {};
333+
function update() {
334+
let newCache = {};
335+
main.patch(render(oldCache, newCache));
336+
oldCache = newCache;
337+
}

0 commit comments

Comments
 (0)