From 82441fb22ce9a53fbf3a909113df385c697477bc Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Wed, 18 Mar 2026 13:59:20 +0200 Subject: [PATCH 01/13] Use ResizeObserver instead of polling for document height --- tracker/src/engagement.js | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tracker/src/engagement.js b/tracker/src/engagement.js index fcc302169e1a..eb94051f4593 100644 --- a/tracker/src/engagement.js +++ b/tracker/src/engagement.js @@ -151,23 +151,11 @@ export function init() { currentDocumentHeight = getDocumentHeight() maxScrollDepthPx = getCurrentScrollDepthPx() - window.addEventListener('load', function () { + new ResizeObserver(function () { currentDocumentHeight = getDocumentHeight() - - // Update the document height again after every 200ms during the - // next 3 seconds. This makes sure dynamically loaded content is - // also accounted for. - var count = 0 - var interval = setInterval(function () { - currentDocumentHeight = getDocumentHeight() - if (++count === 15) { - clearInterval(interval) - } - }, 200) - }) + }).observe(document.documentElement) document.addEventListener('scroll', function () { - currentDocumentHeight = getDocumentHeight() var currentScrollDepthPx = getCurrentScrollDepthPx() if (currentScrollDepthPx > maxScrollDepthPx) { From 3c8c5e7d2e96f9f1a594579131fb76bcbe9d8163 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Wed, 18 Mar 2026 14:52:12 +0200 Subject: [PATCH 02/13] fix: avoid forced reflow in getCurrentScrollDepthPx window.scrollY and window.innerHeight are compositor-cached values that never trigger layout recalculation, unlike el.scrollTop and el.clientHeight. The fallbacks only existed for IE which is already unsupported. --- tracker/src/engagement.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tracker/src/engagement.js b/tracker/src/engagement.js index eb94051f4593..f74e51694a44 100644 --- a/tracker/src/engagement.js +++ b/tracker/src/engagement.js @@ -137,10 +137,8 @@ function getDocumentHeight() { } function getCurrentScrollDepthPx() { - var body = document.body || {} - var el = document.documentElement || {} - var viewportHeight = window.innerHeight || el.clientHeight || 0 - var scrollTop = window.scrollY || el.scrollTop || body.scrollTop || 0 + var viewportHeight = window.innerHeight + var scrollTop = window.scrollY return currentDocumentHeight <= viewportHeight ? currentDocumentHeight From 6579f68f815ac79f62987eca44c7009ce00a5e99 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Wed, 18 Mar 2026 15:19:03 +0200 Subject: [PATCH 03/13] disable engagement tracking in compat mode --- tracker/src/plausible.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tracker/src/plausible.js b/tracker/src/plausible.js index f8b669c7c2a8..51ab1fa7c7b5 100644 --- a/tracker/src/plausible.js +++ b/tracker/src/plausible.js @@ -16,7 +16,9 @@ function init(overrides) { initConfig(options) - initEngagementTracking() + if (!COMPILE_COMPAT) { + initEngagementTracking() + } if (!COMPILE_MANUAL || (COMPILE_CONFIG && config.autoCapturePageviews)) { initAutocapture(track) From e4e48703246e9ddc46ae18434ff40c255428172c Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Wed, 18 Mar 2026 15:34:41 +0200 Subject: [PATCH 04/13] Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b0296baa2ee..3853bf2d56a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ All notable changes to this project will be documented in this file. - Moved graph interval picker, export button, imported data toggle and notices out of the graph and into a new options menu in the top bar - Standardised and improved segment and filter modals styling - Changed graph tooltip positioning logic: it now aligns to the top of the chart, to the right of the hovered data point +- Use ResizeObserver instead of polling in tracker for scroll depth. Removes forced reflows caused by the tracker script. ### Fixed From 663bd238415b1a57ebada066e57403aafdc07415 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Wed, 18 Mar 2026 15:45:42 +0200 Subject: [PATCH 05/13] Bump tracker script version --- tracker/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tracker/package.json b/tracker/package.json index ec0a47654a29..8e15e9d138a4 100644 --- a/tracker/package.json +++ b/tracker/package.json @@ -1,5 +1,5 @@ { - "tracker_script_version": 33, + "tracker_script_version": 34, "type": "module", "scripts": { "lint": "eslint", From d883d1de38f27b2bb08d43f9d2cee4658729adf1 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:06:42 +0300 Subject: [PATCH 06/13] Add COMPAT fallback for engagement tracking --- tracker/src/engagement.js | 27 ++++++++++++++++++++++++--- tracker/src/plausible.js | 4 +--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/tracker/src/engagement.js b/tracker/src/engagement.js index f74e51694a44..22b48b04e87e 100644 --- a/tracker/src/engagement.js +++ b/tracker/src/engagement.js @@ -137,6 +137,16 @@ function getDocumentHeight() { } function getCurrentScrollDepthPx() { + if (COMPILE_COMPAT) { + var el = document.documentElement || {} + var body = document.body || {} + var viewportHeight = window.innerHeight || el.clientHeight || 0 + var scrollTop = window.scrollY || window.pageYOffset || el.scrollTop || body.scrollTop || 0 + return currentDocumentHeight <= viewportHeight + ? currentDocumentHeight + : scrollTop + viewportHeight + } + var viewportHeight = window.innerHeight var scrollTop = window.scrollY @@ -149,9 +159,20 @@ export function init() { currentDocumentHeight = getDocumentHeight() maxScrollDepthPx = getCurrentScrollDepthPx() - new ResizeObserver(function () { - currentDocumentHeight = getDocumentHeight() - }).observe(document.documentElement) + if (COMPILE_COMPAT) { + window.addEventListener('load', function () { + currentDocumentHeight = getDocumentHeight() + var count = 0 + var interval = setInterval(function () { + currentDocumentHeight = getDocumentHeight() + if (++count === 15) clearInterval(interval) + }, 200) + }) + } else { + new ResizeObserver(function () { + currentDocumentHeight = getDocumentHeight() + }).observe(document.documentElement) + } document.addEventListener('scroll', function () { var currentScrollDepthPx = getCurrentScrollDepthPx() diff --git a/tracker/src/plausible.js b/tracker/src/plausible.js index 51ab1fa7c7b5..f8b669c7c2a8 100644 --- a/tracker/src/plausible.js +++ b/tracker/src/plausible.js @@ -16,9 +16,7 @@ function init(overrides) { initConfig(options) - if (!COMPILE_COMPAT) { - initEngagementTracking() - } + initEngagementTracking() if (!COMPILE_MANUAL || (COMPILE_CONFIG && config.autoCapturePageviews)) { initAutocapture(track) From 215006ffd1b0ea85c1da9f1cfb0481b90793c13f Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:09:13 +0300 Subject: [PATCH 07/13] Fix lint --- tracker/src/engagement.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tracker/src/engagement.js b/tracker/src/engagement.js index 22b48b04e87e..c8359a81792e 100644 --- a/tracker/src/engagement.js +++ b/tracker/src/engagement.js @@ -137,19 +137,16 @@ function getDocumentHeight() { } function getCurrentScrollDepthPx() { + var viewportHeight, scrollTop if (COMPILE_COMPAT) { var el = document.documentElement || {} var body = document.body || {} - var viewportHeight = window.innerHeight || el.clientHeight || 0 - var scrollTop = window.scrollY || window.pageYOffset || el.scrollTop || body.scrollTop || 0 - return currentDocumentHeight <= viewportHeight - ? currentDocumentHeight - : scrollTop + viewportHeight + viewportHeight = window.innerHeight || el.clientHeight || 0 + scrollTop = window.scrollY || window.pageYOffset || el.scrollTop || body.scrollTop || 0 + } else { + viewportHeight = window.innerHeight + scrollTop = window.scrollY } - - var viewportHeight = window.innerHeight - var scrollTop = window.scrollY - return currentDocumentHeight <= viewportHeight ? currentDocumentHeight : scrollTop + viewportHeight From 7681b90368408ba2fd826e7a6062a7de3a1f1aa0 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:13:49 +0300 Subject: [PATCH 08/13] Fix formatting issues --- tracker/src/engagement.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tracker/src/engagement.js b/tracker/src/engagement.js index c8359a81792e..c4a6ab9e55c8 100644 --- a/tracker/src/engagement.js +++ b/tracker/src/engagement.js @@ -142,7 +142,12 @@ function getCurrentScrollDepthPx() { var el = document.documentElement || {} var body = document.body || {} viewportHeight = window.innerHeight || el.clientHeight || 0 - scrollTop = window.scrollY || window.pageYOffset || el.scrollTop || body.scrollTop || 0 + scrollTop = + window.scrollY || + window.pageYOffset || + el.scrollTop || + body.scrollTop || + 0 } else { viewportHeight = window.innerHeight scrollTop = window.scrollY From 7d1b6d09a2ae86cca3e4431a546abf26ca2fa6f4 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:24:02 +0300 Subject: [PATCH 09/13] fix: use hkps keyserver to avoid blocked port 80 in CI --- .github/workflows/tracker-script-update.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tracker-script-update.yml b/.github/workflows/tracker-script-update.yml index a4f041b7a4a5..06ab681c7d71 100644 --- a/.github/workflows/tracker-script-update.yml +++ b/.github/workflows/tracker-script-update.yml @@ -30,13 +30,15 @@ jobs: - name: Install jq and clickhouse-local run: | - sudo apt-get install apt-transport-https ca-certificates dirmngr - sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 8919F6BD2B48D754 - echo "deb https://packages.clickhouse.com/deb stable main" | sudo tee \ - /etc/apt/sources.list.d/clickhouse.list + sudo apt-get install -y apt-transport-https ca-certificates dirmngr + sudo gpg --no-default-keyring \ + --keyring /usr/share/keyrings/clickhouse-archive-keyring.gpg \ + --keyserver hkps://keyserver.ubuntu.com \ + --recv-keys 8919F6BD2B48D754 + echo "deb [signed-by=/usr/share/keyrings/clickhouse-archive-keyring.gpg] https://packages.clickhouse.com/deb stable main" \ + | sudo tee /etc/apt/sources.list.d/clickhouse.list sudo apt-get update - - sudo apt-get install jq clickhouse-server -y + sudo apt-get install -y jq clickhouse-server - name: Compare and increment tracker_script_version id: increment From c6390cfde9d32882e4b09078e71152ae90f737cd Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:25:55 +0300 Subject: [PATCH 10/13] fix: fetch ClickHouse key via curl instead of keyserver --- .github/workflows/tracker-script-update.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tracker-script-update.yml b/.github/workflows/tracker-script-update.yml index 06ab681c7d71..38683ca7b9cd 100644 --- a/.github/workflows/tracker-script-update.yml +++ b/.github/workflows/tracker-script-update.yml @@ -30,11 +30,8 @@ jobs: - name: Install jq and clickhouse-local run: | - sudo apt-get install -y apt-transport-https ca-certificates dirmngr - sudo gpg --no-default-keyring \ - --keyring /usr/share/keyrings/clickhouse-archive-keyring.gpg \ - --keyserver hkps://keyserver.ubuntu.com \ - --recv-keys 8919F6BD2B48D754 + curl -fsSL 'https://packages.clickhouse.com/rpm/lts/repodata/repomd.xml.key' \ + | sudo gpg --batch --yes --dearmor -o /usr/share/keyrings/clickhouse-archive-keyring.gpg echo "deb [signed-by=/usr/share/keyrings/clickhouse-archive-keyring.gpg] https://packages.clickhouse.com/deb stable main" \ | sudo tee /etc/apt/sources.list.d/clickhouse.list sudo apt-get update From 4fb22a758473b080aecd6195dd90dbd80d946cc8 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:39:44 +0300 Subject: [PATCH 11/13] chore: print PR labels in workflow for debugging --- .github/workflows/tracker-script-update.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tracker-script-update.yml b/.github/workflows/tracker-script-update.yml index 38683ca7b9cd..20e3ed669037 100644 --- a/.github/workflows/tracker-script-update.yml +++ b/.github/workflows/tracker-script-update.yml @@ -116,6 +116,7 @@ jobs: contains(github.event.pull_request.labels.*.name, 'tracker-release: none') ) }} run: | + echo "PR labels: ${{ toJSON(github.event.pull_request.labels.*.name) }}" echo "::error::PR changes tracker script but does not have a 'tracker release:' label. Please add one." exit 1 From 04360c887b557d51c4d5a4118129837b4bfa00a2 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:45:43 +0300 Subject: [PATCH 12/13] Revert "chore: print PR labels in workflow for debugging" This reverts commit 4fb22a758473b080aecd6195dd90dbd80d946cc8. --- .github/workflows/tracker-script-update.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tracker-script-update.yml b/.github/workflows/tracker-script-update.yml index 20e3ed669037..38683ca7b9cd 100644 --- a/.github/workflows/tracker-script-update.yml +++ b/.github/workflows/tracker-script-update.yml @@ -116,7 +116,6 @@ jobs: contains(github.event.pull_request.labels.*.name, 'tracker-release: none') ) }} run: | - echo "PR labels: ${{ toJSON(github.event.pull_request.labels.*.name) }}" echo "::error::PR changes tracker script but does not have a 'tracker release:' label. Please add one." exit 1 From c3560ef670f8bb081e73daf5633a234f842c1662 Mon Sep 17 00:00:00 2001 From: Uku Taht Date: Tue, 5 May 2026 15:46:43 +0300 Subject: [PATCH 13/13] Add tracker script changelog entry --- tracker/npm_package/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tracker/npm_package/CHANGELOG.md b/tracker/npm_package/CHANGELOG.md index 712eb449b543..67463f87277d 100644 --- a/tracker/npm_package/CHANGELOG.md +++ b/tracker/npm_package/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## [0.4.5] - 2026-05-05 + +- Use ResizeObserver over polling for getting scroll metrics + ## [0.4.4] - 2025-10-31 - Convert all TypeScript definition comments from `//` style to JSDoc `/** */` style for better IDE integration and TypeScript tooling support