@humanspeak/svelte-virtual-list 0.2.6 → 0.3.1-beta.1
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/README.md +50 -13
- package/dist/SvelteVirtualList.svelte +619 -179
- package/dist/SvelteVirtualList.svelte.d.ts +156 -65
- package/dist/reactive-height-manager/INTEGRATION_EXAMPLE.md +136 -0
- package/dist/reactive-height-manager/README.md +324 -0
- package/dist/reactive-height-manager/ReactiveHeightManager.svelte.d.ts +116 -0
- package/dist/reactive-height-manager/ReactiveHeightManager.svelte.js +200 -0
- package/dist/reactive-height-manager/benchmark.d.ts +5 -0
- package/dist/reactive-height-manager/benchmark.js +25 -0
- package/dist/reactive-height-manager/index.d.ts +50 -0
- package/dist/reactive-height-manager/index.js +55 -0
- package/dist/reactive-height-manager/test/TestComponent.svelte +78 -0
- package/dist/reactive-height-manager/test/TestComponent.svelte.d.ts +23 -0
- package/dist/reactive-height-manager/types.d.ts +41 -0
- package/dist/reactive-height-manager/types.js +1 -0
- package/dist/types.d.ts +24 -5
- package/dist/utils/heightCalculation.d.ts +18 -8
- package/dist/utils/heightCalculation.js +18 -11
- package/dist/utils/heightChangeDetection.d.ts +12 -0
- package/dist/utils/heightChangeDetection.js +20 -0
- package/dist/utils/resizeObserver.d.ts +89 -0
- package/dist/utils/resizeObserver.js +119 -0
- package/dist/utils/scrollCalculation.d.ts +47 -0
- package/dist/utils/scrollCalculation.js +167 -0
- package/dist/utils/throttle.d.ts +95 -0
- package/dist/utils/throttle.js +155 -0
- package/dist/utils/types.d.ts +0 -6
- package/dist/utils/virtualList.d.ts +20 -23
- package/dist/utils/virtualList.js +153 -61
- package/dist/utils/virtualListDebug.d.ts +12 -7
- package/dist/utils/virtualListDebug.js +19 -9
- package/package.json +33 -31
|
@@ -47,7 +47,14 @@
|
|
|
47
47
|
* - Added comprehensive documentation
|
|
48
48
|
* - Optimized debug output to reduce noise
|
|
49
49
|
*
|
|
50
|
-
* 9.
|
|
50
|
+
* 9. Architecture Refactoring ✓
|
|
51
|
+
* - Extracted scroll calculation logic to scrollCalculation.ts utility
|
|
52
|
+
* - Extracted ResizeObserver utilities to resizeObserver.ts
|
|
53
|
+
* - Added comprehensive test coverage for extracted utilities
|
|
54
|
+
* - Improved separation of concerns and maintainability
|
|
55
|
+
* - Simplified initialization (removed unnecessary chunked processing)
|
|
56
|
+
*
|
|
57
|
+
* 10. Future Improvements (Planned)
|
|
51
58
|
* - Add horizontal scrolling support
|
|
52
59
|
* - Implement variable-sized item caching
|
|
53
60
|
* - Add keyboard navigation support
|
|
@@ -65,18 +72,158 @@
|
|
|
65
72
|
* - Debug output optimization
|
|
66
73
|
* - Accurate size calculations with caching
|
|
67
74
|
* - Responsive size adjustments
|
|
75
|
+
* - Modular architecture with testable utility functions
|
|
68
76
|
*
|
|
69
77
|
* Current Architecture:
|
|
70
78
|
* - Four-layer DOM structure for optimal performance
|
|
71
79
|
* - State management using Svelte 5's $state
|
|
72
80
|
* - Reactive height and scroll calculations
|
|
73
81
|
* - Configurable buffer zones for smooth scrolling
|
|
74
|
-
* -
|
|
75
|
-
*
|
|
82
|
+
* - Modular utility system with dedicated helper files:
|
|
83
|
+
* * scrollCalculation.ts: Complex scroll positioning logic
|
|
84
|
+
* * resizeObserver.ts: ResizeObserver management utilities
|
|
85
|
+
* * heightCalculation.ts: Debounced height measurement
|
|
86
|
+
* * virtualList.ts: Core virtual list calculations
|
|
87
|
+
* * virtualListDebug.ts: Debug information utilities
|
|
76
88
|
* - Height caching and estimation system
|
|
77
89
|
* - Progressive size adjustment system
|
|
78
90
|
*/
|
|
79
91
|
import { type SvelteVirtualListProps, type SvelteVirtualListScrollOptions } from './types.js';
|
|
92
|
+
declare function $$render<TItem = any>(): {
|
|
93
|
+
props: SvelteVirtualListProps<TItem>;
|
|
94
|
+
exports: {
|
|
95
|
+
/**
|
|
96
|
+
* Scrolls the virtual list to the item at the given index.
|
|
97
|
+
*
|
|
98
|
+
* @deprecated This function is deprecated and will be removed in a future version.
|
|
99
|
+
* Use the new scroll method from the component instance instead.
|
|
100
|
+
*
|
|
101
|
+
* @function scrollToIndex
|
|
102
|
+
* @param index The index of the item to scroll to.
|
|
103
|
+
* @param smoothScroll (default: true) Whether to use smooth scrolling.
|
|
104
|
+
* @param shouldThrowOnBounds (default: true) Whether to throw an error if the index is out of bounds.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* // Svelte usage:
|
|
108
|
+
* // In your <script> block:
|
|
109
|
+
* import SvelteVirtualList from '@humanspeak/svelte-virtual-list';
|
|
110
|
+
* let virtualList;
|
|
111
|
+
* const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` }));
|
|
112
|
+
*
|
|
113
|
+
* // In your markup:
|
|
114
|
+
* <button onclick={() => virtualList.scrollToIndex(5000)}>
|
|
115
|
+
* Scroll to 5000
|
|
116
|
+
* </button>
|
|
117
|
+
* <SvelteVirtualList {items} bind:this={virtualList}>
|
|
118
|
+
* {#snippet renderItem(item)}
|
|
119
|
+
* <div>{item.text}</div>
|
|
120
|
+
* {/snippet}
|
|
121
|
+
* </SvelteVirtualList>
|
|
122
|
+
*
|
|
123
|
+
* @returns {void}
|
|
124
|
+
* @throws {Error} If the index is out of bounds and shouldThrowOnBounds is true
|
|
125
|
+
*/ scrollToIndex: (index: number, smoothScroll?: boolean, shouldThrowOnBounds?: boolean) => void;
|
|
126
|
+
/**
|
|
127
|
+
* Scrolls the virtual list to the item at the given index using a type-based options approach.
|
|
128
|
+
*
|
|
129
|
+
* @function scroll
|
|
130
|
+
* @param options Configuration options for scrolling behavior.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* // Svelte usage:
|
|
134
|
+
* // In your <script> block:
|
|
135
|
+
* import SvelteVirtualList from './index.js';
|
|
136
|
+
* let virtualList;
|
|
137
|
+
* const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` }));
|
|
138
|
+
*
|
|
139
|
+
* <button onclick={() => virtualList.scroll({ index: 5000 })}>
|
|
140
|
+
* Scroll to 5000
|
|
141
|
+
* </button>
|
|
142
|
+
* <SvelteVirtualList {items} bind:this={virtualList}>
|
|
143
|
+
* {#snippet renderItem(item)}
|
|
144
|
+
* <div>{item.text}</div>
|
|
145
|
+
* {/snippet}
|
|
146
|
+
* </SvelteVirtualList>
|
|
147
|
+
*
|
|
148
|
+
* @returns {Promise<void>} Promise that resolves when scrolling is complete
|
|
149
|
+
* @throws {Error} If the index is out of bounds and shouldThrowOnBounds is true
|
|
150
|
+
*/ scroll: (options: SvelteVirtualListScrollOptions) => Promise<void>;
|
|
151
|
+
};
|
|
152
|
+
bindings: "";
|
|
153
|
+
slots: {};
|
|
154
|
+
events: {};
|
|
155
|
+
};
|
|
156
|
+
declare class __sveltets_Render<TItem = any> {
|
|
157
|
+
props(): ReturnType<typeof $$render<TItem>>['props'];
|
|
158
|
+
events(): ReturnType<typeof $$render<TItem>>['events'];
|
|
159
|
+
slots(): ReturnType<typeof $$render<TItem>>['slots'];
|
|
160
|
+
bindings(): "";
|
|
161
|
+
exports(): {
|
|
162
|
+
/**
|
|
163
|
+
* Scrolls the virtual list to the item at the given index.
|
|
164
|
+
*
|
|
165
|
+
* @deprecated This function is deprecated and will be removed in a future version.
|
|
166
|
+
* Use the new scroll method from the component instance instead.
|
|
167
|
+
*
|
|
168
|
+
* @function scrollToIndex
|
|
169
|
+
* @param index The index of the item to scroll to.
|
|
170
|
+
* @param smoothScroll (default: true) Whether to use smooth scrolling.
|
|
171
|
+
* @param shouldThrowOnBounds (default: true) Whether to throw an error if the index is out of bounds.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* // Svelte usage:
|
|
175
|
+
* // In your <script> block:
|
|
176
|
+
* import SvelteVirtualList from '@humanspeak/svelte-virtual-list';
|
|
177
|
+
* let virtualList;
|
|
178
|
+
* const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` }));
|
|
179
|
+
*
|
|
180
|
+
* // In your markup:
|
|
181
|
+
* <button onclick={() => virtualList.scrollToIndex(5000)}>
|
|
182
|
+
* Scroll to 5000
|
|
183
|
+
* </button>
|
|
184
|
+
* <SvelteVirtualList {items} bind:this={virtualList}>
|
|
185
|
+
* {#snippet renderItem(item)}
|
|
186
|
+
* <div>{item.text}</div>
|
|
187
|
+
* {/snippet}
|
|
188
|
+
* </SvelteVirtualList>
|
|
189
|
+
*
|
|
190
|
+
* @returns {void}
|
|
191
|
+
* @throws {Error} If the index is out of bounds and shouldThrowOnBounds is true
|
|
192
|
+
*/ scrollToIndex: (index: number, smoothScroll?: boolean, shouldThrowOnBounds?: boolean) => void;
|
|
193
|
+
/**
|
|
194
|
+
* Scrolls the virtual list to the item at the given index using a type-based options approach.
|
|
195
|
+
*
|
|
196
|
+
* @function scroll
|
|
197
|
+
* @param options Configuration options for scrolling behavior.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* // Svelte usage:
|
|
201
|
+
* // In your <script> block:
|
|
202
|
+
* import SvelteVirtualList from './index.js';
|
|
203
|
+
* let virtualList;
|
|
204
|
+
* const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` }));
|
|
205
|
+
*
|
|
206
|
+
* <button onclick={() => virtualList.scroll({ index: 5000 })}>
|
|
207
|
+
* Scroll to 5000
|
|
208
|
+
* </button>
|
|
209
|
+
* <SvelteVirtualList {items} bind:this={virtualList}>
|
|
210
|
+
* {#snippet renderItem(item)}
|
|
211
|
+
* <div>{item.text}</div>
|
|
212
|
+
* {/snippet}
|
|
213
|
+
* </SvelteVirtualList>
|
|
214
|
+
*
|
|
215
|
+
* @returns {Promise<void>} Promise that resolves when scrolling is complete
|
|
216
|
+
* @throws {Error} If the index is out of bounds and shouldThrowOnBounds is true
|
|
217
|
+
*/ scroll: (options: SvelteVirtualListScrollOptions) => Promise<void>;
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
interface $$IsomorphicComponent {
|
|
221
|
+
new <TItem = any>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TItem>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TItem>['props']>, ReturnType<__sveltets_Render<TItem>['events']>, ReturnType<__sveltets_Render<TItem>['slots']>> & {
|
|
222
|
+
$$bindings?: ReturnType<__sveltets_Render<TItem>['bindings']>;
|
|
223
|
+
} & ReturnType<__sveltets_Render<TItem>['exports']>;
|
|
224
|
+
<TItem = any>(internal: unknown, props: ReturnType<__sveltets_Render<TItem>['props']> & {}): ReturnType<__sveltets_Render<TItem>['exports']>;
|
|
225
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
226
|
+
}
|
|
80
227
|
/**
|
|
81
228
|
* SvelteVirtualList
|
|
82
229
|
*
|
|
@@ -120,15 +267,16 @@ import { type SvelteVirtualListProps, type SvelteVirtualListScrollOptions } from
|
|
|
120
267
|
* - Only visible items + buffer are mounted in the DOM
|
|
121
268
|
* - Height caching and estimation for dynamic content
|
|
122
269
|
* - Handles resize events and dynamic content changes
|
|
123
|
-
* -
|
|
124
|
-
* -
|
|
270
|
+
* - Optimized for very large lists through virtualization
|
|
271
|
+
* - Modular architecture with extracted utility functions
|
|
125
272
|
* - Bi-directional support: mode="topToBottom" or "bottomToTop"
|
|
126
273
|
* - Designed for extensibility and easy debugging
|
|
127
274
|
*
|
|
128
275
|
* =============================
|
|
129
276
|
* == For Contributors ==
|
|
130
277
|
* =============================
|
|
131
|
-
* -
|
|
278
|
+
* - Complex logic is extracted to dedicated utility files in src/lib/utils/
|
|
279
|
+
* - Scroll positioning logic is in scrollCalculation.ts (well-tested)
|
|
132
280
|
* - Add new features behind feature flags or as optional props
|
|
133
281
|
* - Write tests for all new features (see /test and /tests/scroll)
|
|
134
282
|
* - Use TypeScript and Svelte 5 runes for all new code
|
|
@@ -138,63 +286,6 @@ import { type SvelteVirtualListProps, type SvelteVirtualListScrollOptions } from
|
|
|
138
286
|
*
|
|
139
287
|
* MIT License © Humanspeak, Inc.
|
|
140
288
|
*/
|
|
141
|
-
declare const SvelteVirtualList:
|
|
142
|
-
|
|
143
|
-
* Scrolls the virtual list to the item at the given index.
|
|
144
|
-
*
|
|
145
|
-
* @deprecated This function is deprecated and will be removed in a future version.
|
|
146
|
-
* Use the new scroll method from the component instance instead.
|
|
147
|
-
*
|
|
148
|
-
* @function scrollToIndex
|
|
149
|
-
* @param index The index of the item to scroll to.
|
|
150
|
-
* @param smoothScroll (default: true) Whether to use smooth scrolling.
|
|
151
|
-
* @param shouldThrowOnBounds (default: true) Whether to throw an error if the index is out of bounds.
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
* // Svelte usage:
|
|
155
|
-
* // In your <script> block:
|
|
156
|
-
* import SvelteVirtualList from '@humanspeak/svelte-virtual-list';
|
|
157
|
-
* let virtualList;
|
|
158
|
-
* const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` }));
|
|
159
|
-
*
|
|
160
|
-
* // In your markup:
|
|
161
|
-
* <button onclick={() => virtualList.scrollToIndex(5000)}>
|
|
162
|
-
* Scroll to 5000
|
|
163
|
-
* </button>
|
|
164
|
-
* <SvelteVirtualList {items} bind:this={virtualList}>
|
|
165
|
-
* {#snippet renderItem(item)}
|
|
166
|
-
* <div>{item.text}</div>
|
|
167
|
-
* {/snippet}
|
|
168
|
-
* </SvelteVirtualList>
|
|
169
|
-
*
|
|
170
|
-
* @returns {void}
|
|
171
|
-
* @throws {Error} If the index is out of bounds and shouldThrowOnBounds is true
|
|
172
|
-
*/ scrollToIndex: (index: number, smoothScroll?: boolean, shouldThrowOnBounds?: boolean) => void;
|
|
173
|
-
/**
|
|
174
|
-
* Scrolls the virtual list to the item at the given index using a type-based options approach.
|
|
175
|
-
*
|
|
176
|
-
* @function scroll
|
|
177
|
-
* @param options Configuration options for scrolling behavior.
|
|
178
|
-
*
|
|
179
|
-
* @example
|
|
180
|
-
* // Svelte usage:
|
|
181
|
-
* // In your <script> block:
|
|
182
|
-
* import SvelteVirtualList from './index.js';
|
|
183
|
-
* let virtualList;
|
|
184
|
-
* const items = Array.from({ length: 10000 }, (_, i) => ({ id: i, text: `Item ${i}` }));
|
|
185
|
-
*
|
|
186
|
-
* <button onclick={() => virtualList.scroll({ index: 5000 })}>
|
|
187
|
-
* Scroll to 5000
|
|
188
|
-
* </button>
|
|
189
|
-
* <SvelteVirtualList {items} bind:this={virtualList}>
|
|
190
|
-
* {#snippet renderItem(item)}
|
|
191
|
-
* <div>{item.text}</div>
|
|
192
|
-
* {/snippet}
|
|
193
|
-
* </SvelteVirtualList>
|
|
194
|
-
*
|
|
195
|
-
* @returns {void}
|
|
196
|
-
* @throws {Error} If the index is out of bounds and shouldThrowOnBounds is true
|
|
197
|
-
*/ scroll: (options: SvelteVirtualListScrollOptions) => void;
|
|
198
|
-
}, "">;
|
|
199
|
-
type SvelteVirtualList = ReturnType<typeof SvelteVirtualList>;
|
|
289
|
+
declare const SvelteVirtualList: $$IsomorphicComponent;
|
|
290
|
+
type SvelteVirtualList<TItem = any> = InstanceType<typeof SvelteVirtualList<TItem>>;
|
|
200
291
|
export default SvelteVirtualList;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# ReactiveHeightManager Integration Examples
|
|
2
|
+
|
|
3
|
+
> Detailed integration patterns for common use cases
|
|
4
|
+
|
|
5
|
+
**📖 For full documentation, see [README.md](./README.md)**
|
|
6
|
+
|
|
7
|
+
## SvelteVirtualList Integration
|
|
8
|
+
|
|
9
|
+
### 1. Import the ReactiveHeightManager
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { ReactiveHeightManager } from '$lib/reactive-height-manager'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### 2. Create the manager instance
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// Create reactive height manager
|
|
19
|
+
const heightManager = new ReactiveHeightManager({
|
|
20
|
+
itemLength: items.length,
|
|
21
|
+
estimatedHeight: defaultEstimatedItemHeight
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Update when items change
|
|
25
|
+
$effect(() => {
|
|
26
|
+
heightManager.updateItemLength(items.length)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// Update calculated height when it changes
|
|
30
|
+
$effect(() => {
|
|
31
|
+
heightManager.calculatedItemHeight = calculatedItemHeight
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 3. Modify the calculateAverageHeightDebounced callback
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
const updateHeight = () => {
|
|
39
|
+
heightUpdateTimeout = calculateAverageHeightDebounced(
|
|
40
|
+
// ... existing params
|
|
41
|
+
(result) => {
|
|
42
|
+
// Critical updates first (synchronous)
|
|
43
|
+
calculatedItemHeight = result.newHeight
|
|
44
|
+
lastMeasuredIndex = result.newLastMeasuredIndex
|
|
45
|
+
heightCache = result.updatedHeightCache
|
|
46
|
+
|
|
47
|
+
// Process dirty heights incrementally - O(dirty items)!
|
|
48
|
+
// If result.heightChanges already has compatible format, pass directly:
|
|
49
|
+
heightManager.processDirtyHeights(result.heightChanges)
|
|
50
|
+
|
|
51
|
+
// Or convert if needed:
|
|
52
|
+
// const heightChanges = result.heightChanges.map((change) => ({
|
|
53
|
+
// index: change.index,
|
|
54
|
+
// oldHeight: change.oldHeight,
|
|
55
|
+
// newHeight: change.newHeight
|
|
56
|
+
// }))
|
|
57
|
+
// heightManager.processDirtyHeights(heightChanges)
|
|
58
|
+
|
|
59
|
+
// Handle scroll correction (bottomToTop mode)
|
|
60
|
+
if (result.heightChanges.length > 0 && mode === 'bottomToTop') {
|
|
61
|
+
handleHeightChangesScrollCorrection(result.heightChanges)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ... rest of callback logic
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4. Replace totalHeight derived with reactive manager
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
// OLD: O(n) calculation every time
|
|
74
|
+
// let totalHeight = $derived(() => {
|
|
75
|
+
// let total = 0
|
|
76
|
+
// for (let i = 0; i < items.length; i++) {
|
|
77
|
+
// total += heightCache[i] || calculatedItemHeight
|
|
78
|
+
// }
|
|
79
|
+
// return total
|
|
80
|
+
// })
|
|
81
|
+
|
|
82
|
+
// NEW: O(1) reactive calculation 🚀
|
|
83
|
+
let totalHeight = $derived(() => heightManager.totalHeight)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Performance Benefits
|
|
87
|
+
|
|
88
|
+
- **Before**: O(n) calculation on every height change
|
|
89
|
+
- **After**: O(dirty items) incremental updates + O(1) derived calculation
|
|
90
|
+
- **Result**: ~90%+ performance improvement for large lists (10k+ items)
|
|
91
|
+
|
|
92
|
+
## Type Compatibility
|
|
93
|
+
|
|
94
|
+
The `ReactiveHeightManager` uses its own types but is designed to be compatible:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
// If SvelteVirtualList heightChanges are compatible, use directly:
|
|
98
|
+
heightManager.processDirtyHeights(result.heightChanges)
|
|
99
|
+
|
|
100
|
+
// Or convert if different interface:
|
|
101
|
+
const heightChanges: HeightChange[] = result.heightChanges.map((change) => ({
|
|
102
|
+
index: change.index,
|
|
103
|
+
oldHeight: change.oldHeight,
|
|
104
|
+
newHeight: change.newHeight
|
|
105
|
+
}))
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Debug and Monitoring
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Performance monitoring
|
|
112
|
+
const debugInfo = heightManager.getDebugInfo()
|
|
113
|
+
console.log(`Coverage: ${debugInfo.coveragePercent.toFixed(1)}%`)
|
|
114
|
+
console.log(`Measured: ${debugInfo.measuredCount}/${debugInfo.itemLength}`)
|
|
115
|
+
|
|
116
|
+
// Check if we have sufficient measurements
|
|
117
|
+
if (heightManager.hasSufficientMeasurements(20)) {
|
|
118
|
+
console.log('Height calculations are highly accurate')
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Testing
|
|
123
|
+
|
|
124
|
+
The ReactiveHeightManager comes with comprehensive performance tests:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Run specific tests
|
|
128
|
+
npm run test -- ReactiveHeightManager.test.ts --reporter=verbose
|
|
129
|
+
|
|
130
|
+
# Performance benchmarking
|
|
131
|
+
import { benchmarkHeightManager } from '$lib/reactive-height-manager'
|
|
132
|
+
|
|
133
|
+
const results = benchmarkHeightManager(10000, 1000, 100)
|
|
134
|
+
console.log(`Average time: ${results.avgTime.toFixed(2)}ms`)
|
|
135
|
+
console.log(`Operations/sec: ${results.opsPerSecond.toFixed(0)}`)
|
|
136
|
+
```
|