From 451a9125f9195afa2e53be3a4cfd1561ed77eb6e Mon Sep 17 00:00:00 2001 From: Afshin Mehrabani Date: Sat, 30 Dec 2023 15:11:41 +0000 Subject: [PATCH] Throttle the container.tsx pipeline processing function --- src/config.ts | 3 +++ src/util/throttle.ts | 13 +++++++++++-- src/view/container.tsx | 35 ++++++++++++++++++----------------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/config.ts b/src/config.ts index 71e07a43..b3b20352 100644 --- a/src/config.ts +++ b/src/config.ts @@ -36,6 +36,8 @@ export interface Config { /** to parse a HTML table and load the data */ from: HTMLElement; storage: Storage; + /** Pipeline process throttle timeout in milliseconds */ + processingThrottleMs: number; pipeline: Pipeline; /** to automatically calculate the columns width */ autoWidth: boolean; @@ -128,6 +130,7 @@ export class Config { tableRef: createRef(), width: '100%', height: 'auto', + processingThrottleMs: 50, autoWidth: true, style: {}, className: {}, diff --git a/src/util/throttle.ts b/src/util/throttle.ts index 7a677609..c11da443 100644 --- a/src/util/throttle.ts +++ b/src/util/throttle.ts @@ -1,11 +1,20 @@ -export const throttle = (fn: (...args) => void, wait = 100) => { +/** + * Throttle a given function + * @param fn Function to be called + * @param wait Throttle timeout in milliseconds + * @param leading whether or not to call "fn" immediately + * @returns Throttled function + */ +export const throttle = (fn: (...args) => void, wait = 100, leading = true) => { let inThrottle: boolean; let lastFn: ReturnType; let lastTime: number; return (...args) => { if (!inThrottle) { - fn(...args); + if (leading) { + fn(...args); + } lastTime = Date.now(); inThrottle = true; } else { diff --git a/src/view/container.tsx b/src/view/container.tsx index 92b6dd58..35c8bde2 100644 --- a/src/view/container.tsx +++ b/src/view/container.tsx @@ -10,6 +10,7 @@ import * as actions from './actions'; import { useStore } from '../hooks/useStore'; import useSelector from '../../src/hooks/useSelector'; import { useConfig } from '../../src/hooks/useConfig'; +import { throttle } from 'src/util/throttle'; export function Container() { const config = useConfig(); @@ -19,6 +20,23 @@ export function Container() { const tableRef = useSelector((state) => state.tableRef); const tempRef = createRef(); + const processPipeline = throttle(async () => { + dispatch(actions.SetLoadingData()); + + try { + const data = await config.pipeline.process(); + dispatch(actions.SetData(data)); + + // TODO: do we need this setTimemout? + setTimeout(() => { + dispatch(actions.SetStatusToRendered()); + }, 0); + } catch (e) { + log.error(e); + dispatch(actions.SetDataErrored()); + } + }, config.processingThrottleMs, false); + useEffect(() => { // set the initial header object // we update the header width later when "data" @@ -41,23 +59,6 @@ export function Container() { } }, [data, config, tempRef]); - const processPipeline = async () => { - dispatch(actions.SetLoadingData()); - - try { - const data = await config.pipeline.process(); - dispatch(actions.SetData(data)); - - // TODO: do we need this setTimemout? - setTimeout(() => { - dispatch(actions.SetStatusToRendered()); - }, 0); - } catch (e) { - log.error(e); - dispatch(actions.SetDataErrored()); - } - }; - return (