mtrl-addons 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{src/components/index.ts → dist/components/index.d.ts} +0 -2
- package/dist/components/vlist/config.d.ts +86 -0
- package/{src/components/vlist/constants.ts → dist/components/vlist/constants.d.ts} +10 -11
- package/dist/components/vlist/features/api.d.ts +7 -0
- package/{src/components/vlist/features/index.ts → dist/components/vlist/features/index.d.ts} +0 -2
- package/dist/components/vlist/features/selection.d.ts +6 -0
- package/dist/components/vlist/features/viewport.d.ts +9 -0
- package/dist/components/vlist/features.d.ts +31 -0
- package/{src/components/vlist/index.ts → dist/components/vlist/index.d.ts} +1 -10
- package/dist/components/vlist/types.d.ts +596 -0
- package/dist/components/vlist/vlist.d.ts +29 -0
- package/dist/core/compose/features/gestures/index.d.ts +86 -0
- package/dist/core/compose/features/gestures/longpress.d.ts +85 -0
- package/dist/core/compose/features/gestures/pan.d.ts +108 -0
- package/dist/core/compose/features/gestures/pinch.d.ts +111 -0
- package/dist/core/compose/features/gestures/rotate.d.ts +111 -0
- package/dist/core/compose/features/gestures/swipe.d.ts +149 -0
- package/dist/core/compose/features/gestures/tap.d.ts +79 -0
- package/{src/core/compose/features/index.ts → dist/core/compose/features/index.d.ts} +1 -2
- package/{src/core/compose/index.ts → dist/core/compose/index.d.ts} +2 -11
- package/{src/core/gestures/index.ts → dist/core/gestures/index.d.ts} +1 -20
- package/dist/core/gestures/longpress.d.ts +23 -0
- package/dist/core/gestures/manager.d.ts +14 -0
- package/dist/core/gestures/pan.d.ts +12 -0
- package/dist/core/gestures/pinch.d.ts +14 -0
- package/dist/core/gestures/rotate.d.ts +14 -0
- package/dist/core/gestures/swipe.d.ts +20 -0
- package/dist/core/gestures/tap.d.ts +12 -0
- package/dist/core/gestures/types.d.ts +320 -0
- package/dist/core/gestures/utils.d.ts +57 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/layout/config.d.ts +33 -0
- package/dist/core/layout/index.d.ts +51 -0
- package/dist/core/layout/jsx.d.ts +65 -0
- package/dist/core/layout/schema.d.ts +112 -0
- package/dist/core/layout/types.d.ts +69 -0
- package/dist/core/viewport/constants.d.ts +105 -0
- package/dist/core/viewport/features/base.d.ts +14 -0
- package/dist/core/viewport/features/collection.d.ts +41 -0
- package/dist/core/viewport/features/events.d.ts +13 -0
- package/{src/core/viewport/features/index.ts → dist/core/viewport/features/index.d.ts} +0 -7
- package/dist/core/viewport/features/item-size.d.ts +30 -0
- package/dist/core/viewport/features/loading.d.ts +34 -0
- package/dist/core/viewport/features/momentum.d.ts +17 -0
- package/dist/core/viewport/features/performance.d.ts +53 -0
- package/dist/core/viewport/features/placeholders.d.ts +38 -0
- package/dist/core/viewport/features/rendering.d.ts +16 -0
- package/dist/core/viewport/features/scrollbar.d.ts +26 -0
- package/dist/core/viewport/features/scrolling.d.ts +16 -0
- package/dist/core/viewport/features/utils.d.ts +43 -0
- package/dist/core/viewport/features/virtual.d.ts +18 -0
- package/{src/core/viewport/index.ts → dist/core/viewport/index.d.ts} +1 -17
- package/dist/core/viewport/types.d.ts +96 -0
- package/dist/core/viewport/utils/speed-tracker.d.ts +22 -0
- package/dist/core/viewport/viewport.d.ts +11 -0
- package/{src/index.ts → dist/index.d.ts} +0 -4
- package/dist/index.js +5143 -0
- package/dist/index.mjs +5111 -0
- package/dist/styles.css +254 -0
- package/dist/styles.css.map +1 -0
- package/package.json +5 -1
- package/.cursorrules +0 -117
- package/AI.md +0 -39
- package/CLAUDE.md +0 -882
- package/build.js +0 -377
- package/scripts/analyze-orphaned-functions.ts +0 -387
- package/scripts/debug/vlist-selection.ts +0 -121
- package/src/components/vlist/config.ts +0 -323
- package/src/components/vlist/features/api.ts +0 -626
- package/src/components/vlist/features/selection.ts +0 -436
- package/src/components/vlist/features/viewport.ts +0 -59
- package/src/components/vlist/features.ts +0 -112
- package/src/components/vlist/types.ts +0 -723
- package/src/components/vlist/vlist.ts +0 -92
- package/src/core/compose/features/gestures/index.ts +0 -227
- package/src/core/compose/features/gestures/longpress.ts +0 -383
- package/src/core/compose/features/gestures/pan.ts +0 -424
- package/src/core/compose/features/gestures/pinch.ts +0 -475
- package/src/core/compose/features/gestures/rotate.ts +0 -485
- package/src/core/compose/features/gestures/swipe.ts +0 -492
- package/src/core/compose/features/gestures/tap.ts +0 -334
- package/src/core/gestures/longpress.ts +0 -68
- package/src/core/gestures/manager.ts +0 -418
- package/src/core/gestures/pan.ts +0 -48
- package/src/core/gestures/pinch.ts +0 -58
- package/src/core/gestures/rotate.ts +0 -58
- package/src/core/gestures/swipe.ts +0 -66
- package/src/core/gestures/tap.ts +0 -45
- package/src/core/gestures/types.ts +0 -387
- package/src/core/gestures/utils.ts +0 -128
- package/src/core/index.ts +0 -43
- package/src/core/layout/config.ts +0 -102
- package/src/core/layout/index.ts +0 -168
- package/src/core/layout/jsx.ts +0 -174
- package/src/core/layout/schema.ts +0 -1044
- package/src/core/layout/types.ts +0 -95
- package/src/core/viewport/constants.ts +0 -145
- package/src/core/viewport/features/base.ts +0 -73
- package/src/core/viewport/features/collection.ts +0 -1182
- package/src/core/viewport/features/events.ts +0 -130
- package/src/core/viewport/features/item-size.ts +0 -271
- package/src/core/viewport/features/loading.ts +0 -263
- package/src/core/viewport/features/momentum.ts +0 -269
- package/src/core/viewport/features/performance.ts +0 -161
- package/src/core/viewport/features/placeholders.ts +0 -335
- package/src/core/viewport/features/rendering.ts +0 -962
- package/src/core/viewport/features/scrollbar.ts +0 -434
- package/src/core/viewport/features/scrolling.ts +0 -634
- package/src/core/viewport/features/utils.ts +0 -94
- package/src/core/viewport/features/virtual.ts +0 -525
- package/src/core/viewport/types.ts +0 -133
- package/src/core/viewport/utils/speed-tracker.ts +0 -79
- package/src/core/viewport/viewport.ts +0 -265
- package/test/benchmarks/layout/advanced.test.ts +0 -656
- package/test/benchmarks/layout/comparison.test.ts +0 -519
- package/test/benchmarks/layout/performance-comparison.test.ts +0 -274
- package/test/benchmarks/layout/real-components.test.ts +0 -733
- package/test/benchmarks/layout/simple.test.ts +0 -321
- package/test/benchmarks/layout/stress.test.ts +0 -990
- package/test/collection/basic.test.ts +0 -304
- package/test/components/vlist-selection.test.ts +0 -240
- package/test/components/vlist.test.ts +0 -63
- package/test/core/collection/adapter.test.ts +0 -161
- package/test/core/collection/collection.test.ts +0 -394
- package/test/core/layout/layout.test.ts +0 -201
- package/test/utils/dom-helpers.ts +0 -275
- package/test/utils/performance-helpers.ts +0 -392
- package/tsconfig.json +0 -20
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
// test/core/layout/benchmarks.test.ts - Layout Performance Benchmarks
|
|
2
|
-
import {
|
|
3
|
-
describe,
|
|
4
|
-
test,
|
|
5
|
-
expect,
|
|
6
|
-
beforeAll,
|
|
7
|
-
afterAll,
|
|
8
|
-
beforeEach,
|
|
9
|
-
afterEach,
|
|
10
|
-
} from "bun:test";
|
|
11
|
-
import { JSDOM } from "jsdom";
|
|
12
|
-
|
|
13
|
-
// Setup for DOM testing environment
|
|
14
|
-
let dom: JSDOM;
|
|
15
|
-
let window: Window;
|
|
16
|
-
let document: Document;
|
|
17
|
-
let originalGlobalDocument: any;
|
|
18
|
-
let originalGlobalWindow: any;
|
|
19
|
-
|
|
20
|
-
// Setup DOM environment before importing modules
|
|
21
|
-
beforeAll(() => {
|
|
22
|
-
// Create a new JSDOM instance
|
|
23
|
-
dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
|
|
24
|
-
url: "http://localhost/",
|
|
25
|
-
pretendToBeVisual: true,
|
|
26
|
-
resources: "usable",
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// Get window and document from jsdom
|
|
30
|
-
window = dom.window as any;
|
|
31
|
-
document = window.document;
|
|
32
|
-
|
|
33
|
-
// Store original globals
|
|
34
|
-
originalGlobalDocument = global.document;
|
|
35
|
-
originalGlobalWindow = global.window;
|
|
36
|
-
|
|
37
|
-
// Set globals to use jsdom
|
|
38
|
-
global.document = document;
|
|
39
|
-
global.window = window as any;
|
|
40
|
-
global.Element = (window as any).Element;
|
|
41
|
-
global.HTMLElement = (window as any).HTMLElement;
|
|
42
|
-
global.DocumentFragment = (window as any).DocumentFragment;
|
|
43
|
-
global.requestAnimationFrame = (window as any).requestAnimationFrame;
|
|
44
|
-
global.cancelAnimationFrame = (window as any).cancelAnimationFrame;
|
|
45
|
-
// Fix performance.now conflict - use custom timer
|
|
46
|
-
global.performance = {
|
|
47
|
-
now: () => Date.now(),
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
// Add missing DOM APIs
|
|
51
|
-
global.getComputedStyle =
|
|
52
|
-
(window as any).getComputedStyle ||
|
|
53
|
-
(() => ({
|
|
54
|
-
position: "static",
|
|
55
|
-
getPropertyValue: () => "",
|
|
56
|
-
}));
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
afterAll(() => {
|
|
60
|
-
// Restore original globals
|
|
61
|
-
global.document = originalGlobalDocument;
|
|
62
|
-
global.window = originalGlobalWindow;
|
|
63
|
-
|
|
64
|
-
// Clean up jsdom
|
|
65
|
-
window.close();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// Import layout systems after DOM setup
|
|
69
|
-
import {
|
|
70
|
-
createLayout as addonsLayout,
|
|
71
|
-
grid,
|
|
72
|
-
row,
|
|
73
|
-
stack,
|
|
74
|
-
performance as addonsPerformance,
|
|
75
|
-
} from "../../../src/core/layout";
|
|
76
|
-
|
|
77
|
-
// Mock mtrl createLayout for comparison
|
|
78
|
-
const mockMtrlLayout = (schema: any) => {
|
|
79
|
-
// Simple mock that creates basic DOM structure
|
|
80
|
-
const createElement = (options: any = {}) => {
|
|
81
|
-
const tag = options.tag || "div";
|
|
82
|
-
const element = document.createElement(tag);
|
|
83
|
-
if (options.class) element.className = options.class;
|
|
84
|
-
if (options.text || options.textContent) {
|
|
85
|
-
element.textContent = options.text || options.textContent;
|
|
86
|
-
}
|
|
87
|
-
return element;
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const processSchema = (items: any[], parent?: any): any => {
|
|
91
|
-
const layout: any = {};
|
|
92
|
-
let currentElement = null;
|
|
93
|
-
|
|
94
|
-
for (let i = 0; i < items.length; i++) {
|
|
95
|
-
const item = items[i];
|
|
96
|
-
|
|
97
|
-
if (typeof item === "string" && i === 0) {
|
|
98
|
-
// Tag name
|
|
99
|
-
currentElement = createElement({ tag: item });
|
|
100
|
-
layout.element = currentElement;
|
|
101
|
-
} else if (typeof item === "string" && i === 1) {
|
|
102
|
-
// Name
|
|
103
|
-
layout[item] = currentElement;
|
|
104
|
-
} else if (typeof item === "object" && !Array.isArray(item)) {
|
|
105
|
-
// Options
|
|
106
|
-
if (currentElement && item.class) {
|
|
107
|
-
currentElement.className = item.class;
|
|
108
|
-
}
|
|
109
|
-
if (currentElement && (item.text || item.textContent)) {
|
|
110
|
-
currentElement.textContent = item.text || item.textContent;
|
|
111
|
-
}
|
|
112
|
-
} else if (Array.isArray(item)) {
|
|
113
|
-
// Nested array
|
|
114
|
-
const childResult = processSchema(item, currentElement);
|
|
115
|
-
if (currentElement && childResult.element) {
|
|
116
|
-
currentElement.appendChild(childResult.element);
|
|
117
|
-
}
|
|
118
|
-
Object.assign(layout, childResult);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return {
|
|
123
|
-
layout,
|
|
124
|
-
element: layout.element,
|
|
125
|
-
component: layout,
|
|
126
|
-
get: (name: string) => layout[name] || null,
|
|
127
|
-
getAll: () => layout,
|
|
128
|
-
destroy: () => {
|
|
129
|
-
if (layout.element && layout.element.parentNode) {
|
|
130
|
-
layout.element.parentNode.removeChild(layout.element);
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
return processSchema(Array.isArray(schema) ? schema : [schema]);
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
describe("Layout Performance Benchmarks", () => {
|
|
140
|
-
let container: HTMLElement;
|
|
141
|
-
|
|
142
|
-
beforeEach(() => {
|
|
143
|
-
// Create fresh container for each test
|
|
144
|
-
container = document.createElement("div");
|
|
145
|
-
container.style.height = "400px";
|
|
146
|
-
container.style.overflow = "auto";
|
|
147
|
-
document.body.appendChild(container);
|
|
148
|
-
|
|
149
|
-
// Clear caches before each test
|
|
150
|
-
addonsPerformance.clearAll();
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
afterEach(() => {
|
|
154
|
-
// Cleanup container
|
|
155
|
-
if (container && container.parentNode) {
|
|
156
|
-
container.parentNode.removeChild(container);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
describe("Performance Environment", () => {
|
|
161
|
-
test("DOM environment is ready", () => {
|
|
162
|
-
expect(document).toBeDefined();
|
|
163
|
-
expect(document.createElement).toBeDefined();
|
|
164
|
-
expect(performance.now).toBeDefined();
|
|
165
|
-
expect(container).toBeDefined();
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
test("layout systems are available", () => {
|
|
169
|
-
expect(addonsLayout).toBeDefined();
|
|
170
|
-
expect(mockMtrlLayout).toBeDefined();
|
|
171
|
-
expect(addonsPerformance).toBeDefined();
|
|
172
|
-
});
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
describe("Basic Performance Comparison", () => {
|
|
176
|
-
test("simple layout creation speed", () => {
|
|
177
|
-
const iterations = 1000;
|
|
178
|
-
const schema = ["div", "test", { class: "simple-test" }];
|
|
179
|
-
|
|
180
|
-
// Test mtrl-addons
|
|
181
|
-
addonsPerformance.clearAll();
|
|
182
|
-
const addonsStart = performance.now();
|
|
183
|
-
for (let i = 0; i < iterations; i++) {
|
|
184
|
-
const layout = addonsLayout(schema);
|
|
185
|
-
layout.destroy();
|
|
186
|
-
}
|
|
187
|
-
const addonsEnd = performance.now();
|
|
188
|
-
const addonsTime = addonsEnd - addonsStart;
|
|
189
|
-
|
|
190
|
-
// Test mock mtrl
|
|
191
|
-
const mtrlStart = performance.now();
|
|
192
|
-
for (let i = 0; i < iterations; i++) {
|
|
193
|
-
const layout = mockMtrlLayout(schema);
|
|
194
|
-
layout.destroy();
|
|
195
|
-
}
|
|
196
|
-
const mtrlEnd = performance.now();
|
|
197
|
-
const mtrlTime = mtrlEnd - mtrlStart;
|
|
198
|
-
|
|
199
|
-
console.log(`\n📊 Simple Layout Performance (${iterations} iterations):`);
|
|
200
|
-
console.log(` mtrl-addons: ${addonsTime.toFixed(2)}ms`);
|
|
201
|
-
console.log(` mock-mtrl: ${mtrlTime.toFixed(2)}ms`);
|
|
202
|
-
console.log(` Difference: ${(addonsTime - mtrlTime).toFixed(2)}ms`);
|
|
203
|
-
console.log(` Ratio: ${(addonsTime / mtrlTime).toFixed(2)}x`);
|
|
204
|
-
|
|
205
|
-
expect(addonsTime).toBeGreaterThan(0);
|
|
206
|
-
expect(mtrlTime).toBeGreaterThan(0);
|
|
207
|
-
expect(addonsTime).toBeLessThan(5000); // Should complete in reasonable time
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
test("complex nested layout speed", () => {
|
|
211
|
-
const iterations = 500;
|
|
212
|
-
const complexSchema = [
|
|
213
|
-
"div",
|
|
214
|
-
"main",
|
|
215
|
-
{ class: "main-container" },
|
|
216
|
-
[
|
|
217
|
-
"div",
|
|
218
|
-
"header",
|
|
219
|
-
{ class: "header" },
|
|
220
|
-
["h1", "title", { text: "Title", class: "title" }],
|
|
221
|
-
[
|
|
222
|
-
"nav",
|
|
223
|
-
"nav",
|
|
224
|
-
{ class: "navigation" },
|
|
225
|
-
["a", "link1", { text: "Home", class: "nav-link" }],
|
|
226
|
-
["a", "link2", { text: "About", class: "nav-link" }],
|
|
227
|
-
],
|
|
228
|
-
],
|
|
229
|
-
[
|
|
230
|
-
"div",
|
|
231
|
-
"content",
|
|
232
|
-
{ class: "content" },
|
|
233
|
-
["p", "paragraph", { text: "Content paragraph", class: "text" }],
|
|
234
|
-
],
|
|
235
|
-
];
|
|
236
|
-
|
|
237
|
-
// Test mtrl-addons
|
|
238
|
-
addonsPerformance.clearAll();
|
|
239
|
-
const addonsStart = performance.now();
|
|
240
|
-
for (let i = 0; i < iterations; i++) {
|
|
241
|
-
const layout = addonsLayout(complexSchema);
|
|
242
|
-
layout.destroy();
|
|
243
|
-
}
|
|
244
|
-
const addonsEnd = performance.now();
|
|
245
|
-
const addonsTime = addonsEnd - addonsStart;
|
|
246
|
-
|
|
247
|
-
// Test mock mtrl
|
|
248
|
-
const mtrlStart = performance.now();
|
|
249
|
-
for (let i = 0; i < iterations; i++) {
|
|
250
|
-
const layout = mockMtrlLayout(complexSchema);
|
|
251
|
-
layout.destroy();
|
|
252
|
-
}
|
|
253
|
-
const mtrlEnd = performance.now();
|
|
254
|
-
const mtrlTime = mtrlEnd - mtrlStart;
|
|
255
|
-
|
|
256
|
-
console.log(
|
|
257
|
-
`\n📊 Complex Layout Performance (${iterations} iterations):`
|
|
258
|
-
);
|
|
259
|
-
console.log(` mtrl-addons: ${addonsTime.toFixed(2)}ms`);
|
|
260
|
-
console.log(` mock-mtrl: ${mtrlTime.toFixed(2)}ms`);
|
|
261
|
-
console.log(` Difference: ${(addonsTime - mtrlTime).toFixed(2)}ms`);
|
|
262
|
-
console.log(` Ratio: ${(addonsTime / mtrlTime).toFixed(2)}x`);
|
|
263
|
-
|
|
264
|
-
expect(addonsTime).toBeGreaterThan(0);
|
|
265
|
-
expect(mtrlTime).toBeGreaterThan(0);
|
|
266
|
-
});
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
describe("Cache Effectiveness", () => {
|
|
270
|
-
test("class name cache impact", () => {
|
|
271
|
-
const iterations = 1000;
|
|
272
|
-
const schema = [
|
|
273
|
-
"div",
|
|
274
|
-
"container",
|
|
275
|
-
{
|
|
276
|
-
layout: { type: "grid", columns: 3, gap: "1rem", align: "center" },
|
|
277
|
-
layoutItem: { span: 2, width: 6 },
|
|
278
|
-
},
|
|
279
|
-
];
|
|
280
|
-
|
|
281
|
-
// First run - cache empty
|
|
282
|
-
addonsPerformance.clearAll();
|
|
283
|
-
const coldStart = performance.now();
|
|
284
|
-
for (let i = 0; i < iterations; i++) {
|
|
285
|
-
const layout = addonsLayout(schema);
|
|
286
|
-
layout.destroy();
|
|
287
|
-
}
|
|
288
|
-
const coldEnd = performance.now();
|
|
289
|
-
const coldTime = coldEnd - coldStart;
|
|
290
|
-
|
|
291
|
-
// Second run - cache warmed
|
|
292
|
-
const warmStart = performance.now();
|
|
293
|
-
for (let i = 0; i < iterations; i++) {
|
|
294
|
-
const layout = addonsLayout(schema);
|
|
295
|
-
layout.destroy();
|
|
296
|
-
}
|
|
297
|
-
const warmEnd = performance.now();
|
|
298
|
-
const warmTime = warmEnd - warmStart;
|
|
299
|
-
|
|
300
|
-
const improvement = ((coldTime - warmTime) / coldTime) * 100;
|
|
301
|
-
|
|
302
|
-
console.log(`\n🚀 Cache Performance (${iterations} iterations):`);
|
|
303
|
-
console.log(` Cold cache: ${coldTime.toFixed(2)}ms`);
|
|
304
|
-
console.log(` Warm cache: ${warmTime.toFixed(2)}ms`);
|
|
305
|
-
console.log(` Improvement: ${improvement.toFixed(1)}%`);
|
|
306
|
-
|
|
307
|
-
expect(coldTime).toBeGreaterThan(0);
|
|
308
|
-
expect(warmTime).toBeGreaterThan(0);
|
|
309
|
-
expect(warmTime).toBeLessThanOrEqual(coldTime); // Should be same or faster
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
test("fragment pool effectiveness", () => {
|
|
313
|
-
const iterations = 2000;
|
|
314
|
-
const schema = [
|
|
315
|
-
"div",
|
|
316
|
-
"container",
|
|
317
|
-
{ class: "fragment-test" },
|
|
318
|
-
["span", "child1", { textContent: "Child 1" }],
|
|
319
|
-
["span", "child2", { textContent: "Child 2" }],
|
|
320
|
-
["span", "child3", { textContent: "Child 3" }],
|
|
321
|
-
];
|
|
322
|
-
|
|
323
|
-
// Clear pool and measure
|
|
324
|
-
addonsPerformance.clearAll();
|
|
325
|
-
const start = performance.now();
|
|
326
|
-
|
|
327
|
-
const layouts = [];
|
|
328
|
-
for (let i = 0; i < iterations; i++) {
|
|
329
|
-
layouts.push(addonsLayout(schema));
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Destroy all at once to test fragment recycling
|
|
333
|
-
for (const layout of layouts) {
|
|
334
|
-
layout.destroy();
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const end = performance.now();
|
|
338
|
-
const time = end - start;
|
|
339
|
-
|
|
340
|
-
console.log(`\n♻️ Fragment Pool Test (${iterations} layouts):`);
|
|
341
|
-
console.log(` Total time: ${time.toFixed(2)}ms`);
|
|
342
|
-
console.log(` Avg per layout: ${(time / iterations).toFixed(3)}ms`);
|
|
343
|
-
console.log(` Per layout: ${(time / iterations).toFixed(3)}ms`);
|
|
344
|
-
|
|
345
|
-
expect(time).toBeGreaterThan(0);
|
|
346
|
-
expect(time).toBeLessThan(10000); // Should be fast
|
|
347
|
-
});
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
describe("Convenience Functions Performance", () => {
|
|
351
|
-
test("grid layout convenience function", () => {
|
|
352
|
-
const iterations = 500;
|
|
353
|
-
|
|
354
|
-
const start = performance.now();
|
|
355
|
-
for (let i = 0; i < iterations; i++) {
|
|
356
|
-
const layout = grid(3, { gap: "1rem" });
|
|
357
|
-
layout.destroy();
|
|
358
|
-
}
|
|
359
|
-
const end = performance.now();
|
|
360
|
-
const time = end - start;
|
|
361
|
-
|
|
362
|
-
console.log(`\n📐 Grid Convenience Function (${iterations} iterations):`);
|
|
363
|
-
console.log(` Time: ${time.toFixed(2)}ms`);
|
|
364
|
-
console.log(` Avg per grid: ${(time / iterations).toFixed(3)}ms`);
|
|
365
|
-
|
|
366
|
-
expect(time).toBeGreaterThan(0);
|
|
367
|
-
expect(time).toBeLessThan(5000);
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
test("row and stack convenience functions", () => {
|
|
371
|
-
const iterations = 500;
|
|
372
|
-
|
|
373
|
-
const rowStart = performance.now();
|
|
374
|
-
for (let i = 0; i < iterations; i++) {
|
|
375
|
-
const layout = row({ gap: "1rem", mobileStack: true });
|
|
376
|
-
layout.destroy();
|
|
377
|
-
}
|
|
378
|
-
const rowEnd = performance.now();
|
|
379
|
-
const rowTime = rowEnd - rowStart;
|
|
380
|
-
|
|
381
|
-
const stackStart = performance.now();
|
|
382
|
-
for (let i = 0; i < iterations; i++) {
|
|
383
|
-
const layout = stack({ gap: "2rem" });
|
|
384
|
-
layout.destroy();
|
|
385
|
-
}
|
|
386
|
-
const stackEnd = performance.now();
|
|
387
|
-
const stackTime = stackEnd - stackStart;
|
|
388
|
-
|
|
389
|
-
console.log(`\n📦 Layout Functions (${iterations} each):`);
|
|
390
|
-
console.log(` Row layouts: ${rowTime.toFixed(2)}ms`);
|
|
391
|
-
console.log(` Stack layouts: ${stackTime.toFixed(2)}ms`);
|
|
392
|
-
console.log(` Total: ${(rowTime + stackTime).toFixed(2)}ms`);
|
|
393
|
-
|
|
394
|
-
expect(rowTime).toBeGreaterThan(0);
|
|
395
|
-
expect(stackTime).toBeGreaterThan(0);
|
|
396
|
-
});
|
|
397
|
-
});
|
|
398
|
-
|
|
399
|
-
describe("Memory Usage Patterns", () => {
|
|
400
|
-
test("large dataset handling", () => {
|
|
401
|
-
const itemCount = 1000;
|
|
402
|
-
const schema = ["div", "container", { class: "large-dataset" }];
|
|
403
|
-
|
|
404
|
-
// Add many children
|
|
405
|
-
for (let i = 0; i < itemCount; i++) {
|
|
406
|
-
schema.push([
|
|
407
|
-
"div",
|
|
408
|
-
`item${i}`,
|
|
409
|
-
{
|
|
410
|
-
class: "dataset-item",
|
|
411
|
-
textContent: `Item ${i}`,
|
|
412
|
-
layoutItem: { width: (i % 12) + 1 },
|
|
413
|
-
},
|
|
414
|
-
]);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
const start = performance.now();
|
|
418
|
-
const layout = addonsLayout(schema);
|
|
419
|
-
const end = performance.now();
|
|
420
|
-
const createTime = end - start;
|
|
421
|
-
|
|
422
|
-
const destroyStart = performance.now();
|
|
423
|
-
layout.destroy();
|
|
424
|
-
const destroyEnd = performance.now();
|
|
425
|
-
const destroyTime = destroyEnd - destroyStart;
|
|
426
|
-
|
|
427
|
-
console.log(`\n🗂️ Large Dataset (${itemCount} items):`);
|
|
428
|
-
console.log(` Creation: ${createTime.toFixed(2)}ms`);
|
|
429
|
-
console.log(` Cleanup: ${destroyTime.toFixed(2)}ms`);
|
|
430
|
-
console.log(` Total: ${(createTime + destroyTime).toFixed(2)}ms`);
|
|
431
|
-
|
|
432
|
-
expect(createTime).toBeGreaterThan(0);
|
|
433
|
-
expect(destroyTime).toBeGreaterThan(0);
|
|
434
|
-
expect(createTime).toBeLessThan(5000); // Should handle large datasets reasonably
|
|
435
|
-
});
|
|
436
|
-
});
|
|
437
|
-
|
|
438
|
-
describe("Performance Summary", () => {
|
|
439
|
-
test("overall performance metrics", () => {
|
|
440
|
-
const testCases = [
|
|
441
|
-
{
|
|
442
|
-
name: "Simple div",
|
|
443
|
-
schema: ["div", { class: "simple" }],
|
|
444
|
-
iterations: 1000,
|
|
445
|
-
},
|
|
446
|
-
{
|
|
447
|
-
name: "Text content",
|
|
448
|
-
schema: ["p", "text", { text: "Hello World", class: "text" }],
|
|
449
|
-
iterations: 1000,
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
name: "Nested structure",
|
|
453
|
-
schema: [
|
|
454
|
-
"div",
|
|
455
|
-
"parent",
|
|
456
|
-
{ class: "parent" },
|
|
457
|
-
["span", "child", { textContent: "Child" }],
|
|
458
|
-
],
|
|
459
|
-
iterations: 500,
|
|
460
|
-
},
|
|
461
|
-
{
|
|
462
|
-
name: "Layout classes",
|
|
463
|
-
schema: [
|
|
464
|
-
"div",
|
|
465
|
-
"layout",
|
|
466
|
-
{
|
|
467
|
-
layout: { type: "grid", columns: 2 },
|
|
468
|
-
layoutItem: { span: 1 },
|
|
469
|
-
},
|
|
470
|
-
],
|
|
471
|
-
iterations: 500,
|
|
472
|
-
},
|
|
473
|
-
];
|
|
474
|
-
|
|
475
|
-
console.log(`\n📋 Performance Summary:`);
|
|
476
|
-
console.log(`======================`);
|
|
477
|
-
|
|
478
|
-
const results = testCases.map((testCase) => {
|
|
479
|
-
addonsPerformance.clearAll();
|
|
480
|
-
|
|
481
|
-
const start = performance.now();
|
|
482
|
-
for (let i = 0; i < testCase.iterations; i++) {
|
|
483
|
-
const layout = addonsLayout(testCase.schema);
|
|
484
|
-
layout.destroy();
|
|
485
|
-
}
|
|
486
|
-
const end = performance.now();
|
|
487
|
-
const time = end - start;
|
|
488
|
-
const avgTime = time / testCase.iterations;
|
|
489
|
-
const opsPerSec = Math.round(testCase.iterations / (time / 1000));
|
|
490
|
-
|
|
491
|
-
console.log(
|
|
492
|
-
` ${testCase.name.padEnd(16)}: ${avgTime.toFixed(3)}ms per operation`
|
|
493
|
-
);
|
|
494
|
-
|
|
495
|
-
return { ...testCase, time, avgTime, opsPerSec };
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
const totalOps = results.reduce((sum, r) => sum + r.iterations, 0);
|
|
499
|
-
const totalTime = results.reduce((sum, r) => sum + r.time, 0);
|
|
500
|
-
const overallOpsPerSec = Math.round(totalOps / (totalTime / 1000));
|
|
501
|
-
|
|
502
|
-
console.log(
|
|
503
|
-
` ${"Total".padEnd(
|
|
504
|
-
16
|
|
505
|
-
)}: ${totalOps.toLocaleString()} operations in ${totalTime.toFixed(
|
|
506
|
-
0
|
|
507
|
-
)}ms`
|
|
508
|
-
);
|
|
509
|
-
console.log(
|
|
510
|
-
` ${"Overall".padEnd(16)}: ${(totalTime / totalOps).toFixed(
|
|
511
|
-
3
|
|
512
|
-
)}ms per operation`
|
|
513
|
-
);
|
|
514
|
-
|
|
515
|
-
expect(results.length).toBe(testCases.length);
|
|
516
|
-
expect(overallOpsPerSec).toBeGreaterThan(1000); // Should be reasonably fast
|
|
517
|
-
});
|
|
518
|
-
});
|
|
519
|
-
});
|