Published
Edited
Mar 3, 2021
Insert cell
Insert cell
Insert cell
Insert cell
// the target url can be changed for a better comparison
getUrl = i => `https://jsonplaceholder.typicode.com/posts/${i}`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
tooltip = d3
.select("body")
.append("div")
.attr("class", "svg-tooltip")
.style("position", "absolute")
.style("visibility", "hidden")
Insert cell
chart.update(result)
Insert cell
Insert cell
Insert cell
config = ({
height: 300,
marginX: 50,
marginY: 50
})
Insert cell
formatMs = x => `${x.toFixed(0)}ms`
Insert cell
mutable result = ({ normalEntries: [], workerEntries: [] })
Insert cell
sortResult = () => {
const normalEntries = d3.sort(result.normalEntries);
const workerEntries = d3.sort(result.workerEntries);
mutable result = { normalEntries, workerEntries };
}
Insert cell
makeBatchUrl = () => {
return d3
.range(sampling)
.map((_, i) => d3.range(sampleTry).map((_, i) => getUrl(i + 1)));
}
Insert cell
async function startWork() {
mutable jobFinished = false;
mutable jobStarted = true;
let normalEntries = [];
let workerEntries = [];
mutable result = { normalEntries, workerEntries };
console.log('started downloading!');

const batchUrls = makeBatchUrl();

normalEntries = [
...result.normalEntries,
...(await Promise.all(batchUrls.map(fetchNormal)))
];
mutable result = { normalEntries, workerEntries };

const _batchUrls = makeBatchUrl();
const worker = new Worker(workerScript);
workerEntries = [
...result.workerEntries,
...(await Promise.all(_batchUrls.map(urls => fetchWorker(worker, urls))))
];
worker.terminate();

console.log('started worker downloading!');
mutable result = { normalEntries, workerEntries };
mutable jobFinished = true;
}
Insert cell
function asleep(_time = 300) {
return new Promise((resolve, reject) => {
setTimeout(resolve, _time);
});
}
Insert cell
async function fetchNormal(urls) {
const startTime = performance.now();
const normalFetches = urls.map(normalFetcher);
await Promise.all(normalFetches);
const endTime = performance.now();
await asleep(500);
return endTime - startTime;
}
Insert cell
async function fetchWorker(worker, urls) {
const startTime = performance.now();
const workerFetches = urls.map(url => workerFetcher(worker, url));
await Promise.all(workerFetches);
const endTime = performance.now();
await asleep(500);
return endTime - startTime;
}
Insert cell
mutable jobStarted = false
Insert cell
mutable jobFinished = false
Insert cell
normalFetcher = async url => {
const req = await fetch(url);
const json = await req.json();
return json;
}
Insert cell
workerFetcher = (worker, url) => {
return new Promise((resolve, reject) => {
worker.addEventListener('message', ({ data }) => {
resolve(data);
});
worker.postMessage(url);
});
}
Insert cell
workerScript = makeWorkerScript(`
onmessage = async function({data}) {
const req = await fetch(data);
const json = await req.json();
postMessage(json);
}
`)
Insert cell
makeWorkerScript = _script => {
const blob = new Blob([_script], { type: 'text/javascript' });
const script = URL.createObjectURL(blob);
invalidation.then(() => URL.revokeObjectURL(script));
return script;
}
Insert cell
d3 = require('d3@v6.5.0')
Insert cell
import { setCoords, setSize, trans2d } from '@rabelais/tree-utils'
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more