We have the following Situation on our home page (Angular, with Server Side Rendering):
Right below the Header, we have a full width & full height (100vh) video Element (Autoplay, muted). The video has two sources:
- Landscape Ratio Source: Is used for desktop devices
- Portrait Ratio Source: Is used for mobile devices
The video Element is treated as Largest Contentful Paint Element by Google Lighthouse. Our implementation so far was, to use Javascript logic to determine the appropriate video source. This works correctly on the client, but in Server Side Rendering (where no screen context is available), it is always choosing the Landscape based video.
This leads to a bad LCP Value on Lighthouse, since for mobile devices, they get the Markup generated in server Side Rendering (with the Video for Desktop) and then need to through that away and load the video for Mobile.
We see the following options:
- Exclude the Video from Server Side Rendering
- Render both video's as source tags with data-src and decide on the client, which one to use
- Use a normal responsive image and swap it when the image is loaded
- Use the Poster Attribute to show an Image until the video is loaded (This is not ideal rendition wise as the poster image can just have one size)
Solutions 1-3 include the usage of JS to determine the correct video, which again gives a worse LCP Score.
Solution 4 is CSS only, but the poster image resolution cannot fit the different device screens. And the Problem with the multiple Video Sources remains..
Since the video tag does not support media queries, a css only solution does not seem possible..
Any idea how we could load the correct video source in server side rendering without the usage of JS to improve the LCP Value?
<video>
doesn't support media queries, but<source>
does (despite being otherwise annoyingly limited inside<video>
), which should allow you to do what you want:Something like:
Or it might make sense to be less literal with the landscape/portrait and use whatever width breakpoint(s) you use for styling in the media query instead.