Skip to content

Instantly share code, notes, and snippets.

@aganders3
Last active December 19, 2025 16:58
Show Gist options
  • Select an option

  • Save aganders3/a7520029d9a5c446136413e4a1639106 to your computer and use it in GitHub Desktop.

Select an option

Save aganders3/a7520029d9a5c446136413e4a1639106 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zarrita Decompression Benchmark</title>
<script type="importmap">
{
"imports": {
"@zarrita/storage/fetch": "./packages/@zarrita-storage/dist/src/fetch.js",
"numcodecs/": "https://esm.sh/numcodecs@0.3.2/"
}
}
</script>
</head>
<body>
<h1>Zarrita Decompression Benchmark</h1>
<p>This test fetches <strong>10 individual Z-slices</strong> from a CryoET tomogram where chunk size >> 1 in Z.</p>
<p><em>Note: Run <code>npm run build</code> first, then serve with: <code>npx serve .</code> and open http://localhost:3000/examples/decompression-benchmark.html</em></p>
<button id="run">Run Benchmark</button>
<div id="output"></div>
<script type="module">
// Use local build with chunk caching support
import * as zarr from './packages/zarrita/dist/src/index.js';
import FetchStore from './packages/@zarrita-storage/dist/src/fetch.js';
// CryoET data portal dataset (Zarr v2, OME-Zarr multiscale level 2)
const ZARR_URL = 'https://files.cryoetdataportal.cziscience.com/10456/25jul29a_Position_13/Reconstructions/VoxelSpacing14.985/Tomograms/100/25jul29a_Position_13.zarr/2';
const NUM_SLICES = 10;
const output = document.getElementById('output');
const runBtn = document.getElementById('run');
async function benchmark(arr, numSlices, useCache = false) {
const cache = useCache ? new Map() : undefined;
const start = performance.now();
for (let z = 0; z < numSlices; z++) {
const result = await zarr.get(arr, [z, null, null], { cache });
}
const elapsed = performance.now() - start;
return { elapsed, cacheSize: cache?.size };
}
runBtn.addEventListener('click', async () => {
runBtn.disabled = true;
output.innerHTML = '<p>Loading array...</p>';
try {
const store = new FetchStore(ZARR_URL);
const root = zarr.root(store);
const arr = await zarr.open.v2(root, { kind: 'array' });
output.innerHTML = `<p>Array: shape=${JSON.stringify(arr.shape)}, chunks=${JSON.stringify(arr.chunks)}</p>`;
// Warm up browser cache
output.innerHTML += '<p>Warming up browser cache (fetching slices to populate HTTP cache)...</p>';
await benchmark(arr, NUM_SLICES, false);
output.innerHTML += '<p style="color: green;">✓ Browser cache warmed up</p>';
output.innerHTML += '<p>Running benchmark without cache...</p>';
const without = await benchmark(arr, NUM_SLICES, false);
output.innerHTML += '<p>Running benchmark with cache...</p>';
const withCache = await benchmark(arr, NUM_SLICES, true);
const speedup = (without.elapsed / withCache.elapsed).toFixed(2);
output.innerHTML += `
<div class="results">
<h3>Results</h3>
<table>
<tr><th>Metric</th><th>Without Cache</th><th>With Cache</th></tr>
<tr><td>Total time</td><td>${without.elapsed.toFixed(0)}ms</td><td>${withCache.elapsed.toFixed(0)}ms</td></tr>
<tr><td>Per slice</td><td>${(without.elapsed/NUM_SLICES).toFixed(1)}ms</td><td>${(withCache.elapsed/NUM_SLICES).toFixed(1)}ms</td></tr>
</table>
<p class="metric">Speedup: ${speedup}x</p>
</div>
`;
} catch (error) {
output.innerHTML = `<p style="color: red;">Error: ${error.message}</p>`;
console.error(error);
} finally {
runBtn.disabled = false;
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment