-
Notifications
You must be signed in to change notification settings - Fork 4
Store image aspect ratio on puzzles for CLS optimization #84
Copy link
Copy link
Open
Description
Problem
Currently, puzzle thumbnail images use a square aspect ratio assumption (width=80 height=80) for the HTML width/height attributes. These attributes tell the browser how much space to reserve before the image loads, preventing Cumulative Layout Shift (CLS).
Since most puzzle images are not square (e.g. 135×200 portrait), the assumed dimensions don't match reality. This means either:
- The browser reserves wrong space and layout shifts when the image loads
- We rely on inline
max-heightCSS to constrain overflow, which works visually but doesn't give the browser the correct aspect ratio hint
Solution
Store the image aspect ratio (width / height) as a single float column on the puzzle entity (e.g. imageRatio).
Why ratio instead of width+height
A single float is sufficient. Given the ratio and a target max display size, we can calculate exact width and height at render time:
if ratio > 1 (landscape): width = size, height = size / ratio
if ratio < 1 (portrait): height = maxHeight, width = maxHeight * ratio
if ratio = 1 (square): width = height = size
Example: Dino Frozen image (135×200, ratio=0.675) at size=80 → width="54" height="80"
Implementation steps
- Add
imageRatio(nullable float) column to the Puzzle entity - On image upload, calculate and store
width / heightfrom the uploaded image dimensions - Write a migration to backfill existing puzzles (read dimensions from stored S3 images or thumbnails)
- Update
LazyImageTwigExtension::lazyPuzzleImage()to accept the ratio and calculate accuratewidth/heightattributes - Pass the ratio from templates/components that render puzzle images
Impact
- Eliminates CLS for puzzle image loading across all pages
- Removes the need for the inline
style="max-height:Xpx"workaround - Better Lighthouse/PageSpeed scores
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels