From be07f1f57269fd90a2afa09279eaf2f60bb2388c Mon Sep 17 00:00:00 2001 From: Johannes Odland Date: Mon, 12 Feb 2024 22:53:42 +0100 Subject: [PATCH] Improve performance during resize --- src/scroll-timeline-base.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/scroll-timeline-base.js b/src/scroll-timeline-base.js index 2c85492..9889dc6 100644 --- a/src/scroll-timeline-base.js +++ b/src/scroll-timeline-base.js @@ -213,8 +213,18 @@ export function measureSubject(source, subject) { * Update measurements of source, and update timelines * @param {HTMLElement} source */ -function updateMeasurements(source) { +function updateMeasurements(source, throttle) { let details = sourceDetails.get(source); + if (details.updateScheduled && throttle) { + // Update already scheduled for the next animation frame + return; + } + + details.updateScheduled = true + requestAnimationFrame(() => { + details.updateScheduled = false + }) + details.sourceMeasurements = measureSource(source); // Update measurements of the subject of connected view timelines @@ -226,9 +236,6 @@ function updateMeasurements(source) { } } - if (details.updateScheduled) - return; - setTimeout(() => { // Schedule a task to update timelines after all measurements are completed for (const ref of details.timelineRefs) { @@ -237,10 +244,7 @@ function updateMeasurements(source) { updateInternal(timeline); } } - - details.updateScheduled = false; }); - details.updateScheduled = true; } function updateSource(timeline, source) { @@ -283,9 +287,7 @@ function updateSource(timeline, source) { // Use resize observer to detect changes to source size const resizeObserver = new ResizeObserver((entries) => { - for (const entry of entries) { - updateMeasurements(timelineDetails.source) - } + updateMeasurements(timelineDetails.source, true) }); resizeObserver.observe(source); for (const child of source.children) { @@ -295,7 +297,7 @@ function updateSource(timeline, source) { // Use mutation observer to detect updated style attributes on source element const mutationObserver = new MutationObserver((records) => { for (const record of records) { - updateMeasurements(record.target); + updateMeasurements(record.target, false); } }); mutationObserver.observe(source, {attributes: true, attributeFilter: ['style', 'class']}); @@ -836,12 +838,12 @@ export class ViewTimeline extends ScrollTimeline { } if (details.subject) { const resizeObserver = new ResizeObserver(() => { - updateMeasurements(details.source) + updateMeasurements(details.source, true) }) resizeObserver.observe(details.subject) const mutationObserver = new MutationObserver(() => { - updateMeasurements(details.source); + updateMeasurements(details.source, false); }); mutationObserver.observe(details.subject, {attributes: true, attributeFilter: ['class', 'style']}); }