guardian / guardian/dotcom-rendering
Investigate Island Placeholders
- Dominant language
- TypeScript
- Stars
- 274
- Forks
- 34
- Avg merge
- 2d 22h
- Merged PRs (30d)
- 121
Description
When we load content on the client, we often use a loading container to indicate to the user that content is loading. When the content is loaded, we replace the loading container with the content.
For example, the Most Viewed component (at the bottom of article pages):
| | Loading | Content |
| - | - | - |
| mobile | ![mobile-loading] | ![mobile-content] |
| desktop | ![desktop-loading] | ![desktop-content] |
[mobile-loading]: https://github.com/user-attachments/assets/154b0ad9-65de-48d8-a7eb-01e9248eeae1
[desktop-loading]: https://github.com/user-attachments/assets/701090d0-f702-4474-97bf-0a230b453c0f
[mobile-content]: https://github.com/user-attachments/assets/a20362d7-51b7-45ec-9403-6d6088947543
[desktop-content]: https://github.com/user-attachments/assets/0338afc3-7622-4b4c-b8eb-2d072dacef29
Problems:
- CLS. Notice how the height of the container when content is loading is _much_ smaller that the height of the container when the content is displayed. This will negatively impact our CLS scores. The height of the placeholder is currently the same for both mobile and desktop in many cases.
- UX. A large loading container does not indicate to the user anything about the content that is loading. This could lead the user to thinking the page is "broken" when on weaker network connections. This is especially true on mobile, where the loading container can take up almost all off the screen.
Solution:
- We should create skeleton containers for content. This will allow us to more accurately predict the height of the content, to differentiate between the mobile and desktop experiences, and to provide the user with visual clues to what kind of content is loading.
Occurrences in codebase:
- [MostViewedFooterData](https://github.com/guardian/dotcom-rendering/blob/79acedaf5b2a4df6972981cca6770897c7ff3d3d/dotcom-rendering/src/components/MostViewedFooterData.importable.tsx#L97)
- [DiscussionWeb](https://github.com/guardian/dotcom-rendering/blob/71fec6484151959e95724ca4baaeb5baf9fd6ba3/dotcom-rendering/src/components/DiscussionWeb.importable.tsx#L107)
- [FetchOnwardsData](https://github.com/guardian/dotcom-rendering/blob/79acedaf5b2a4df6972981cca6770897c7ff3d3d/dotcom-rendering/src/components/FetchOnwardsData.importable.tsx#L57)
- [GetCricketScoreboard](https://github.com/guardian/dotcom-rendering/blob/79acedaf5b2a4df6972981cca6770897c7ff3d3d/dotcom-rendering/src/components/GetCricketScoreboard.importable.tsx#L13)
- [GetMatchStats](https://github.com/guardian/dotcom-rendering/blob/79acedaf5b2a4df6972981cca6770897c7ff3d3d/dotcom-rendering/src/components/GetMatchStats.importable.tsx#L14)
- [InteractiveBlockComponent](https://github.com/guardian/dotcom-rendering/blob/79acedaf5b2a4df6972981cca6770897c7ff3d3d/dotcom-rendering/src/components/InteractiveBlockComponent.importable.tsx#L411)
Contributor guide
Assessment
This issue has not been assessed yet.