This gist shows how you take advantage of Streaming SSR in React 18 & Next.js to reduce bundle size & not impact CLS.
- The
hls.js
lib is too big. (Adding at best 254kb gzip and at worst +300kb gzip to your bundle size). - Streaming SSR is more performant than Next.js' native dynamic object.
- Reduce bundle size without impacting CLS.
- Create an hls video player component.
- Expose and bind react refs.
- Instantiate hls.js inside this component.
- Parent component imports using
next/dynamic
withsuspense:true
- Render fallback as video poster url.
- Native browser preload poster based on media query.
- Enforce aspect ratio using CSS to avoid CLS shift.
- Resources load (styles, js & PRELOADED images).
- During resource load (before app.js mount), HLSPlayer.tsx async loading is dispatched.
- Body renders (with preloaded images if ready). === Video poster is available on browser paint.
- App hydrates (if network is fast, HLS is ready otherwise poster will still show)
- Ref callbacks dispatched
- Why not lazy import
hls.js
inside useEffect?- Loading will be dispatched after hydration of app.js ~ 120ms
- Time saved for Safari is not worth it. (Use hydration + canPlayType setState call render safari only video comp without HLS.js to improve safari load times). Can default to this for even greater perf.