From bb3ee88ced82b596650173a901790979667df90e Mon Sep 17 00:00:00 2001 From: Oran Epelbaum Date: Thu, 5 Aug 2021 16:57:52 +0300 Subject: [PATCH] added passive listener indication to event handlers, to resolve performance warning --- src/index.tsx | 22 +++++++++++------ src/utils/passive-event-feature-detection.ts | 26 ++++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 src/utils/passive-event-feature-detection.ts diff --git a/src/index.tsx b/src/index.tsx index 2782fbb..06c7379 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,7 @@ import React, { Component, ReactNode, CSSProperties } from 'react'; import { throttle } from 'throttle-debounce'; import { ThresholdUnits, parseThreshold } from './utils/threshold'; +import { supportsPassive } from './utils/passive-event-feature-detection'; type Fn = () => any; export interface Props { @@ -80,9 +81,14 @@ export default class InfiniteScroll extends Component { ? this._infScroll : this._scrollableNode || window; + const eventListenerOpts = supportsPassive() ? { passive: true } : false; + if (this.el) { - this.el.addEventListener('scroll', this - .throttledOnScrollListener as EventListenerOrEventListenerObject); + this.el.addEventListener( + 'scroll', + this.throttledOnScrollListener as EventListenerOrEventListenerObject, + eventListenerOpts + ); } if ( @@ -95,13 +101,13 @@ export default class InfiniteScroll extends Component { } if (this.props.pullDownToRefresh && this.el) { - this.el.addEventListener('touchstart', this.onStart); - this.el.addEventListener('touchmove', this.onMove); - this.el.addEventListener('touchend', this.onEnd); + this.el.addEventListener('touchstart', this.onStart, eventListenerOpts); + this.el.addEventListener('touchmove', this.onMove, eventListenerOpts); + this.el.addEventListener('touchend', this.onEnd, eventListenerOpts); - this.el.addEventListener('mousedown', this.onStart); - this.el.addEventListener('mousemove', this.onMove); - this.el.addEventListener('mouseup', this.onEnd); + this.el.addEventListener('mousedown', this.onStart, eventListenerOpts); + this.el.addEventListener('mousemove', this.onMove, eventListenerOpts); + this.el.addEventListener('mouseup', this.onEnd, eventListenerOpts); // get BCR of pullDown element to position it above this.maxPullDownDistance = diff --git a/src/utils/passive-event-feature-detection.ts b/src/utils/passive-event-feature-detection.ts new file mode 100644 index 0000000..6e320b1 --- /dev/null +++ b/src/utils/passive-event-feature-detection.ts @@ -0,0 +1,26 @@ +/* eslint-disable no-empty */ + +let cachedResult: null | boolean = null; +const dummyEventName = 'testPassive' as keyof WindowEventMap; + +export function supportsPassive(): boolean { + if (cachedResult !== null) { + return cachedResult; + } + if (!window) { + return false; // to not fail if used with server-side rendering + } + try { + const opts = Object.defineProperty({}, 'passive', { + get: function() { + cachedResult = true; + }, + }); + window.addEventListener(dummyEventName, () => null, opts); + window.removeEventListener(dummyEventName, () => null, opts); + } catch (e) {} + if (cachedResult === null) { + cachedResult = false; + } + return cachedResult; +}