From 8f6145e383a2c35091fbc65f980ae434e48a4f43 Mon Sep 17 00:00:00 2001 From: Nolan Lawson Date: Sun, 10 Mar 2019 09:40:59 -0700 Subject: [PATCH] perf: throttle keyboard input to improve responsiveness --- src/components/search.js | 5 ++++- src/utils/index.js | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/components/search.js b/src/components/search.js index 19992dd..fc6c5e5 100644 --- a/src/components/search.js +++ b/src/components/search.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import { search as icons } from '../svgs' import NimbleEmojiIndex from '../utils/emoji-index/nimble-emoji-index' +import { throttleIdleTask } from '../utils/index' export default class Search extends React.PureComponent { constructor(props) { @@ -15,9 +16,11 @@ export default class Search extends React.PureComponent { this.data = props.data this.emojiIndex = new NimbleEmojiIndex(this.data) this.setRef = this.setRef.bind(this) - this.handleChange = this.handleChange.bind(this) this.clear = this.clear.bind(this) this.handleKeyUp = this.handleKeyUp.bind(this) + + // throttle keyboard input so that typing isn't delayed + this.handleChange = throttleIdleTask(this.handleChange.bind(this)) } search(value) { diff --git a/src/utils/index.js b/src/utils/index.js index 241b18b..8276184 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -189,6 +189,24 @@ function measureScrollbar() { return scrollbarWidth } +// Use requestIdleCallback() if available, else fall back to setTimeout(). +// Throttle so as not to run too frequently. +function throttleIdleTask(func) { + const queue = + typeof requestIdleCallback === 'function' ? requestIdleCallback : setTimeout + const clear = + typeof cancelIdleCallback === 'function' ? cancelIdleCallback : clearTimeout + + let id + + return function throttled() { + if (id) { + clear(id) + } + id = queue(func) + } +} + export { getData, getSanitizedData, @@ -197,4 +215,5 @@ export { deepMerge, unifiedToNative, measureScrollbar, + throttleIdleTask, }