-
-
Notifications
You must be signed in to change notification settings - Fork 484
Render an empty div for game cards until they inter the viewport #2460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
} | ||
|
||
.gameCard.gamepad { | ||
aspect-ratio: 3/4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are the current ratios, but I'm hardcoding them so the empty divs use the correct space
@@ -63,6 +63,24 @@ const GameCard = ({ | |||
isRecent = false, | |||
gameInfo: gameInfoFromProps | |||
}: Card) => { | |||
const [visible, setVisible] = useState(false) | |||
|
|||
useEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
start as invisible, make visible when the visible-cards
event is fired and this card is in the list of visible cards
@@ -344,7 +372,7 @@ const GameCard = ({ | |||
/> | |||
)} | |||
<ContextMenu items={items}> | |||
<div className={wrapperClasses}> | |||
<div className={wrapperClasses} data-app-name={appName}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using this data attribute for the intersection observer
const { t } = useTranslation() | ||
const [gameCards, setGameCards] = useState<JSX.Element[]>([]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this useState and the useEffect changing it was causing extra re-renders
I moved this back to the return jsx instead of using a useState+useEffect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm
This is an alternative to #2447
Instead of pagination, it renders all the library elements but for the ones that are outside of the viewport it renders an empty div until the element has to be displayed. Then it uses the IntersectionObserver to actually render the real content.
I'll add some comments in the PR.
There are still improvements that can be made (because of how react works, all hooks has to be defined before rendering the empty div, so there's extra unnecessary work there, also cards are re-rendered multiple times) but I'll leave those things for another PR.
You can see the empty divs using devtools and how they are updated when scrolling:

Use the following Checklist if you have changed something on the Backend or Frontend: