react-grid-system
react-grid-system copied to clipboard
SSR - Unstyled / Wrong styled with Audit ?
Issues
- Wrong render the first time when light house audit (always rendered the desktop version first).
Step to reproduce
- Go on https://staging-v3.hostnfly.com/ to audit with lighthouse
What did I try
- Using the ScreenClass coming from userAgent directly (using xs if mobile device, xl if desktop) and passing this to the config. not working. Even like that, it's not working.
It's impacting the score of the audit.
Any idea ?
Here is some code :
// _app.tsx
setConfiguration({
gridColumns: 12,
defaultScreenClass: serverSideScreenClass,
maxScreenClass: "xl",
gutterWidth: 20,
});
MyApp.getInitialProps = async (appContext: AppContext) => {
const pageProps = App.getInitialProps ? await App.getInitialProps(appContext) : {};
let userAgent: string;
if (process.browser) {
userAgent = navigator.userAgent;
} else {
userAgent = appContext.ctx.req.headers["user-agent"];
}
const md = new MobileDetect(userAgent);
let serverSideScreenClass: string;
if (md.phone() !== null) {
serverSideScreenClass = "xs";
} else if (md.tablet() !== null) {
serverSideScreenClass = "md";
} else {
serverSideScreenClass = "xl";
}
return {
...pageProps,
userAgent,
serverSideScreenClass,
namespacesRequired: ["common"],
};
};
Did you found a solution?
Nop, I found à Way to improve but not that much..
Ok, so I did a workaround.
With custom Next js server, I added with Mobile detect, the fallbackscreenclass in the headers, so I can initialize the grid with the fallback. But even with this hack, it's not working.
Perhaps to clarify this a little bit for anyone stumbling over this or contemplates using this library, because I see you use lighthouse and I'm currently tasked with optimizing a site for the core web vitals that uses this library as well...
When we write modern web applications we want them to be responsive (for mobile/tablet/desktop/toasters), the web has a solution for this for many years in CSS called media-queries:
@media (min-width: 577px) {
... tablet styling go here ...
}
When you use a modern framework like mui and use their Grid components you would write something like:
<Grid item xs={6}>
...
</Grid>
In the background this generates CSS with media queries using CSS-in-js (just pseudocode):
@media (max-width: 577px) {
.<generated-class-name> {
width: 50%;
}
}
This is what a library like react-grid-system should do.
Instead this library takes a fundamentally different approach, it uses JavaScript to determine the viewport width, then its Grid/Col components change the inline-style attribute depending on the screen size. Its emulating media-queries in javascript/react.
When we attempt to render the page on the server all the CSS will be generated for some screen size, the client renders the page (HTML and CSS first, before JavaScript) in whatever the screen size the library thought it was during the server side render. Once the javascript is loaded and executed and the real device screen size is determined, this library then has to change all the CSS again and the browser does a repaint of all the elements effected by the change. During all of which the user can't interact with the page.
You will never know the exact screen size / window size in advance of rendering the page on the server.
The Core Web Vitals (which now also effect Google ranking) take heavy emphasis on time to first paint metrics and first to interactive, this library - by design - makes optimizing those metrics impossible.
I found the issue on my side. I removed the setConfiguration which was too slow to initialize. I kept only what I wanted from the lib and the issue was gone. Keep it light :)