From cf549f3849bd1c4dfdc9c58901e9c84c296faa8f Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Sun, 13 Sep 2026 09:12:45 +0200 Subject: [PATCH 1/2] Lazy load CWV distribution histogram and sync with filter updates --- src/js/techreport/cwvDistribution.js | 87 ++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 18 deletions(-) diff --git a/src/js/techreport/cwvDistribution.js b/src/js/techreport/cwvDistribution.js index a386ab0f..57292a3f 100644 --- a/src/js/techreport/cwvDistribution.js +++ b/src/js/techreport/cwvDistribution.js @@ -12,16 +12,21 @@ class CwvDistribution { this.config = config; this.pageFilters = filters; this.distributionData = null; + this.isLoading = false; this.chart = null; this.root = document.querySelector(`[data-id="${this.id}"]`); this.date = this.pageFilters.end || this.root?.dataset?.latestDate || ''; this.selectedMetric = this.resolveMetric(UrlUtils.get('good-cwv-over-time')); const updateDateFromTimeseries = (newDate) => { + const dateChanged = this.date && this.date !== newDate; this.date = newDate; const tsSlot = this.root?.querySelector('[data-slot="cwv-distribution-timestamp"]'); if (tsSlot && this.date) tsSlot.textContent = UIUtils.printMonthYear(this.date); - if (!this.distributionData) { + if (dateChanged) { + this.distributionData = null; + } + if (!this.distributionData && !this.isLoading && !this.root?.classList.contains('hidden')) { this.fetchData(); } }; @@ -32,13 +37,12 @@ class CwvDistribution { const cwvChartDate = document.querySelector('#section-good_cwv_timeseries [data-slot=timestamp]'); if (cwvChartDate && cwvChartDate.dataset.date) { updateDateFromTimeseries(cwvChartDate.dataset.date); - } else { - document.addEventListener('timeseries-date-updated', (event) => { - if (event.detail.id === 'good_cwv_timeseries') { - updateDateFromTimeseries(event.detail.date); - } - }); } + document.addEventListener('timeseries-date-updated', (event) => { + if (event.detail.id === 'good_cwv_timeseries') { + updateDateFromTimeseries(event.detail.date); + } + }); } else { // Populate "Latest data" timestamp immediately const tsSlot = this.root?.querySelector('[data-slot="cwv-distribution-timestamp"]'); @@ -84,6 +88,17 @@ class CwvDistribution { this.toggle(!isVisible); }); } + + const submitBtn = document.getElementById('submit-form'); + if (submitBtn) { + submitBtn.addEventListener('click', () => { + if (this.root && !this.root.classList.contains('hidden')) { + const url = new URL(window.location.href); + url.hash = `#section-${this.id}`; + window.history.replaceState(null, null, url); + } + }, true); + } } toggle(show) { @@ -93,10 +108,22 @@ class CwvDistribution { if (btn) btn.textContent = 'Hide histogram'; if (!this.date) { const cwvChartDate = document.querySelector('#section-good_cwv_timeseries [data-slot=timestamp]'); - this.date = cwvChartDate.dataset.date; + if (cwvChartDate?.dataset?.date) { + this.date = cwvChartDate.dataset.date; + const tsSlot = this.root?.querySelector('[data-slot="cwv-distribution-timestamp"]'); + if (tsSlot && this.date) tsSlot.textContent = UIUtils.printMonthYear(this.date); + } } - if (!this.distributionData && this.date) { - this.fetchData(); + const currentUrl = this.getUrl(); + if (this.fetchedUrl && this.fetchedUrl !== currentUrl) { + this.distributionData = null; + } + if (!this.distributionData && !this.isLoading) { + if (this.date) { + this.fetchData(); + } else { + this.showLoader(); + } } else if (this.chart) { this.chart.reflow(); } @@ -118,8 +145,33 @@ class CwvDistribution { return document.getElementById(`${this.id}-chart`); } + getUrl() { + const technology = this.pageFilters.app.map(encodeURIComponent).join(','); + const rank = encodeURIComponent(this.pageFilters.rank || 'ALL'); + const geo = encodeURIComponent(this.pageFilters.geo || 'ALL'); + let url = `${Constants.apiBase}/cwv-distribution?technology=${technology}&rank=${rank}&geo=${geo}`; + if (this.date) { + url += `&date=${encodeURIComponent(this.date)}`; + } + return url; + } + updateContent() { - if (this.distributionData) this.renderChart(); + const isVisible = this.root && !this.root.classList.contains('hidden'); + const currentUrl = this.getUrl(); + const urlChanged = this.fetchedUrl && this.fetchedUrl !== currentUrl; + + if (urlChanged) { + this.distributionData = null; + } + + if (isVisible) { + if (!this.distributionData && !this.isLoading && this.date) { + this.fetchData(); + } else if (this.distributionData) { + this.renderChart(); + } + } } showLoader() { @@ -139,15 +191,12 @@ class CwvDistribution { } fetchData() { + if (this.isLoading) return; + this.isLoading = true; this.showLoader(); - const technology = this.pageFilters.app.map(encodeURIComponent).join(','); - const rank = encodeURIComponent(this.pageFilters.rank || 'ALL'); - const geo = encodeURIComponent(this.pageFilters.geo || 'ALL'); - let url = `${Constants.apiBase}/cwv-distribution?technology=${technology}&rank=${rank}&geo=${geo}`; - if (this.date) { - url += `&date=${encodeURIComponent(this.date)}`; - } + const url = this.getUrl(); + this.fetchedUrl = url; fetch(url) .then(r => { @@ -157,11 +206,13 @@ class CwvDistribution { .then(rows => { if (!Array.isArray(rows) || rows.length === 0) throw new Error('Empty response'); this.distributionData = rows; + this.isLoading = false; this.hideLoader(); this.renderChart(); }) .catch(err => { console.error('CWV Distribution fetch error:', err); + this.isLoading = false; this.showError(); }); } From 280c4c7a73fce8a5be2ee1544d7035431bfe2722 Mon Sep 17 00:00:00 2001 From: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> Date: Sun, 13 Sep 2026 13:40:16 +0200 Subject: [PATCH 2/2] fix: remove form submit hash update Signed-off-by: Max Ostapenko <1611259+max-ostapenko@users.noreply.github.com> --- src/js/components/filters.js | 3 +-- src/js/techreport/cwvDistribution.js | 11 ----------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/js/components/filters.js b/src/js/components/filters.js index 22e3e397..b2a0305e 100644 --- a/src/js/components/filters.js +++ b/src/js/components/filters.js @@ -97,8 +97,7 @@ class Filters { url.searchParams.delete('page'); url.searchParams.append('page', '1'); - // /* Scroll to the report content */ - // url.hash = '#report-content'; + // Preserves existing URL hash so expanded sections (e.g. #section-cwv_distribution) remain open if (url.pathname.includes('/reports/techreport/comparison') || url.pathname.includes('/reports/techreport/drilldown')) { url.pathname = '/reports/techreport/tech'; diff --git a/src/js/techreport/cwvDistribution.js b/src/js/techreport/cwvDistribution.js index 57292a3f..99cc9b07 100644 --- a/src/js/techreport/cwvDistribution.js +++ b/src/js/techreport/cwvDistribution.js @@ -88,17 +88,6 @@ class CwvDistribution { this.toggle(!isVisible); }); } - - const submitBtn = document.getElementById('submit-form'); - if (submitBtn) { - submitBtn.addEventListener('click', () => { - if (this.root && !this.root.classList.contains('hidden')) { - const url = new URL(window.location.href); - url.hash = `#section-${this.id}`; - window.history.replaceState(null, null, url); - } - }, true); - } } toggle(show) {