At a glance
- Write down what the first view must show on a phone, and treat everything else as deferrable.
- Put the likely LCP image in the HTML with fetchpriority="high"; give hidden carousel slides low priority.
- Size every tile, eager-load only the first visible row and lazy-load the rest.
- Render only the tiles in view, and load filter and search code when it is used.
Decide what the first view must show
Open the lobby on a mid-range phone and list what is visible before any scrolling: usually the header, a banner or promotional strip, category tabs and one or two rows of game tiles. That list is the critical path. Everything below it, plus every widget the player has not opened yet, can wait. Most lobby performance problems start when the page treats all 200 games, the chat, the jackpot ticker and the full filter panel as equally urgent.
Hero banners and carousels
If a banner is in the first view, it is a strong LCP candidate. web.dev's advice for the LCP image applies directly:
- Include it as an
<img>in the HTML so the browser finds it at once, not as a slide created by script. - Add
fetchpriority="high"to it, and to no more than one or two images in total. - Never lazy-load it.
For carousels, web.dev's fetch priority article suggests high priority for the first visible slide and low priority for the others, noting that lazy loading alone may not stop the browser from boosting offscreen slides. Carousels that rotate automatically also need a pause control: WCAG 2.2 success criterion 2.2.2 requires a way to pause, stop or hide moving content that starts automatically, lasts more than five seconds and is shown alongside other content.
The game grid
A grid of game tiles is many images competing for the same connection. Three rules keep it under control:
- Size every tile with width and height so the grid does not shift as images arrive.
- Load the first visible row eagerly and give the rest
loading="lazy", which web.dev recommends "only for images outside the initial viewport". - Serve tiles at the size shown, in a modern format. The thumbnail guide covers formats and srcset.
Rendering matters as much as downloading. A lobby that builds every tile in the DOM at once makes each filter change slower, because web.dev notes that rendering cost grows with DOM size. Render the tiles in view and append more as the player scrolls, or use content-visibility: auto on offscreen sections with a placeholder size.
Filters, search and categories
Category tabs and filters are often the first thing a player taps, so they decide early INP. Keep their handlers small, update the grid in chunks if it is large and give visual feedback in the next frame. Load the advanced filter panel and the search index when the player opens them, using dynamic import() as web.dev's code splitting guide describes. See JavaScript execution costs.
Personalized and logged-in lobbies
Recommendations, recently played games and balances make the lobby HTML harder to cache. A common pattern is to cache the shell and the default grid, then fill personal modules after the first paint into slots of fixed size. That keeps the time to first byte low and avoids layout shift when the personal content arrives. See caching and delivery.
A lobby checklist
| Check | Protects |
|---|---|
| LCP image in HTML, high priority, not lazy | LCP |
| Only one or two images at high priority | LCP |
| Width and height on every tile and banner | CLS |
| First row eager, other rows lazy | LCP, data use |
| Tiles rendered as they come into view | INP |
| Filter and search code loaded on use | INP |
| Personal modules in fixed-size slots | CLS, TTFB |
| Pause control on auto-rotating carousels | Accessibility |
Questions
How many rows should load eagerly?
The rows visible without scrolling on your most common mobile viewport. Check the template on real devices, because the answer changes with banner height.
Is infinite scroll bad for performance?
Not in itself. It needs sized placeholders so new rows do not shift content, and it should not keep every past row in the DOM.
Should the lobby wait for the player's balance?
No. Render the lobby and fill the balance into a fixed slot when it arrives.
Sources
- web.dev, Optimize Largest Contentful Paint, last updated March 31, 2025.
- web.dev, Optimize resource loading with the Fetch Priority API, last updated November 14, 2023.
- web.dev, Browser-level image lazy loading for the web, last updated August 13, 2024.
- web.dev, Optimize Interaction to Next Paint, last updated September 2, 2025.
- web.dev, Code-split JavaScript, last updated December 4, 2023.
- W3C, Web Content Accessibility Guidelines (WCAG) 2.2, W3C Recommendation, October 5, 2023.