From af2d28e805a425deb4dde2e2893dab2b8c4c7137 Mon Sep 17 00:00:00 2001 From: Philippe Maes Date: Tue, 22 Sep 2020 16:14:51 +0200 Subject: [PATCH] Fix orderbook speed issues --- src/components/Orderbook.jsx | 49 ++++++++++++++++-------------------- src/components/TradeForm.jsx | 4 +-- src/pages/TradePage.jsx | 12 ++++++--- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/components/Orderbook.jsx b/src/components/Orderbook.jsx index 6b8b9eb..952ace6 100644 --- a/src/components/Orderbook.jsx +++ b/src/components/Orderbook.jsx @@ -52,9 +52,7 @@ export default function Orderbook({ smallScreen, depth = 7, onPrice, onSize }) { const currentOrderbookData = useRef(null); const lastOrderbookData = useRef(null); - const [asksToDisplay, setAsksToDisplay] = useState([]); - const [bidsToDisplay, setBidsToDisplay] = useState([]); - const [totalSize, setTotalSize] = useState(0); + const [orderbookData, setOrderbookData] = useState(null); useInterval(() => { if ( @@ -65,24 +63,19 @@ export default function Orderbook({ smallScreen, depth = 7, onPrice, onSize }) { let bids = orderbook?.bids || []; let asks = orderbook?.asks || []; - let [asksToDisplay, totalAskSize] = getCumulativeOrderbookSide( - asks, - true, - ); - let [bidsToDisplay, totalBidSize] = getCumulativeOrderbookSide( - bids, - false, - ); - let totalSize = totalAskSize + totalBidSize; + let sum = (total, [, size], index) => + index < depth ? total + size : total; + let totalSize = bids.reduce(sum, 0) + asks.reduce(sum, 0); - setAsksToDisplay(asksToDisplay); - setBidsToDisplay(bidsToDisplay); - setTotalSize(totalSize); + let bidsToDisplay = getCumulativeOrderbookSide(bids, totalSize, false); + let asksToDisplay = getCumulativeOrderbookSide(asks, totalSize, true); currentOrderbookData.current = { bids: orderbook?.bids, asks: orderbook?.asks, }; + + setOrderbookData({ bids: bidsToDisplay, asks: asksToDisplay }); } }, 250); @@ -93,23 +86,23 @@ export default function Orderbook({ smallScreen, depth = 7, onPrice, onSize }) { }; }, [orderbook]); - function getCumulativeOrderbookSide(orders, backwards = false) { + function getCumulativeOrderbookSide(orders, totalSize, backwards = false) { let cumulative = orders .slice(0, depth) .reduce((cumulative, [price, size], i) => { + const cumulativeSize = (cumulative[i - 1]?.cumulativeSize || 0) + size; cumulative.push({ price, size, - cumulativeSize: (cumulative[i - 1]?.cumulativeSize || 0) + size, + cumulativeSize, + sizePercent: Math.round((cumulativeSize / (totalSize || 1)) * 100), }); return cumulative; }, []); if (backwards) { cumulative = cumulative.reverse(); } - let totalSize = - cumulative[backwards ? 0 : cumulative.length - 1]?.cumulativeSize || 0; - return [cumulative, totalSize]; + return cumulative; } return ( @@ -127,27 +120,27 @@ export default function Orderbook({ smallScreen, depth = 7, onPrice, onSize }) { Price ({quoteCurrency}) - {asksToDisplay.map(({ price, size, cumulativeSize }) => ( + {orderbookData?.asks.map(({ price, size, sizePercent }) => ( onSize(size)} + sizePercent={sizePercent} onPriceClick={() => onPrice(price)} + onSizeClick={() => onSize(size)} /> ))} - {bidsToDisplay.map(({ price, size, cumulativeSize }) => ( + {orderbookData?.bids.map(({ price, size, sizePercent }) => ( onSize(size)} + sizePercent={sizePercent} onPriceClick={() => onPrice(price)} + onSizeClick={() => onSize(size)} /> ))} @@ -168,7 +161,7 @@ const OrderbookRow = React.memo( () => element.current?.classList.contains('flash') && element.current?.classList.remove('flash'), - 500, + 250, ); }, [price, size]); @@ -202,7 +195,7 @@ const OrderbookRow = React.memo( ); }, (prevProps, nextProps) => - isEqual(prevProps, nextProps, ['side', 'price', 'size', 'sizePercent']), + isEqual(prevProps, nextProps, ['price', 'size', 'sizePercent']), ); const MarkPriceComponent = React.memo( diff --git a/src/components/TradeForm.jsx b/src/components/TradeForm.jsx index a2a24d3..cf0fe77 100644 --- a/src/components/TradeForm.jsx +++ b/src/components/TradeForm.jsx @@ -77,7 +77,7 @@ export default function TradeForm({ style, setChangeOrderRef }) { }, [setChangeOrderRef]); useEffect(() => { - onSliderChange(sizeFraction); + baseSize && price && onSliderChange(sizeFraction); // eslint-disable-next-line react-hooks/exhaustive-deps }, [side]); @@ -221,7 +221,7 @@ export default function TradeForm({ style, setChangeOrderRef }) { style={{ textAlign: 'right', paddingBottom: 8 }} addonBefore={
Price
} suffix={ - {baseCurrency} + {quoteCurrency} } value={price} type="number" diff --git a/src/pages/TradePage.jsx b/src/pages/TradePage.jsx index 585a072..8dd86ef 100644 --- a/src/pages/TradePage.jsx +++ b/src/pages/TradePage.jsx @@ -58,10 +58,14 @@ export default function TradePage() { const width = dimensions?.width; const componentProps = { onChangeOrderRef: (ref) => (changeOrderRef.current = ref), - onPrice: (price) => - changeOrderRef.current && changeOrderRef.current({ price }), - onSize: (size) => - changeOrderRef.current && changeOrderRef.current({ size }), + onPrice: useCallback( + (price) => changeOrderRef.current && changeOrderRef.current({ price }), + [], + ), + onSize: useCallback( + (size) => changeOrderRef.current && changeOrderRef.current({ size }), + [], + ), }; const getComponent = useCallback(() => { if (handleDeprecated) {