From ba5f16358f0233811c6e73086573f04c731930cb Mon Sep 17 00:00:00 2001 From: Bruno Windels Date: Fri, 22 Feb 2019 18:30:22 +0100 Subject: [PATCH] fall back to InteractionObserver for detecting timeline resizes this is not nearly as smooth as using ResizeObserver, as the callback rate is a lot lower, but seems to be quite a bit better than what we have right now, without the 7% cpu hog that the requestAnimationFrame polling fallback has. --- src/components/structures/ScrollPanel.js | 33 +++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/components/structures/ScrollPanel.js b/src/components/structures/ScrollPanel.js index ecfdfd5db2..ecbb5ab868 100644 --- a/src/components/structures/ScrollPanel.js +++ b/src/components/structures/ScrollPanel.js @@ -78,6 +78,28 @@ if (DEBUG_SCROLL) { * scroll down further. If stickyBottom is disabled, we just save the scroll * offset as normal. */ + + +function createTimelineResizeDetector(scrollNode, itemlist, callback) { + if (typeof ResizeObserver !== "undefined") { + const ro = new ResizeObserver(callback); + ro.observe(itemlist); + return ro; + } else if (typeof IntersectionObserver !== "undefined") { + const threshold = []; + for (let i = 0; i < 1000; ++i) { + threshold.push(i / 1000); + } + threshold.push(1); + const io = new IntersectionObserver( + callback, + {root: scrollNode, threshold}, + ); + io.observe(itemlist); + return io; + } +} + module.exports = React.createClass({ displayName: 'ScrollPanel', @@ -161,12 +183,11 @@ module.exports = React.createClass({ componentDidMount: function() { this.checkScroll(); - if (typeof ResizeObserver !== "undefined") { - this._timelineSizeObserver = new ResizeObserver(() => { - this._restoreSavedScrollState(); - }); - this._timelineSizeObserver.observe(this.refs.itemlist); - } + this._timelineSizeObserver = createTimelineResizeDetector( + this._getScrollNode(), + this.refs.itemlist, + () => { this._restoreSavedScrollState(); }, + ); }, componentDidUpdate: function() {