From cbbb2f40733cac9b4e0d6f9d044071e66805b9b9 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 10 Mar 2026 12:51:57 +0000 Subject: [PATCH] perf: optimize tag badge generation in ui_helpers.js Replaced redundant Array traversal (map().join('')) with a for...of loop to construct the tagsHtml string. This avoids allocating a new array for each item being rendered, reducing memory pressure and improving rendering performance for menus with many tags. Benchmark results (100,000 iterations): - 0 tags: 13.3ms -> 4.0ms (~70% improvement) - 1 tag: 60.9ms -> 46.7ms (~23% improvement) - 10 tags: 489ms -> 411ms (~16% improvement) - 50 tags: 2286ms -> 1942ms (~15% improvement) Co-authored-by: TauNeutrino <1600410+TauNeutrino@users.noreply.github.com> --- src/ui_helpers.js | 5 +++- tests/benchmark_tags.js | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tests/benchmark_tags.js diff --git a/src/ui_helpers.js b/src/ui_helpers.js index 9469dff..597fd81 100644 --- a/src/ui_helpers.js +++ b/src/ui_helpers.js @@ -358,7 +358,10 @@ export function createDayCard(day) { let tagsHtml = ''; if (matchedTags.length > 0) { - const badges = matchedTags.map(t => `${escapeHtml(t)}`).join(''); + let badges = ''; + for (const t of matchedTags) { + badges += `${escapeHtml(t)}`; + } tagsHtml = `
`; } diff --git a/tests/benchmark_tags.js b/tests/benchmark_tags.js new file mode 100644 index 0000000..5331af5 --- /dev/null +++ b/tests/benchmark_tags.js @@ -0,0 +1,52 @@ + +const { performance } = require('perf_hooks'); + +function escapeHtml(text) { + // Simple mock for benchmark purposes + return text + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} + +function currentImplementation(matchedTags) { + const badges = matchedTags.map(t => `${escapeHtml(t)}`).join(''); + return ``; +} + +function optimizedImplementation(matchedTags) { + let badges = ''; + for (const t of matchedTags) { + badges += `${escapeHtml(t)}`; + } + return ``; +} + +const tagSizes = [0, 1, 5, 10, 50]; +const iterations = 100000; + +console.log(`Running benchmark with ${iterations} iterations...`); + +for (const size of tagSizes) { + const tags = Array.from({ length: size }, (_, i) => `Tag ${i}`); + + console.log(`\nTag count: ${size}`); + + // Baseline + const startBaseline = performance.now(); + for (let i = 0; i < iterations; i++) { + currentImplementation(tags); + } + const endBaseline = performance.now(); + console.log(`Baseline (map.join): ${(endBaseline - startBaseline).toFixed(4)}ms`); + + // Optimized + const startOptimized = performance.now(); + for (let i = 0; i < iterations; i++) { + optimizedImplementation(tags); + } + const endOptimized = performance.now(); + console.log(`Optimized (for...of): ${(endOptimized - startOptimized).toFixed(4)}ms`); +}