From 20f6e646acae0bdef620d87dcb5892bc97dd8d5d Mon Sep 17 00:00:00 2001 From: Cesar Varela Date: Fri, 10 Nov 2023 18:43:29 -0300 Subject: [PATCH] Improve discover performance (#2402) * Reduce test flake * Conditionally render controls based on window size * Debounce resize * Add virtual filters to prevent refinements from getting removed from state * Reduce flake --- .../src/components/discover/Controls.js | 2 +- .../src/components/discover/Discover.js | 29 ++++++- .../src/components/discover/OptionsModal.js | 85 ++++++++++++------- 3 files changed, 82 insertions(+), 34 deletions(-) diff --git a/site/gatsby-site/src/components/discover/Controls.js b/site/gatsby-site/src/components/discover/Controls.js index cf2473f413..b0d7b4b740 100644 --- a/site/gatsby-site/src/components/discover/Controls.js +++ b/site/gatsby-site/src/components/discover/Controls.js @@ -27,7 +27,7 @@ const Controls = () => { return ( <> -
+
diff --git a/site/gatsby-site/src/components/discover/Discover.js b/site/gatsby-site/src/components/discover/Discover.js index 41cb910f06..775c008c08 100644 --- a/site/gatsby-site/src/components/discover/Discover.js +++ b/site/gatsby-site/src/components/discover/Discover.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import Col from 'elements/Col'; import Row from 'elements/Row'; import Container from 'elements/Container'; @@ -16,6 +16,7 @@ import parseURL from './parseURL'; import { queryConfig } from './queryParams'; import { history } from 'instantsearch.js/es/lib/routers'; import Pagination from './Pagination'; +import debounce from 'lodash/debounce'; const searchClient = algoliasearch( config.header.search.algoliaAppId, @@ -34,6 +35,28 @@ export default function Discover() { const [indexName] = useState(`instant_search-${locale}-featured`); + const [width, setWidth] = useState(0); + + const handleWindowSizeChange = useRef( + debounce(() => { + setWidth(window.innerWidth); + }, 1000) + ).current; + + useEffect(() => { + window.addEventListener('resize', handleWindowSizeChange); + + handleWindowSizeChange(); + + return () => { + window.removeEventListener('resize', handleWindowSizeChange); + }; + }, []); + + if (width == 0) { + return null; + } + return ( - - - + {width > 767 ? : } diff --git a/site/gatsby-site/src/components/discover/OptionsModal.js b/site/gatsby-site/src/components/discover/OptionsModal.js index 7ce454b136..94e984f282 100644 --- a/site/gatsby-site/src/components/discover/OptionsModal.js +++ b/site/gatsby-site/src/components/discover/OptionsModal.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; import REFINEMENT_LISTS from 'components/discover/REFINEMENT_LISTS'; import { AccordionFilter } from './Filter'; import Stats from './Stats'; @@ -8,16 +8,42 @@ import DisplayModeSwitch from './DisplayModeSwitch'; import Button from 'elements/Button'; import DisplayOptions from './DisplayOptions'; import { Accordion, Modal } from 'flowbite-react'; +import { useRange, useRefinementList } from 'react-instantsearch'; + +const VirtualRefinementList = ({ attribute }) => { + useRefinementList({ attribute }); + + return null; +}; + +const VirtualRange = ({ attribute }) => { + useRange({ attribute }); + + return null; +}; + +const componentsMap = { + refinement: VirtualRefinementList, + range: VirtualRange, +}; + +function VirtualFilters() { + return ( + <> + {REFINEMENT_LISTS.map((list) => { + const Component = componentsMap[list.type]; + + return ; + })} + + ); +} function OptionsModal() { const [showModal, setShowModal] = useState(false); const handleClose = () => setShowModal(false); - const [mounted, setMounted] = useState(false); - - useEffect(() => setMounted(true), []); - return (
@@ -33,31 +59,32 @@ function OptionsModal() {
- {mounted && ( - - - Search Options - - -
-
- - -
- - {REFINEMENT_LISTS.map((list) => ( - - ))} - + + + + + + Search Options + + +
+
+ +
- - - - - - )} + + {REFINEMENT_LISTS.map((list) => ( + + ))} + +
+
+ + + +
); }