From 7181d599667d4143c737b774ec053d5262e1e13f Mon Sep 17 00:00:00 2001 From: nym21 Date: Mon, 1 Jun 2026 00:38:12 +0200 Subject: [PATCH] heatmaps: part 10 --- .../src/generators/javascript/client.rs | 2 +- modules/brk-client/index.js | 2 +- website/src/heatmap/grid.js | 34 ++++--- website/src/heatmap/index.js | 93 +------------------ website/src/heatmap/oracle.js | 25 ----- 5 files changed, 24 insertions(+), 132 deletions(-) diff --git a/crates/brk_bindgen/src/generators/javascript/client.rs b/crates/brk_bindgen/src/generators/javascript/client.rs index a08992121..80744f2eb 100644 --- a/crates/brk_bindgen/src/generators/javascript/client.rs +++ b/crates/brk_bindgen/src/generators/javascript/client.rs @@ -482,7 +482,7 @@ class BrkClientBase {{ const url = `${{this.baseUrl}}${{path}}`; /** @type {{_MemEntry | undefined}} */ const memHit = this._memGet(url); - const browserCache = this._browserCache ?? await this._browserCachePromise; + const browserCache = this._browserCache; // L1 fast path: deliver from memCache, revalidate via network. // ETag match → zero parse, zero clone, zero cache write, no second onValue fire. diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index 5f3a0b660..394933769 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -1916,7 +1916,7 @@ class BrkClientBase { const url = `${this.baseUrl}${path}`; /** @type {_MemEntry | undefined} */ const memHit = this._memGet(url); - const browserCache = this._browserCache ?? await this._browserCachePromise; + const browserCache = this._browserCache; // L1 fast path: deliver from memCache, revalidate via network. // ETag match → zero parse, zero clone, zero cache write, no second onValue fire. diff --git a/website/src/heatmap/grid.js b/website/src/heatmap/grid.js index 733445563..112c37c91 100644 --- a/website/src/heatmap/grid.js +++ b/website/src/heatmap/grid.js @@ -65,15 +65,24 @@ export function createAverageGrid({ * @param {number} value */ function addValue(col, y, value) { - if (!Number.isFinite(value)) return undefined; + if (!Number.isFinite(value)) return false; const row = toRow(y); - if (row === undefined) return undefined; + if (row === undefined) return false; const index = row * cols + col; sums[index] += value; counts[index] += 1; - maxByCol[col] = Math.max(maxByCol[col], sums[index] / counts[index]); + return true; + } + + /** @param {number} col */ + function updateColumnMax(col) { + let max = 0; + for (let row = 0; row < rows; row++) { + const index = row * cols + col; + if (counts[index]) max = Math.max(max, sums[index] / counts[index]); + } + maxByCol[col] = max; cumulativeMaxDirty = true; - return col; } /** @type {HeatmapGrid} */ @@ -87,22 +96,19 @@ export function createAverageGrid({ let dirty = false; if (points.kind === "implicit") { for (let i = 0; i < points.values.length; i++) { - dirty = - addValue( - col, - points.yStart + i * points.yStep, - points.values[i], - ) !== undefined || dirty; + if (addValue(col, points.yStart + i * points.yStep, points.values[i])) { + dirty = true; + } } } else { const length = Math.min(points.y.length, points.values.length); for (let i = 0; i < length; i++) { - dirty = - addValue(col, points.y[i], points.values[i]) !== undefined || - dirty; + if (addValue(col, points.y[i], points.values[i])) dirty = true; } } - return dirty ? col : undefined; + if (!dirty) return undefined; + updateColumnMax(col); + return col; }, getValue(col, row) { if (col < 0 || col >= cols || row < 0 || row >= rows) { diff --git a/website/src/heatmap/index.js b/website/src/heatmap/index.js index 9b294d63c..affe6d987 100644 --- a/website/src/heatmap/index.js +++ b/website/src/heatmap/index.js @@ -15,8 +15,6 @@ import { dateRange, GENESIS_DATE, todayISODate, toISODate } from "./time.js"; */ const MAX_PARALLEL_FETCHES = 8; -const DEBUG = true; -const DEBUG_STARTED_AT = performance.now(); /** @type {ReturnType | undefined} */ let renderer; @@ -43,22 +41,11 @@ let initialized = false; let from = yearStartISODate(new Date().getUTCFullYear()); let to = todayISODate(); -/** - * @param {string} message - * @param {Record} [data] - */ -function debug(message, data) { - if (!DEBUG) return; - const elapsed = Math.round(performance.now() - DEBUG_STARTED_AT); - console.log(`[heatmap +${elapsed}ms] ${message}`, data ?? ""); -} - /** * Initializes the heatmap pane once for the app lifetime. */ export function init() { if (initialized) return; - debug("init:start"); initialized = true; const header = createHeader(); @@ -79,17 +66,13 @@ export function init() { new ResizeObserver( debounce(() => { - debug("resize"); resizeAndRebuild(); }, 250), ).observe(heatmapElement); - - debug("init:done"); } /** @param {HeatmapOption} option */ export function setOption(option) { - debug("setOption", { title: option.title, same: currentOption === option }); init(); if (currentOption !== option) { currentOption = option; @@ -103,19 +86,11 @@ export function setOption(option) { function resizeAndRebuild() { if (!canvas || !renderer) return; const { width, height } = canvas.getBoundingClientRect(); - debug("resizeAndRebuild", { width, height }); if (renderer.resize(width, height)) rebuildGrid(); } function loadRange() { if (!currentOption) return; - const startedAt = performance.now(); - debug("loadRange:start", { - title: currentOption.title, - from, - to, - cacheSize: pointsByDate.size, - }); abortController?.abort(); const generation = ++loadGeneration; @@ -123,7 +98,6 @@ function loadRange() { const controller = new AbortController(); abortController = controller; currentDates = dateRange(from, to); - debug("loadRange:dates", { count: currentDates.length }); /** @type {{ date: string, dateIndex: number }[]} */ const missing = []; @@ -134,41 +108,22 @@ function loadRange() { let completed = currentDates.length - missing.length; let failed = 0; updateStatus(completed, currentDates.length, failed); - debug("loadRange:missing", { - missing: missing.length, - cached: completed, - total: currentDates.length, - }); if (!missing.length) { - debug("loadRange:all-cached:rebuild:start"); rebuildGrid(); - debug("loadRange:all-cached:rebuild:done", { - elapsed: Math.round(performance.now() - startedAt), - }); abortController = undefined; return; } let cursor = 0; - debug("loadRange:workers:start", { - workers: Math.min(MAX_PARALLEL_FETCHES, missing.length), - }); const workers = Array.from({ length: Math.min(MAX_PARALLEL_FETCHES, missing.length), - }).map(async (_, workerId) => { - debug("worker:start", { workerId }); + }).map(async () => { let index = nextMissingIndex(); while (index !== undefined) { const entry = missing[index]; try { - if (completed < 10) { - debug("worker:fetch:start", { workerId, date: entry.date }); - } const points = await option.points.fetch(entry.date, controller.signal); - if (completed < 10) { - debug("worker:fetch:done", { workerId, date: entry.date }); - } if (isCurrentLoad(option, controller, generation)) { pointsByDate.set(entry.date, points); addDateToGrid(entry.dateIndex, points); @@ -181,42 +136,18 @@ function loadRange() { if (isCurrentLoad(option, controller, generation)) { completed += 1; updateStatus(completed, currentDates.length, failed); - if (completed <= 10 || completed % 25 === 0 || completed === currentDates.length) { - debug("loadRange:progress", { - completed, - total: currentDates.length, - failed, - elapsed: Math.round(performance.now() - startedAt), - }); - } } } index = nextMissingIndex(); } - debug("worker:done", { workerId }); }); - debug("loadRange:rebuild:start"); rebuildGrid(); - debug("loadRange:rebuild:done", { - elapsed: Math.round(performance.now() - startedAt), - }); void Promise.all(workers).then(() => { if (isCurrentLoad(option, controller, generation)) { updateStatus(completed, currentDates.length, failed); - debug("loadRange:final-paint:start", { - completed, - total: currentDates.length, - failed, - }); paint(); - debug("loadRange:done", { - completed, - total: currentDates.length, - failed, - elapsed: Math.round(performance.now() - startedAt), - }); } }); @@ -243,7 +174,6 @@ function isCurrentLoad(option, controller, generation) { } function rebuildGrid() { - const startedAt = performance.now(); if ( !currentOption || !renderer || @@ -252,39 +182,21 @@ function rebuildGrid() { !currentDates.length ) { currentGrid = undefined; - debug("rebuildGrid:skip"); return; } - debug("rebuildGrid:create:start", { - dates: currentDates.length, - width: renderer.width, - height: renderer.height, - cached: pointsByDate.size, - }); currentGrid = currentOption.grid.create({ dates: currentDates, width: renderer.width, height: renderer.height, }); - let added = 0; for (let i = 0; i < currentDates.length; i++) { const points = pointsByDate.get(currentDates[i]); - if (points) { - currentGrid.add(i, points); - added += 1; - } + if (points) currentGrid.add(i, points); } - debug("rebuildGrid:add:done", { - added, - elapsed: Math.round(performance.now() - startedAt), - }); paint(); - debug("rebuildGrid:paint:done", { - elapsed: Math.round(performance.now() - startedAt), - }); } /** @@ -299,7 +211,6 @@ function addDateToGrid(dateIndex, points) { /** @param {number} col */ function schedulePaint(col) { - if (dirtyCols.size === 0) debug("paint:schedule", { col }); dirtyCols.add(col); if (paintScheduled) return; paintScheduled = true; diff --git a/website/src/heatmap/oracle.js b/website/src/heatmap/oracle.js index f1785c79e..b8391a7cb 100644 --- a/website/src/heatmap/oracle.js +++ b/website/src/heatmap/oracle.js @@ -9,19 +9,6 @@ import { defaultTooltip } from "./tooltip.js"; const BINS = 2400; const MIN_LOG = -8; const BINS_PER_DECADE = 200; -const DEBUG = true; -const DEBUG_STARTED_AT = performance.now(); -let fetchLogCount = 0; - -/** - * @param {string} message - * @param {Record} [data] - */ -function debug(message, data) { - if (!DEBUG) return; - const elapsed = Math.round(performance.now() - DEBUG_STARTED_AT); - console.log(`[heatmap:oracle +${elapsed}ms] ${message}`, data ?? ""); -} export const oracleRawHeatmapOption = createOracleHeatmapOption("raw", "Raw"); export const oracleEmaHeatmapOption = createOracleHeatmapOption("ema", "EMA"); @@ -56,23 +43,11 @@ function createOracleHeatmapOption(mode, name) { * @returns {Promise} */ async function fetchOraclePoints(mode, date, signal) { - const shouldLog = DEBUG && fetchLogCount < 20; - fetchLogCount += 1; - const startedAt = performance.now(); - if (shouldLog) debug("fetch:start", { mode, date }); const values = await firstAvailable((onValue) => mode === "raw" ? brk.getOracleHistogramRaw(date, { signal, onValue }) : brk.getOracleHistogramEma(date, { signal, onValue }), ); - if (shouldLog) { - debug("fetch:done", { - mode, - date, - length: values.length, - elapsed: Math.round(performance.now() - startedAt), - }); - } return { kind: "implicit",