Skip to content

Commit 9037f09

Browse files
committed
Improve perf test page
1 parent 568064c commit 9037f09

File tree

5 files changed

+105
-78
lines changed

5 files changed

+105
-78
lines changed

packages/idb-cache-app/src/App.tsx

Lines changed: 82 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import "./App.css";
22
import { IDBCache } from "@instructure/idb-cache";
3-
import { useCallback, useEffect, useState } from "react";
3+
import { useCallback, useState } from "react";
44
import { uuid, deterministicHash, generateTextOfSize } from "./utils";
55
import { Button } from "@instructure/ui-buttons";
6-
import { MetricGroup, Metric } from "@instructure/ui-metric";
6+
import { Metric } from "@instructure/ui-metric";
77
import { View } from "@instructure/ui-view";
88
import { Flex } from "@instructure/ui-flex";
99
import { Heading } from "@instructure/ui-heading";
@@ -38,38 +38,45 @@ const initialItemSize =
3838
localStorage.getItem("itemSize") || String(DEFAULT_ITEM_SIZE),
3939
) || DEFAULT_ITEM_SIZE;
4040

41+
const BlankStat = () => (
42+
<span
43+
style={{
44+
color: "#ddd",
45+
}}
46+
>
47+
------
48+
</span>
49+
);
50+
4151
const App = () => {
4252
const [hash1, setHash1] = useState<string | null>(null);
4353
const [hash2, setHash2] = useState<string | null>(null);
54+
const [timeToGenerate, setTimeToGenerate] = useState<number | null>(null);
4455
const [setTime, setSetTime] = useState<number | null>(null);
4556
const [getTime, setGetTime] = useState<number | null>(null);
4657
const [itemSize, setItemSize] = useState<number>(initialItemSize);
47-
const [isEncrypting, setIsEncrypting] = useState<boolean>(false);
48-
const [isDecrypting, setIsDecrypting] = useState<boolean>(false);
4958

5059
const encryptAndStore = useCallback(async () => {
51-
console.time("generating content");
52-
setIsEncrypting(true);
60+
const start1 = performance.now();
5361
const paragraphs = Array.from({ length: DEFAULT_NUM_ITEMS }, (_, index) =>
5462
generateTextOfSize(itemSize, `${cacheBuster}-${index}`),
5563
);
56-
console.timeEnd("generating content");
64+
const end1 = performance.now();
65+
setTimeToGenerate(end1 - start1);
5766

58-
const start = performance.now();
67+
const start2 = performance.now();
5968

6069
for (let i = 0; i < DEFAULT_NUM_ITEMS; i++) {
6170
await cache.setItem(`item-${i}`, paragraphs[i]);
6271
}
6372

64-
const end = performance.now();
65-
setSetTime(end - start);
73+
const end2 = performance.now();
74+
setSetTime(end2 - start2);
6675

6776
setHash1(deterministicHash(paragraphs.join("")));
68-
setIsEncrypting(false);
6977
}, [itemSize]);
7078

7179
const retrieveAndDecrypt = useCallback(async () => {
72-
setIsDecrypting(true);
7380
const results: Array<string | null> = [];
7481
const start = performance.now();
7582

@@ -81,18 +88,6 @@ const App = () => {
8188
const end = performance.now();
8289
setGetTime(end - start);
8390
setHash2(results.length > 0 ? deterministicHash(results.join("")) : null);
84-
setIsDecrypting(false);
85-
}, []);
86-
87-
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
88-
useEffect(() => {
89-
requestAnimationFrame(() => {
90-
encryptAndStore().then(() => {
91-
requestAnimationFrame(() => {
92-
retrieveAndDecrypt();
93-
});
94-
});
95-
});
9691
}, []);
9792

9893
return (
@@ -144,7 +139,7 @@ const App = () => {
144139
<legend className="text-lg font-semibold text-gray-700">
145140
Test Configuration
146141
</legend>
147-
<div className="flex flex-col gap-4">
142+
<Flex direction="column" gap="small">
148143
<div className="flex items-center justify-between">
149144
<span>
150145
Cache key: <code className="text-sm">{cacheKey}</code>
@@ -171,14 +166,7 @@ const App = () => {
171166
Reset
172167
</Button>
173168
</div>
174-
</div>
175-
</fieldset>
176169

177-
<fieldset className="border border-gray-300 rounded-lg p-4 mb-6">
178-
<legend className="text-lg font-semibold text-gray-700">
179-
Performance Test
180-
</legend>
181-
<div className="flex flex-col gap-4">
182170
<Flex gap="medium">
183171
<Flex.Item shouldGrow>
184172
<NumberInput
@@ -219,7 +207,14 @@ const App = () => {
219207
/>
220208
</Flex.Item>
221209
</Flex>
210+
</Flex>
211+
</fieldset>
222212

213+
<fieldset className="border border-gray-300 rounded-lg p-4">
214+
<legend className="text-lg font-semibold text-gray-700">
215+
Performance Tests
216+
</legend>
217+
<div className="flex flex-col gap-4">
223218
<View
224219
as="span"
225220
display="inline-block"
@@ -230,23 +225,41 @@ const App = () => {
230225
>
231226
<Flex direction="column">
232227
<Button color="primary" onClick={encryptAndStore}>
233-
Encrypt and store
228+
setItem
234229
</Button>
235230
<View padding="medium 0 0 0">
236-
<MetricGroup>
237-
<Metric
238-
renderLabel="to encrypt and store"
239-
renderValue={
240-
setTime !== null
241-
? `${Math.round(setTime)} ms`
242-
: "N/A"
243-
}
244-
/>
245-
<Metric
246-
renderLabel="hash of data"
247-
renderValue={hash1}
248-
/>
249-
</MetricGroup>
231+
<Flex>
232+
<Flex.Item size="33.3%">
233+
<Metric
234+
renderLabel="generate test data"
235+
renderValue={
236+
setTime !== null ? (
237+
`${Math.round(timeToGenerate || 0)} ms`
238+
) : (
239+
<BlankStat />
240+
)
241+
}
242+
/>
243+
</Flex.Item>
244+
<Flex.Item shouldGrow>
245+
<Metric
246+
renderLabel="setItem"
247+
renderValue={
248+
setTime !== null ? (
249+
`${Math.round(setTime)} ms`
250+
) : (
251+
<BlankStat />
252+
)
253+
}
254+
/>
255+
</Flex.Item>
256+
<Flex.Item size="33.3%">
257+
<Metric
258+
renderLabel="hash"
259+
renderValue={hash1 || <BlankStat />}
260+
/>
261+
</Flex.Item>
262+
</Flex>
250263
</View>
251264
</Flex>
252265
</View>
@@ -261,24 +274,31 @@ const App = () => {
261274
>
262275
<Flex direction="column">
263276
<Button color="primary" onClick={retrieveAndDecrypt}>
264-
Retrieve and decrypt
277+
getItem
265278
</Button>
266279

267280
<View padding="medium 0 0 0">
268-
<MetricGroup>
269-
<Metric
270-
renderLabel="to retrieve and decrypt"
271-
renderValue={
272-
getTime !== null
273-
? `${Math.round(getTime)} ms`
274-
: "error"
275-
}
276-
/>
277-
<Metric
278-
renderLabel="hash of data"
279-
renderValue={hash2}
280-
/>
281-
</MetricGroup>
281+
<Flex>
282+
<Flex.Item size="33.3%">&nbsp;</Flex.Item>
283+
<Flex.Item shouldGrow>
284+
<Metric
285+
renderLabel="getItem"
286+
renderValue={
287+
getTime !== null ? (
288+
`${Math.round(getTime)} ms`
289+
) : (
290+
<BlankStat />
291+
)
292+
}
293+
/>
294+
</Flex.Item>
295+
<Flex.Item size="33.3%">
296+
<Metric
297+
renderLabel="hash"
298+
renderValue={hash2 || <BlankStat />}
299+
/>
300+
</Flex.Item>
301+
</Flex>
282302
</View>
283303
</Flex>
284304
</View>
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import React from 'react';
2-
import ReactDOM from 'react-dom/client';
3-
import App from './App';
1+
import React from "react";
2+
import ReactDOM from "react-dom/client";
3+
import App from "./App";
44

5-
const rootEl = document.getElementById('root');
5+
const rootEl = document.getElementById("root");
66
if (rootEl) {
7-
const root = ReactDOM.createRoot(rootEl);
8-
root.render(
9-
<React.StrictMode>
10-
<App />
11-
</React.StrictMode>,
12-
);
7+
const root = ReactDOM.createRoot(rootEl);
8+
root.render(
9+
<React.StrictMode>
10+
<App />
11+
</React.StrictMode>,
12+
);
1313
}
File renamed without changes.

packages/idb-cache/src/index.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { decryptChunk, encryptChunk } from "./encryption";
1+
import { decryptChunk, encryptChunk } from "./encryptionTasks";
22
import type {
33
EncryptedChunk,
44
ExtendedPendingRequest,
@@ -13,7 +13,7 @@ import {
1313
getAllChunkKeysForBaseKey,
1414
deterministicUUID,
1515
} from "./utils";
16-
import { encryptionWorkerFunction } from "./workerFunction";
16+
import { encryptionWorkerFunction } from "./encryptionWorkerFn";
1717
import {
1818
createWorkerFromFunction,
1919
initializeWorker,
@@ -33,6 +33,7 @@ const DEFAULT_CHUNK_SIZE = 25000;
3333
const DEFAULT_GC_TIME = 7 * 24 * 60 * 60 * 1000;
3434
const DEFAULT_PBKDF2_ITERATIONS = 100000;
3535
const CLEANUP_INTERVAL = 60 * 1000;
36+
const DURATION_THRESHOLD = 200;
3637

3738
const isSubtleCryptoSupported = crypto?.subtle;
3839

@@ -193,6 +194,7 @@ export class IDBCache implements AsyncStorage {
193194
const upperBoundRange = IDBKeyRange.lowerBound(currentCacheBuster, true);
194195

195196
const deleteItemsInRange = async (range: IDBKeyRange) => {
197+
let itemsDeleted = 0;
196198
let cursor = await index.openCursor(range);
197199
while (cursor) {
198200
if (this.debug) {
@@ -202,18 +204,23 @@ export class IDBCache implements AsyncStorage {
202204
);
203205
}
204206
await cursor.delete();
207+
itemsDeleted++;
205208
cursor = await cursor.continue();
206209
}
210+
return itemsDeleted;
207211
};
208212

209-
await Promise.all([
213+
const itemsDeleted = await Promise.all([
210214
deleteItemsInRange(lowerBoundRange),
211215
deleteItemsInRange(upperBoundRange),
212216
]);
213217

214218
await transaction.done;
215219
if (this.debug) {
216-
console.debug("Flushed old cache items with different cacheBuster.");
220+
const total = itemsDeleted.reduce((acc, curr) => acc + (curr || 0), 0);
221+
if (total > 0) {
222+
console.debug("Flushed old cache items with different cacheBuster.");
223+
}
217224
}
218225
} catch (error) {
219226
console.error("Error during flushBustedCacheItems:", error);
@@ -343,7 +350,7 @@ export class IDBCache implements AsyncStorage {
343350
);
344351

345352
const duration = Date.now() - startTime;
346-
if (this.debug && duration > 200) {
353+
if (this.debug && duration > DURATION_THRESHOLD) {
347354
console.debug(`getItem for key ${itemKey} took ${duration}ms`);
348355
}
349356

@@ -475,7 +482,7 @@ export class IDBCache implements AsyncStorage {
475482
await tx.done;
476483

477484
const duration = Date.now() - startTime;
478-
if (this.debug && duration > 200) {
485+
if (this.debug && duration > DURATION_THRESHOLD) {
479486
console.debug(`setItem for key ${itemKey} took ${duration}ms`);
480487
}
481488
} catch (error) {

0 commit comments

Comments
 (0)