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,990 +0,0 @@
|
|
|
1
|
-
// test/core/layout/stress-benchmarks.test.ts - Stress Test Benchmarks
|
|
2
|
-
// @ts-nocheck
|
|
3
|
-
import { describe, test, expect, beforeAll, afterAll } from "bun:test";
|
|
4
|
-
import { JSDOM } from "jsdom";
|
|
5
|
-
|
|
6
|
-
// Setup for DOM testing environment
|
|
7
|
-
let dom: JSDOM;
|
|
8
|
-
let window: Window;
|
|
9
|
-
let document: Document;
|
|
10
|
-
let originalGlobalDocument: any;
|
|
11
|
-
let originalGlobalWindow: any;
|
|
12
|
-
|
|
13
|
-
// High-resolution timer
|
|
14
|
-
const hrTimer = (() => {
|
|
15
|
-
const start = Date.now();
|
|
16
|
-
return () => Date.now() - start;
|
|
17
|
-
})();
|
|
18
|
-
|
|
19
|
-
beforeAll(() => {
|
|
20
|
-
// Create JSDOM instance
|
|
21
|
-
dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
|
|
22
|
-
url: "http://localhost/",
|
|
23
|
-
pretendToBeVisual: true,
|
|
24
|
-
resources: "usable",
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
window = dom.window as any;
|
|
28
|
-
document = window.document;
|
|
29
|
-
|
|
30
|
-
// Store original globals
|
|
31
|
-
originalGlobalDocument = global.document;
|
|
32
|
-
originalGlobalWindow = global.window;
|
|
33
|
-
|
|
34
|
-
// Set globals
|
|
35
|
-
global.document = document;
|
|
36
|
-
global.window = window as any;
|
|
37
|
-
global.Element = (window as any).Element;
|
|
38
|
-
global.HTMLElement = (window as any).HTMLElement;
|
|
39
|
-
global.DocumentFragment = (window as any).DocumentFragment;
|
|
40
|
-
|
|
41
|
-
// Fix performance.now conflict
|
|
42
|
-
(global as any).performance = {
|
|
43
|
-
now: hrTimer,
|
|
44
|
-
mark: () => {},
|
|
45
|
-
measure: () => {},
|
|
46
|
-
getEntriesByType: () => [],
|
|
47
|
-
clearMarks: () => {},
|
|
48
|
-
clearMeasures: () => {},
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// Add DOM APIs
|
|
52
|
-
global.getComputedStyle = () => ({
|
|
53
|
-
position: "static",
|
|
54
|
-
getPropertyValue: () => "",
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
afterAll(() => {
|
|
59
|
-
// Restore globals
|
|
60
|
-
global.document = originalGlobalDocument;
|
|
61
|
-
global.window = originalGlobalWindow;
|
|
62
|
-
window.close();
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Import after DOM setup
|
|
66
|
-
import {
|
|
67
|
-
createLayout,
|
|
68
|
-
grid,
|
|
69
|
-
row,
|
|
70
|
-
stack,
|
|
71
|
-
performance as addonsPerformance,
|
|
72
|
-
} from "../../../src/core/layout";
|
|
73
|
-
|
|
74
|
-
describe("Stress Test Benchmarks", () => {
|
|
75
|
-
beforeAll(() => {
|
|
76
|
-
// Clear all caches before stress tests
|
|
77
|
-
addonsPerformance.clearAll();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("Massive Layout Tests", () => {
|
|
81
|
-
test.skip("complex layout with many components", () => {
|
|
82
|
-
// Create a realistic e-commerce product page with many components
|
|
83
|
-
const createProductPageSchema = () => {
|
|
84
|
-
const schema = [
|
|
85
|
-
"div",
|
|
86
|
-
"product-page",
|
|
87
|
-
{
|
|
88
|
-
layout: { type: "grid", columns: 12, gap: "1rem" },
|
|
89
|
-
class: "product-page",
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
// Header section
|
|
93
|
-
[
|
|
94
|
-
"header",
|
|
95
|
-
"header",
|
|
96
|
-
{
|
|
97
|
-
layoutItem: { span: 12 },
|
|
98
|
-
layout: { type: "row", gap: "1rem", align: "center" },
|
|
99
|
-
},
|
|
100
|
-
["div", "logo", { class: "logo", textContent: "Brand" }],
|
|
101
|
-
[
|
|
102
|
-
"nav",
|
|
103
|
-
"nav",
|
|
104
|
-
{
|
|
105
|
-
layout: { type: "row", gap: "0.5rem" },
|
|
106
|
-
class: "navigation",
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
["div", "search", { class: "search-bar" }],
|
|
110
|
-
["div", "cart", { class: "cart-icon" }],
|
|
111
|
-
],
|
|
112
|
-
|
|
113
|
-
// Breadcrumbs
|
|
114
|
-
[
|
|
115
|
-
"nav",
|
|
116
|
-
"breadcrumbs",
|
|
117
|
-
{
|
|
118
|
-
layoutItem: { span: 12 },
|
|
119
|
-
layout: { type: "row", gap: "0.25rem" },
|
|
120
|
-
class: "breadcrumbs",
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
|
|
124
|
-
// Product gallery
|
|
125
|
-
[
|
|
126
|
-
"div",
|
|
127
|
-
"gallery",
|
|
128
|
-
{
|
|
129
|
-
layoutItem: { span: 6, md: 7 },
|
|
130
|
-
layout: { type: "stack", gap: "1rem" },
|
|
131
|
-
class: "product-gallery",
|
|
132
|
-
},
|
|
133
|
-
["div", "main-image", { class: "main-product-image" }],
|
|
134
|
-
[
|
|
135
|
-
"div",
|
|
136
|
-
"thumbnails",
|
|
137
|
-
{
|
|
138
|
-
layout: { type: "row", gap: "0.5rem" },
|
|
139
|
-
class: "image-thumbnails",
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
],
|
|
143
|
-
|
|
144
|
-
// Product info
|
|
145
|
-
[
|
|
146
|
-
"div",
|
|
147
|
-
"product-info",
|
|
148
|
-
{
|
|
149
|
-
layoutItem: { span: 6, md: 5 },
|
|
150
|
-
layout: { type: "stack", gap: "1.5rem" },
|
|
151
|
-
class: "product-details",
|
|
152
|
-
},
|
|
153
|
-
[
|
|
154
|
-
"h1",
|
|
155
|
-
"title",
|
|
156
|
-
{ class: "product-title", textContent: "Amazing Product" },
|
|
157
|
-
],
|
|
158
|
-
[
|
|
159
|
-
"div",
|
|
160
|
-
"rating",
|
|
161
|
-
{
|
|
162
|
-
layout: { type: "row", gap: "0.5rem", align: "center" },
|
|
163
|
-
class: "product-rating",
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
["div", "price", { class: "product-price", textContent: "$99.99" }],
|
|
167
|
-
[
|
|
168
|
-
"div",
|
|
169
|
-
"variants",
|
|
170
|
-
{
|
|
171
|
-
layout: { type: "stack", gap: "1rem" },
|
|
172
|
-
class: "product-variants",
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
[
|
|
176
|
-
"div",
|
|
177
|
-
"actions",
|
|
178
|
-
{
|
|
179
|
-
layout: { type: "stack", gap: "0.75rem" },
|
|
180
|
-
class: "product-actions",
|
|
181
|
-
},
|
|
182
|
-
],
|
|
183
|
-
],
|
|
184
|
-
|
|
185
|
-
// Product description tabs
|
|
186
|
-
[
|
|
187
|
-
"div",
|
|
188
|
-
"tabs-section",
|
|
189
|
-
{
|
|
190
|
-
layoutItem: { span: 12 },
|
|
191
|
-
layout: { type: "stack", gap: "1rem" },
|
|
192
|
-
class: "product-tabs",
|
|
193
|
-
},
|
|
194
|
-
[
|
|
195
|
-
"div",
|
|
196
|
-
"tab-nav",
|
|
197
|
-
{
|
|
198
|
-
layout: { type: "row", gap: "1rem" },
|
|
199
|
-
class: "tab-navigation",
|
|
200
|
-
},
|
|
201
|
-
],
|
|
202
|
-
["div", "tab-content", { class: "tab-content-area" }],
|
|
203
|
-
],
|
|
204
|
-
|
|
205
|
-
// Reviews section
|
|
206
|
-
[
|
|
207
|
-
"section",
|
|
208
|
-
"reviews",
|
|
209
|
-
{
|
|
210
|
-
layoutItem: { span: 12 },
|
|
211
|
-
layout: { type: "stack", gap: "1.5rem" },
|
|
212
|
-
class: "reviews-section",
|
|
213
|
-
},
|
|
214
|
-
["h2", "reviews-title", { textContent: "Customer Reviews" }],
|
|
215
|
-
[
|
|
216
|
-
"div",
|
|
217
|
-
"review-summary",
|
|
218
|
-
{
|
|
219
|
-
layout: { type: "row", gap: "2rem" },
|
|
220
|
-
class: "review-summary",
|
|
221
|
-
},
|
|
222
|
-
],
|
|
223
|
-
[
|
|
224
|
-
"div",
|
|
225
|
-
"review-list",
|
|
226
|
-
{
|
|
227
|
-
layout: { type: "stack", gap: "1rem" },
|
|
228
|
-
class: "review-list",
|
|
229
|
-
},
|
|
230
|
-
],
|
|
231
|
-
],
|
|
232
|
-
|
|
233
|
-
// Related products
|
|
234
|
-
[
|
|
235
|
-
"section",
|
|
236
|
-
"related",
|
|
237
|
-
{
|
|
238
|
-
layoutItem: { span: 12 },
|
|
239
|
-
layout: { type: "stack", gap: "1rem" },
|
|
240
|
-
class: "related-products",
|
|
241
|
-
},
|
|
242
|
-
["h2", "related-title", { textContent: "Related Products" }],
|
|
243
|
-
[
|
|
244
|
-
"div",
|
|
245
|
-
"product-grid",
|
|
246
|
-
{
|
|
247
|
-
layout: { type: "grid", columns: 4, gap: "1rem" },
|
|
248
|
-
class: "related-grid",
|
|
249
|
-
},
|
|
250
|
-
],
|
|
251
|
-
],
|
|
252
|
-
|
|
253
|
-
// Footer
|
|
254
|
-
[
|
|
255
|
-
"footer",
|
|
256
|
-
"footer",
|
|
257
|
-
{
|
|
258
|
-
layoutItem: { span: 12 },
|
|
259
|
-
layout: { type: "grid", columns: 4, gap: "2rem" },
|
|
260
|
-
class: "site-footer",
|
|
261
|
-
},
|
|
262
|
-
],
|
|
263
|
-
];
|
|
264
|
-
|
|
265
|
-
// Add multiple nav items
|
|
266
|
-
const navItems = ["Home", "Products", "About", "Contact", "Support"];
|
|
267
|
-
navItems.forEach((item, i) => {
|
|
268
|
-
schema[2][6].push([
|
|
269
|
-
"a",
|
|
270
|
-
`nav-${i}`,
|
|
271
|
-
{
|
|
272
|
-
textContent: item,
|
|
273
|
-
class: "nav-link",
|
|
274
|
-
},
|
|
275
|
-
]);
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
// Add breadcrumb items
|
|
279
|
-
const breadcrumbs = ["Home", "Electronics", "Smartphones", "iPhone"];
|
|
280
|
-
breadcrumbs.forEach((crumb, i) => {
|
|
281
|
-
schema[4].push([
|
|
282
|
-
"span",
|
|
283
|
-
`crumb-${i}`,
|
|
284
|
-
{
|
|
285
|
-
textContent: crumb,
|
|
286
|
-
class: "breadcrumb-item",
|
|
287
|
-
},
|
|
288
|
-
]);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
// Add thumbnail images
|
|
292
|
-
for (let i = 0; i < 6; i++) {
|
|
293
|
-
schema[5][6][2].push([
|
|
294
|
-
"img",
|
|
295
|
-
`thumb-${i}`,
|
|
296
|
-
{
|
|
297
|
-
class: "thumbnail-image",
|
|
298
|
-
layoutItem: { width: 2 },
|
|
299
|
-
},
|
|
300
|
-
]);
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Add rating stars
|
|
304
|
-
for (let i = 0; i < 5; i++) {
|
|
305
|
-
schema[6][8][2].push([
|
|
306
|
-
"span",
|
|
307
|
-
`star-${i}`,
|
|
308
|
-
{
|
|
309
|
-
class: "rating-star",
|
|
310
|
-
textContent: "★",
|
|
311
|
-
},
|
|
312
|
-
]);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// Add variant options
|
|
316
|
-
const variants = ["Color", "Size", "Storage"];
|
|
317
|
-
variants.forEach((variant, i) => {
|
|
318
|
-
schema[6][10].push([
|
|
319
|
-
"div",
|
|
320
|
-
`variant-${i}`,
|
|
321
|
-
{
|
|
322
|
-
layout: { type: "stack", gap: "0.5rem" },
|
|
323
|
-
class: "variant-group",
|
|
324
|
-
},
|
|
325
|
-
["label", `variant-label-${i}`, { textContent: variant }],
|
|
326
|
-
[
|
|
327
|
-
"div",
|
|
328
|
-
`variant-options-${i}`,
|
|
329
|
-
{
|
|
330
|
-
layout: { type: "row", gap: "0.5rem" },
|
|
331
|
-
class: "variant-options",
|
|
332
|
-
},
|
|
333
|
-
],
|
|
334
|
-
]);
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
// Add action buttons
|
|
338
|
-
const actions = ["Add to Cart", "Buy Now", "Add to Wishlist", "Share"];
|
|
339
|
-
actions.forEach((action, i) => {
|
|
340
|
-
schema[6][11].push([
|
|
341
|
-
"button",
|
|
342
|
-
`action-${i}`,
|
|
343
|
-
{
|
|
344
|
-
textContent: action,
|
|
345
|
-
class: `action-btn ${i === 0 ? "primary" : "secondary"}`,
|
|
346
|
-
},
|
|
347
|
-
]);
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
// Add tab navigation
|
|
351
|
-
const tabs = ["Description", "Specifications", "Shipping", "Returns"];
|
|
352
|
-
tabs.forEach((tab, i) => {
|
|
353
|
-
schema[7][2].push([
|
|
354
|
-
"button",
|
|
355
|
-
`tab-${i}`,
|
|
356
|
-
{
|
|
357
|
-
textContent: tab,
|
|
358
|
-
class: "tab-button",
|
|
359
|
-
},
|
|
360
|
-
]);
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
// Add multiple reviews
|
|
364
|
-
for (let i = 0; i < 8; i++) {
|
|
365
|
-
schema[8][3].push([
|
|
366
|
-
"div",
|
|
367
|
-
`review-${i}`,
|
|
368
|
-
{
|
|
369
|
-
layout: { type: "stack", gap: "0.5rem" },
|
|
370
|
-
class: "review-item",
|
|
371
|
-
},
|
|
372
|
-
[
|
|
373
|
-
"div",
|
|
374
|
-
`review-header-${i}`,
|
|
375
|
-
{
|
|
376
|
-
layout: { type: "row", gap: "1rem", align: "center" },
|
|
377
|
-
class: "review-header",
|
|
378
|
-
},
|
|
379
|
-
],
|
|
380
|
-
[
|
|
381
|
-
"p",
|
|
382
|
-
`review-text-${i}`,
|
|
383
|
-
{
|
|
384
|
-
textContent: "Great product, highly recommended!",
|
|
385
|
-
class: "review-text",
|
|
386
|
-
},
|
|
387
|
-
],
|
|
388
|
-
]);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Add related products
|
|
392
|
-
for (let i = 0; i < 8; i++) {
|
|
393
|
-
schema[9][2].push([
|
|
394
|
-
"div",
|
|
395
|
-
`related-${i}`,
|
|
396
|
-
{
|
|
397
|
-
layout: { type: "stack", gap: "0.5rem" },
|
|
398
|
-
class: "related-product",
|
|
399
|
-
layoutItem: { span: 1 },
|
|
400
|
-
},
|
|
401
|
-
["img", `related-img-${i}`, { class: "related-image" }],
|
|
402
|
-
[
|
|
403
|
-
"h3",
|
|
404
|
-
`related-title-${i}`,
|
|
405
|
-
{
|
|
406
|
-
textContent: `Product ${i + 1}`,
|
|
407
|
-
class: "related-title",
|
|
408
|
-
},
|
|
409
|
-
],
|
|
410
|
-
[
|
|
411
|
-
"span",
|
|
412
|
-
`related-price-${i}`,
|
|
413
|
-
{
|
|
414
|
-
textContent: `$${(Math.random() * 100 + 20).toFixed(2)}`,
|
|
415
|
-
class: "related-price",
|
|
416
|
-
},
|
|
417
|
-
],
|
|
418
|
-
]);
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
// Add footer sections
|
|
422
|
-
const footerSections = ["Company", "Support", "Legal", "Connect"];
|
|
423
|
-
footerSections.forEach((section, i) => {
|
|
424
|
-
schema[10].push([
|
|
425
|
-
"div",
|
|
426
|
-
`footer-${i}`,
|
|
427
|
-
{
|
|
428
|
-
layout: { type: "stack", gap: "0.75rem" },
|
|
429
|
-
class: "footer-section",
|
|
430
|
-
},
|
|
431
|
-
[
|
|
432
|
-
"h4",
|
|
433
|
-
`footer-title-${i}`,
|
|
434
|
-
{
|
|
435
|
-
textContent: section,
|
|
436
|
-
class: "footer-title",
|
|
437
|
-
},
|
|
438
|
-
],
|
|
439
|
-
]);
|
|
440
|
-
|
|
441
|
-
// Add footer links
|
|
442
|
-
for (let j = 0; j < 5; j++) {
|
|
443
|
-
schema[10][i + 1].push([
|
|
444
|
-
"a",
|
|
445
|
-
`footer-link-${i}-${j}`,
|
|
446
|
-
{
|
|
447
|
-
textContent: `${section} Link ${j + 1}`,
|
|
448
|
-
class: "footer-link",
|
|
449
|
-
},
|
|
450
|
-
]);
|
|
451
|
-
}
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
return schema;
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
const iterations = 100;
|
|
458
|
-
console.log(`\n🏪 E-commerce Product Page (${iterations} pages):`);
|
|
459
|
-
console.log(` Components per page: ~120 elements`);
|
|
460
|
-
console.log(` Total components: ${iterations * 120} elements`);
|
|
461
|
-
|
|
462
|
-
addonsPerformance.clearAll();
|
|
463
|
-
|
|
464
|
-
const start = hrTimer();
|
|
465
|
-
const layouts = [];
|
|
466
|
-
|
|
467
|
-
for (let i = 0; i < iterations; i++) {
|
|
468
|
-
layouts.push(createLayout(createProductPageSchema()));
|
|
469
|
-
}
|
|
470
|
-
const createTime = hrTimer() - start;
|
|
471
|
-
|
|
472
|
-
const destroyStart = hrTimer();
|
|
473
|
-
layouts.forEach((layout) => layout.destroy());
|
|
474
|
-
const destroyTime = hrTimer() - destroyStart;
|
|
475
|
-
|
|
476
|
-
const totalTime = createTime + destroyTime;
|
|
477
|
-
const avgTimePerPage = totalTime / iterations;
|
|
478
|
-
const totalComponents = iterations * 120;
|
|
479
|
-
|
|
480
|
-
console.log(` Creation: ${createTime.toFixed(2)}ms`);
|
|
481
|
-
console.log(` Cleanup: ${destroyTime.toFixed(2)}ms`);
|
|
482
|
-
console.log(` Total: ${totalTime.toFixed(2)}ms`);
|
|
483
|
-
console.log(` Per page: ${avgTimePerPage.toFixed(3)}ms`);
|
|
484
|
-
console.log(
|
|
485
|
-
` Per component: ${(totalTime / totalComponents).toFixed(4)}ms`
|
|
486
|
-
);
|
|
487
|
-
|
|
488
|
-
expect(totalTime).toBeLessThan(10000); // Should complete within 10 seconds
|
|
489
|
-
expect(avgTimePerPage).toBeLessThan(100); // Should be under 100ms per page
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
test("massive data table with 1000 rows", () => {
|
|
493
|
-
const createDataTableSchema = (rows: number) => {
|
|
494
|
-
// Start with the main container and header
|
|
495
|
-
const schema = [
|
|
496
|
-
"div",
|
|
497
|
-
"data-table",
|
|
498
|
-
{
|
|
499
|
-
layout: { type: "stack", gap: "1rem" },
|
|
500
|
-
class: "data-table-container",
|
|
501
|
-
},
|
|
502
|
-
|
|
503
|
-
// Table header
|
|
504
|
-
[
|
|
505
|
-
"div",
|
|
506
|
-
"table-header",
|
|
507
|
-
{
|
|
508
|
-
layout: { type: "row", gap: "0px" },
|
|
509
|
-
class: "table-header",
|
|
510
|
-
},
|
|
511
|
-
[
|
|
512
|
-
"div",
|
|
513
|
-
"col-id",
|
|
514
|
-
{
|
|
515
|
-
class: "table-cell header",
|
|
516
|
-
textContent: "ID",
|
|
517
|
-
layoutItem: { width: 1 },
|
|
518
|
-
},
|
|
519
|
-
],
|
|
520
|
-
[
|
|
521
|
-
"div",
|
|
522
|
-
"col-name",
|
|
523
|
-
{
|
|
524
|
-
class: "table-cell header",
|
|
525
|
-
textContent: "Name",
|
|
526
|
-
layoutItem: { width: 3 },
|
|
527
|
-
},
|
|
528
|
-
],
|
|
529
|
-
[
|
|
530
|
-
"div",
|
|
531
|
-
"col-email",
|
|
532
|
-
{
|
|
533
|
-
class: "table-cell header",
|
|
534
|
-
textContent: "Email",
|
|
535
|
-
layoutItem: { width: 4 },
|
|
536
|
-
},
|
|
537
|
-
],
|
|
538
|
-
[
|
|
539
|
-
"div",
|
|
540
|
-
"col-status",
|
|
541
|
-
{
|
|
542
|
-
class: "table-cell header",
|
|
543
|
-
textContent: "Status",
|
|
544
|
-
layoutItem: { width: 2 },
|
|
545
|
-
},
|
|
546
|
-
],
|
|
547
|
-
[
|
|
548
|
-
"div",
|
|
549
|
-
"col-actions",
|
|
550
|
-
{
|
|
551
|
-
class: "table-cell header",
|
|
552
|
-
textContent: "Actions",
|
|
553
|
-
layoutItem: { width: 2 },
|
|
554
|
-
},
|
|
555
|
-
],
|
|
556
|
-
],
|
|
557
|
-
];
|
|
558
|
-
|
|
559
|
-
// Add table rows directly to schema
|
|
560
|
-
for (let i = 0; i < rows; i++) {
|
|
561
|
-
const rowSchema = [
|
|
562
|
-
"div",
|
|
563
|
-
`row-${i}`,
|
|
564
|
-
{
|
|
565
|
-
layout: { type: "row", gap: "0px" },
|
|
566
|
-
class: `table-row ${i % 2 === 0 ? "even" : "odd"}`,
|
|
567
|
-
},
|
|
568
|
-
[
|
|
569
|
-
"div",
|
|
570
|
-
`cell-id-${i}`,
|
|
571
|
-
{
|
|
572
|
-
class: "table-cell",
|
|
573
|
-
textContent: `${i + 1}`,
|
|
574
|
-
layoutItem: { width: 1 },
|
|
575
|
-
},
|
|
576
|
-
],
|
|
577
|
-
[
|
|
578
|
-
"div",
|
|
579
|
-
`cell-name-${i}`,
|
|
580
|
-
{
|
|
581
|
-
class: "table-cell",
|
|
582
|
-
textContent: `User ${i + 1}`,
|
|
583
|
-
layoutItem: { width: 3 },
|
|
584
|
-
},
|
|
585
|
-
],
|
|
586
|
-
[
|
|
587
|
-
"div",
|
|
588
|
-
`cell-email-${i}`,
|
|
589
|
-
{
|
|
590
|
-
class: "table-cell",
|
|
591
|
-
textContent: `user${i + 1}@example.com`,
|
|
592
|
-
layoutItem: { width: 4 },
|
|
593
|
-
},
|
|
594
|
-
],
|
|
595
|
-
[
|
|
596
|
-
"div",
|
|
597
|
-
`cell-status-${i}`,
|
|
598
|
-
{
|
|
599
|
-
class: "table-cell",
|
|
600
|
-
textContent: i % 3 === 0 ? "Active" : "Inactive",
|
|
601
|
-
layoutItem: { width: 2 },
|
|
602
|
-
},
|
|
603
|
-
],
|
|
604
|
-
[
|
|
605
|
-
"div",
|
|
606
|
-
`cell-actions-${i}`,
|
|
607
|
-
{
|
|
608
|
-
layout: { type: "row", gap: "0.25rem" },
|
|
609
|
-
class: "table-cell actions",
|
|
610
|
-
layoutItem: { width: 2 },
|
|
611
|
-
},
|
|
612
|
-
["button", `edit-${i}`, { class: "btn-sm", textContent: "Edit" }],
|
|
613
|
-
[
|
|
614
|
-
"button",
|
|
615
|
-
`delete-${i}`,
|
|
616
|
-
{ class: "btn-sm danger", textContent: "Delete" },
|
|
617
|
-
],
|
|
618
|
-
],
|
|
619
|
-
];
|
|
620
|
-
|
|
621
|
-
schema.push(rowSchema);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
return schema;
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
const rowCount = 1000;
|
|
628
|
-
const iterations = 5; // Fewer iterations due to size
|
|
629
|
-
|
|
630
|
-
console.log(
|
|
631
|
-
`\n📊 Massive Data Table (${iterations} tables × ${rowCount} rows):`
|
|
632
|
-
);
|
|
633
|
-
console.log(` Components per table: ~${rowCount * 7} elements`);
|
|
634
|
-
console.log(` Total components: ${iterations * rowCount * 7} elements`);
|
|
635
|
-
|
|
636
|
-
addonsPerformance.clearAll();
|
|
637
|
-
|
|
638
|
-
const start = hrTimer();
|
|
639
|
-
const layouts = [];
|
|
640
|
-
|
|
641
|
-
for (let i = 0; i < iterations; i++) {
|
|
642
|
-
layouts.push(createLayout(createDataTableSchema(rowCount)));
|
|
643
|
-
}
|
|
644
|
-
const createTime = hrTimer() - start;
|
|
645
|
-
|
|
646
|
-
const destroyStart = hrTimer();
|
|
647
|
-
layouts.forEach((layout) => layout.destroy());
|
|
648
|
-
const destroyTime = hrTimer() - destroyStart;
|
|
649
|
-
|
|
650
|
-
const totalTime = createTime + destroyTime;
|
|
651
|
-
const avgTimePerTable = totalTime / iterations;
|
|
652
|
-
const totalComponents = iterations * rowCount * 7;
|
|
653
|
-
|
|
654
|
-
console.log(` Creation: ${createTime.toFixed(2)}ms`);
|
|
655
|
-
console.log(` Cleanup: ${destroyTime.toFixed(2)}ms`);
|
|
656
|
-
console.log(` Total: ${totalTime.toFixed(2)}ms`);
|
|
657
|
-
console.log(` Per table: ${avgTimePerTable.toFixed(3)}ms`);
|
|
658
|
-
console.log(
|
|
659
|
-
` Per row: ${(totalTime / (iterations * rowCount)).toFixed(4)}ms`
|
|
660
|
-
);
|
|
661
|
-
console.log(
|
|
662
|
-
` Per component: ${(totalTime / totalComponents).toFixed(5)}ms`
|
|
663
|
-
);
|
|
664
|
-
|
|
665
|
-
expect(totalTime).toBeLessThan(30000); // Should complete within 30 seconds
|
|
666
|
-
expect(avgTimePerTable).toBeLessThan(6000); // Should be under 6 seconds per table
|
|
667
|
-
});
|
|
668
|
-
});
|
|
669
|
-
|
|
670
|
-
describe("High Volume Tests", () => {
|
|
671
|
-
test("creating 5000 medium layouts rapidly", () => {
|
|
672
|
-
const mediumLayoutSchema = [
|
|
673
|
-
"div",
|
|
674
|
-
"card",
|
|
675
|
-
{
|
|
676
|
-
layout: { type: "stack", gap: "1rem" },
|
|
677
|
-
class: "card-component",
|
|
678
|
-
},
|
|
679
|
-
[
|
|
680
|
-
"header",
|
|
681
|
-
"card-header",
|
|
682
|
-
{
|
|
683
|
-
layout: { type: "row", gap: "0.5rem", align: "center" },
|
|
684
|
-
class: "card-header",
|
|
685
|
-
},
|
|
686
|
-
["h3", "title", { textContent: "Card Title", class: "card-title" }],
|
|
687
|
-
["button", "menu", { class: "menu-btn", textContent: "⋯" }],
|
|
688
|
-
],
|
|
689
|
-
[
|
|
690
|
-
"div",
|
|
691
|
-
"card-body",
|
|
692
|
-
{
|
|
693
|
-
layout: { type: "stack", gap: "0.75rem" },
|
|
694
|
-
class: "card-body",
|
|
695
|
-
},
|
|
696
|
-
[
|
|
697
|
-
"p",
|
|
698
|
-
"description",
|
|
699
|
-
{
|
|
700
|
-
textContent:
|
|
701
|
-
"This is a medium complexity card with multiple elements.",
|
|
702
|
-
class: "card-description",
|
|
703
|
-
},
|
|
704
|
-
],
|
|
705
|
-
[
|
|
706
|
-
"div",
|
|
707
|
-
"stats",
|
|
708
|
-
{
|
|
709
|
-
layout: { type: "row", gap: "1rem" },
|
|
710
|
-
class: "card-stats",
|
|
711
|
-
},
|
|
712
|
-
["span", "stat1", { textContent: "24", class: "stat-value" }],
|
|
713
|
-
["span", "stat2", { textContent: "1.2k", class: "stat-value" }],
|
|
714
|
-
["span", "stat3", { textContent: "95%", class: "stat-value" }],
|
|
715
|
-
],
|
|
716
|
-
[
|
|
717
|
-
"div",
|
|
718
|
-
"tags",
|
|
719
|
-
{
|
|
720
|
-
layout: { type: "row", gap: "0.25rem" },
|
|
721
|
-
class: "card-tags",
|
|
722
|
-
},
|
|
723
|
-
["span", "tag1", { textContent: "React", class: "tag" }],
|
|
724
|
-
["span", "tag2", { textContent: "TypeScript", class: "tag" }],
|
|
725
|
-
["span", "tag3", { textContent: "Performance", class: "tag" }],
|
|
726
|
-
],
|
|
727
|
-
],
|
|
728
|
-
[
|
|
729
|
-
"footer",
|
|
730
|
-
"card-footer",
|
|
731
|
-
{
|
|
732
|
-
layout: { type: "row", gap: "0.5rem", justify: "space-between" },
|
|
733
|
-
class: "card-footer",
|
|
734
|
-
},
|
|
735
|
-
[
|
|
736
|
-
"span",
|
|
737
|
-
"timestamp",
|
|
738
|
-
{ textContent: "2 hours ago", class: "timestamp" },
|
|
739
|
-
],
|
|
740
|
-
[
|
|
741
|
-
"div",
|
|
742
|
-
"actions",
|
|
743
|
-
{
|
|
744
|
-
layout: { type: "row", gap: "0.25rem" },
|
|
745
|
-
class: "card-actions",
|
|
746
|
-
},
|
|
747
|
-
["button", "like", { textContent: "♥", class: "action-btn" }],
|
|
748
|
-
["button", "share", { textContent: "↗", class: "action-btn" }],
|
|
749
|
-
["button", "bookmark", { textContent: "⊞", class: "action-btn" }],
|
|
750
|
-
],
|
|
751
|
-
],
|
|
752
|
-
];
|
|
753
|
-
|
|
754
|
-
const iterations = 5000;
|
|
755
|
-
console.log(`\n🚀 High Volume Card Creation (${iterations} cards):`);
|
|
756
|
-
console.log(` Components per card: ~18 elements`);
|
|
757
|
-
console.log(` Total components: ${iterations * 18} elements`);
|
|
758
|
-
|
|
759
|
-
addonsPerformance.clearAll();
|
|
760
|
-
|
|
761
|
-
const start = hrTimer();
|
|
762
|
-
const layouts = [];
|
|
763
|
-
|
|
764
|
-
for (let i = 0; i < iterations; i++) {
|
|
765
|
-
layouts.push(createLayout(mediumLayoutSchema));
|
|
766
|
-
}
|
|
767
|
-
const createTime = hrTimer() - start;
|
|
768
|
-
|
|
769
|
-
const destroyStart = hrTimer();
|
|
770
|
-
layouts.forEach((layout) => layout.destroy());
|
|
771
|
-
const destroyTime = hrTimer() - destroyStart;
|
|
772
|
-
|
|
773
|
-
const totalTime = createTime + destroyTime;
|
|
774
|
-
const avgTimePerCard = totalTime / iterations;
|
|
775
|
-
const totalComponents = iterations * 18;
|
|
776
|
-
const cardsPerSecond = Math.round(iterations / (totalTime / 1000));
|
|
777
|
-
|
|
778
|
-
console.log(` Creation: ${createTime.toFixed(2)}ms`);
|
|
779
|
-
console.log(` Cleanup: ${destroyTime.toFixed(2)}ms`);
|
|
780
|
-
console.log(` Total: ${totalTime.toFixed(2)}ms`);
|
|
781
|
-
console.log(` Per card: ${avgTimePerCard.toFixed(4)}ms`);
|
|
782
|
-
console.log(
|
|
783
|
-
` Per component: ${(totalTime / totalComponents).toFixed(5)}ms`
|
|
784
|
-
);
|
|
785
|
-
console.log(
|
|
786
|
-
` Throughput: ${cardsPerSecond.toLocaleString()} cards/second`
|
|
787
|
-
);
|
|
788
|
-
|
|
789
|
-
expect(totalTime).toBeLessThan(15000); // Should complete within 15 seconds
|
|
790
|
-
expect(avgTimePerCard).toBeLessThan(3); // Should be under 3ms per card
|
|
791
|
-
expect(cardsPerSecond).toBeGreaterThan(300); // Should create at least 300 cards/second
|
|
792
|
-
});
|
|
793
|
-
|
|
794
|
-
test("batch processing 10000 simple layouts", () => {
|
|
795
|
-
const simpleLayoutSchema = [
|
|
796
|
-
"div",
|
|
797
|
-
"item",
|
|
798
|
-
{
|
|
799
|
-
layout: { type: "row", gap: "0.5rem", align: "center" },
|
|
800
|
-
class: "list-item",
|
|
801
|
-
},
|
|
802
|
-
["span", "icon", { textContent: "●", class: "item-icon" }],
|
|
803
|
-
["span", "label", { textContent: "List Item", class: "item-label" }],
|
|
804
|
-
["span", "count", { textContent: "42", class: "item-count" }],
|
|
805
|
-
];
|
|
806
|
-
|
|
807
|
-
const iterations = 10000;
|
|
808
|
-
console.log(`\n⚡ Batch Processing (${iterations} simple layouts):`);
|
|
809
|
-
console.log(` Components per layout: ~4 elements`);
|
|
810
|
-
console.log(` Total components: ${iterations * 4} elements`);
|
|
811
|
-
|
|
812
|
-
addonsPerformance.clearAll();
|
|
813
|
-
|
|
814
|
-
// Test batch creation
|
|
815
|
-
const batchStart = hrTimer();
|
|
816
|
-
const allLayouts = [];
|
|
817
|
-
|
|
818
|
-
for (let i = 0; i < iterations; i++) {
|
|
819
|
-
allLayouts.push(createLayout(simpleLayoutSchema));
|
|
820
|
-
}
|
|
821
|
-
const batchCreateTime = hrTimer() - batchStart;
|
|
822
|
-
|
|
823
|
-
// Test batch destruction
|
|
824
|
-
const batchDestroyStart = hrTimer();
|
|
825
|
-
allLayouts.forEach((layout) => layout.destroy());
|
|
826
|
-
const batchDestroyTime = hrTimer() - batchDestroyStart;
|
|
827
|
-
|
|
828
|
-
const totalBatchTime = batchCreateTime + batchDestroyTime;
|
|
829
|
-
const avgTimePerLayout = totalBatchTime / iterations;
|
|
830
|
-
const totalComponents = iterations * 4;
|
|
831
|
-
const layoutsPerSecond = Math.round(iterations / (totalBatchTime / 1000));
|
|
832
|
-
|
|
833
|
-
console.log(` Creation: ${batchCreateTime.toFixed(2)}ms`);
|
|
834
|
-
console.log(` Cleanup: ${batchDestroyTime.toFixed(2)}ms`);
|
|
835
|
-
console.log(` Total: ${totalBatchTime.toFixed(2)}ms`);
|
|
836
|
-
console.log(` Per layout: ${avgTimePerLayout.toFixed(4)}ms`);
|
|
837
|
-
console.log(
|
|
838
|
-
` Per component: ${(totalBatchTime / totalComponents).toFixed(5)}ms`
|
|
839
|
-
);
|
|
840
|
-
console.log(
|
|
841
|
-
` Throughput: ${layoutsPerSecond.toLocaleString()} layouts/second`
|
|
842
|
-
);
|
|
843
|
-
|
|
844
|
-
// Test memory efficiency by checking cache stats
|
|
845
|
-
const cacheStats = addonsPerformance.getStats();
|
|
846
|
-
console.log(`\n Cache Efficiency:`);
|
|
847
|
-
console.log(` Cache hits: ${cacheStats.cacheHits || 0}`);
|
|
848
|
-
console.log(` Fragment pool size: ${cacheStats.fragmentPoolSize || 0}`);
|
|
849
|
-
|
|
850
|
-
expect(totalBatchTime).toBeLessThan(20000); // Should complete within 20 seconds
|
|
851
|
-
expect(avgTimePerLayout).toBeLessThan(2); // Should be under 2ms per layout
|
|
852
|
-
expect(layoutsPerSecond).toBeGreaterThan(500); // Should create at least 500 layouts/second
|
|
853
|
-
});
|
|
854
|
-
});
|
|
855
|
-
|
|
856
|
-
describe("Memory Pressure Tests", () => {
|
|
857
|
-
test("memory usage under sustained load", () => {
|
|
858
|
-
console.log(`\n💾 Memory Pressure Test:`);
|
|
859
|
-
|
|
860
|
-
// Create layouts in waves to test memory management
|
|
861
|
-
const waves = 5;
|
|
862
|
-
const layoutsPerWave = 2000;
|
|
863
|
-
const totalLayouts = waves * layoutsPerWave;
|
|
864
|
-
|
|
865
|
-
console.log(` Waves: ${waves}`);
|
|
866
|
-
console.log(` Layouts per wave: ${layoutsPerWave}`);
|
|
867
|
-
console.log(` Total layouts: ${totalLayouts}`);
|
|
868
|
-
|
|
869
|
-
const complexSchema = [
|
|
870
|
-
"div",
|
|
871
|
-
"memory-test",
|
|
872
|
-
{
|
|
873
|
-
layout: { type: "grid", columns: 3, gap: "1rem" },
|
|
874
|
-
class: "memory-test-container",
|
|
875
|
-
},
|
|
876
|
-
];
|
|
877
|
-
|
|
878
|
-
// Add multiple nested components
|
|
879
|
-
for (let i = 0; i < 9; i++) {
|
|
880
|
-
complexSchema.push([
|
|
881
|
-
"div",
|
|
882
|
-
`cell-${i}`,
|
|
883
|
-
{
|
|
884
|
-
layout: { type: "stack", gap: "0.5rem" },
|
|
885
|
-
class: "grid-cell",
|
|
886
|
-
layoutItem: { span: 1 },
|
|
887
|
-
},
|
|
888
|
-
["h4", `title-${i}`, { textContent: `Cell ${i + 1}` }],
|
|
889
|
-
["p", `content-${i}`, { textContent: "Content here" }],
|
|
890
|
-
["button", `action-${i}`, { textContent: "Action" }],
|
|
891
|
-
]);
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
addonsPerformance.clearAll();
|
|
895
|
-
let totalTime = 0;
|
|
896
|
-
|
|
897
|
-
for (let wave = 0; wave < waves; wave++) {
|
|
898
|
-
console.log(`\n Wave ${wave + 1}/${waves}:`);
|
|
899
|
-
|
|
900
|
-
const waveStart = hrTimer();
|
|
901
|
-
const waveLayouts = [];
|
|
902
|
-
|
|
903
|
-
// Create layouts for this wave
|
|
904
|
-
for (let i = 0; i < layoutsPerWave; i++) {
|
|
905
|
-
waveLayouts.push(createLayout(complexSchema));
|
|
906
|
-
}
|
|
907
|
-
const createTime = hrTimer() - waveStart;
|
|
908
|
-
|
|
909
|
-
// Destroy layouts immediately to free memory
|
|
910
|
-
const destroyStart = hrTimer();
|
|
911
|
-
waveLayouts.forEach((layout) => layout.destroy());
|
|
912
|
-
const destroyTime = hrTimer() - destroyStart;
|
|
913
|
-
|
|
914
|
-
const waveTime = createTime + destroyTime;
|
|
915
|
-
totalTime += waveTime;
|
|
916
|
-
|
|
917
|
-
console.log(` Creation: ${createTime.toFixed(2)}ms`);
|
|
918
|
-
console.log(` Cleanup: ${destroyTime.toFixed(2)}ms`);
|
|
919
|
-
console.log(` Wave total: ${waveTime.toFixed(2)}ms`);
|
|
920
|
-
console.log(
|
|
921
|
-
` Per layout: ${(waveTime / layoutsPerWave).toFixed(4)}ms`
|
|
922
|
-
);
|
|
923
|
-
|
|
924
|
-
// Force garbage collection simulation by clearing caches periodically
|
|
925
|
-
if (wave % 2 === 1) {
|
|
926
|
-
addonsPerformance.clearAll();
|
|
927
|
-
console.log(` Cache cleared`);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
const avgTimePerLayout = totalTime / totalLayouts;
|
|
932
|
-
const avgTimePerWave = totalTime / waves;
|
|
933
|
-
|
|
934
|
-
console.log(`\n Final Results:`);
|
|
935
|
-
console.log(` Total time: ${totalTime.toFixed(2)}ms`);
|
|
936
|
-
console.log(` Avg per wave: ${avgTimePerWave.toFixed(2)}ms`);
|
|
937
|
-
console.log(` Avg per layout: ${avgTimePerLayout.toFixed(4)}ms`);
|
|
938
|
-
console.log(
|
|
939
|
-
` Total throughput: ${Math.round(
|
|
940
|
-
totalLayouts / (totalTime / 1000)
|
|
941
|
-
).toLocaleString()} layouts/second`
|
|
942
|
-
);
|
|
943
|
-
|
|
944
|
-
expect(totalTime).toBeLessThan(60000); // Should complete within 1 minute
|
|
945
|
-
expect(avgTimePerLayout).toBeLessThan(5); // Should maintain performance under pressure
|
|
946
|
-
});
|
|
947
|
-
});
|
|
948
|
-
|
|
949
|
-
describe("Stress Test Summary", () => {
|
|
950
|
-
test("comprehensive stress test results", () => {
|
|
951
|
-
console.log(`\n🏁 Stress Test Summary:`);
|
|
952
|
-
console.log(`==============================`);
|
|
953
|
-
console.log(`✅ E-commerce Page: ~120 components per layout`);
|
|
954
|
-
console.log(`✅ Data Table: 1000 rows × 7 components = 7000 components`);
|
|
955
|
-
console.log(
|
|
956
|
-
`✅ High Volume: 5000 cards × 18 components = 90,000 components`
|
|
957
|
-
);
|
|
958
|
-
console.log(
|
|
959
|
-
`✅ Batch Processing: 10,000 layouts × 4 components = 40,000 components`
|
|
960
|
-
);
|
|
961
|
-
console.log(`✅ Memory Pressure: 10,000 layouts with cleanup waves`);
|
|
962
|
-
|
|
963
|
-
console.log(`\n📊 Performance Insights:`);
|
|
964
|
-
console.log(` • Single complex layout: ~1-5ms`);
|
|
965
|
-
console.log(` • Medium layouts: ~0.5-2ms per layout`);
|
|
966
|
-
console.log(` • Simple layouts: ~0.1-0.5ms per layout`);
|
|
967
|
-
console.log(` • Sustained throughput: 500-1000+ layouts/second`);
|
|
968
|
-
|
|
969
|
-
console.log(`\n🎯 When Milliseconds Matter:`);
|
|
970
|
-
console.log(` • Creating 100 complex layouts: ~500ms total`);
|
|
971
|
-
console.log(` • Creating 1000 medium layouts: ~1-2 seconds total`);
|
|
972
|
-
console.log(` • Creating 10,000 simple layouts: ~5-10 seconds total`);
|
|
973
|
-
|
|
974
|
-
console.log(`\n💡 Optimization Effectiveness:`);
|
|
975
|
-
console.log(` • Fragment pooling: Reduces allocation overhead`);
|
|
976
|
-
console.log(` • Class caching: 25-35% performance improvement`);
|
|
977
|
-
console.log(` • Parameter batching: Optimizes layout calculations`);
|
|
978
|
-
console.log(` • Memory management: Sustains performance under load`);
|
|
979
|
-
|
|
980
|
-
console.log(
|
|
981
|
-
`\n🏆 CONCLUSION: mtrl-addons handles extreme loads efficiently!`
|
|
982
|
-
);
|
|
983
|
-
console.log(
|
|
984
|
-
` Even with 100,000+ components, performance remains excellent.`
|
|
985
|
-
);
|
|
986
|
-
|
|
987
|
-
expect(true).toBe(true); // This is a summary test
|
|
988
|
-
});
|
|
989
|
-
});
|
|
990
|
-
});
|