primereact
primereact copied to clipboard
Flash of unstyled content (FOUC)
Describe the bug
When using built in PR theme seeing a flash of un-styled content: https://en.wikipedia.org/wiki/Flash_of_unstyled_content
I have this super simple code
import React, {useState} from 'react';
import {TabMenu} from 'primereact/tabmenu';
import {MenuItem} from 'primereact/menuitem';
type NavbarProps = {
onPageSelected?: (page: string) => void,
menuItems?: MenuItem[],
}
export const Navbar = ({menuItems, onPageSelected}: NavbarProps) => {
const [activeIndex, setActiveIndex] = useState(0)
return (
<TabMenu
activeIndex={activeIndex}
model={
menuItems
}
onTabChange={(e) => {
setActiveIndex(e.index);
onPageSelected?.(e.value.id as string)
}}
/>
)
}
When the page first loads, it looks like this first for like 0.5 seconds
and then it changes to how it should really look
After some debugging I found out it is because when the component is loaded, it loads this global style
https://github.com/primefaces/primereact/blob/master/components/lib/tabmenu/TabMenuBase.js#L79 https://github.com/primefaces/primereact/blob/master/components/lib/componentbase/ComponentBase.js#L664
I recorded this video with the issue on the codesandbox i created
https://github.com/primefaces/primereact/assets/2165906/01eb40c2-e062-40ee-8934-3355b858f502
I would expect either
- The component should be auto-sufficient (i.e it looks properly on first load)
- To have a way to import the components css globally directly, next to the theme and min imports (something like
import "primereact/components/tabmenu.css
Reproducer
https://codesandbox.io/s/primereact-test-forked-xsr6gj?file=/src/index.js
PrimeReact version
10.0.7
React version
18.x
Language
TypeScript
Build / Runtime
Create React App (CRA)
Browser(s)
No response
Steps to reproduce the behavior
No response
Expected behavior
No response
I agree I have seen this same flash flicker when it renders.
This is known as FOUC https://en.wikipedia.org/wiki/Flash_of_unstyled_content and maybe all those base styles need to be extracted into a primereact.css like you said so if we want we can include it in the page and not need each component to dynamically add the CSS to the HEAD
@gslopez check this out can you try this: https://codesandbox.io/s/primereact-test-forked-9cl6y8?file=/src/styles.css
I merged all of the base styles into a single CSS file to load. If this meets your needs I think I can propose something clever.
Updated with more complete version of the final CSS: https://codesandbox.io/s/primereact-test-forked-9cl6y8?file=/src/styles.css
hey @melloware! Thanks for the quick answer. Yeah, if I add import "./styles.css";
to that codesandbox it seems to be working fine. I think this is good enough for my current project 🙏
@melloware any date prediction of 10.0.10 release? Facing the same issue here
This fix has not been included in 10.0.10 yet as PrimeTek is still discussing my fix. For now you can use the CSS in the reproducer above to temporarily fix your issue.
NextJS 14 reproducer: https://stackblitz.com/edit/stackblitz-starters-mqapwn?file=app%2Fglobals.css,app%2Flayout.tsx
Facing the same issue while migrating to a major version 8 → 10 on my project. Any news here? It's look like a blocker for me
You can use my workaround posted above
You can use my workaround posted above
@melloware do you mean this?
Updated with more complete version of the final CSS: https://codesandbox.io/s/primereact-test-forked-9cl6y8?file=/src/styles.css
This codesandbox still shows a FOUC on first load. It's a little less noticeable but it still occurs. A little difficult to show with Chrome Inspector (it limits how big the Visual Preview window can be) but the following shows the list elements along with the final rendered content 1ms later:
Yes it doesn't eliminate it it just makes it less jarring by preloading CSS.
Is it possible to somehow escalate this issue? Add more likes or idk :) Looks important.
@axlerk PrimeTek is aware of this issue its on their radar.
any news?
any news?
+1
+another
+++
++++
@melloware could you update the workaround for version 10.6.6 please? Until we have a solution
@axlerk i assume you means some styles are missing from my giant CSS file?
Now I get what @melloware is saying now, PrimeReact adds the styles 'after' the component have already been rendered. See the left side of the screenshot and you'll notice that 'base', 'global', 'splitbutton', are being added dynamically. On the right side of the screen, you don't and that's why it's showing FOUC.
I think I can come with decent 'workaround' solution without putting those css somewhere. My idea is the following. Please let me know if my logic can be improved or flawed.
- Make the body tag to be display:none in the Root Layout component. Something like
<body style={{display: "none"}}>
- Add a script tag, that checks for added styles with the attribute 'data-primereact-style-id'. Check that at least 3 of them exists (Imagine those are 'base', 'global', 'common') and maybe add another 50ms and then change the body style back to 'block'/'flex'/or whatever...
Hopefully this will work as temporary workaround...
@acho1833 yes you understand the issue now. PrimeTek I think is working on a long term solution after their next big refactor.
My theory seems to work and I think it's good to go now. To me, this is enough until the fix and looks perfect to me.
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<head>
<style
dangerouslySetInnerHTML={{
__html: `
body {
display: none;
}
`,
}}
/>
<script
dangerouslySetInnerHTML={{
__html: `
document.addEventListener('DOMContentLoaded', function() {
const intervalId = setInterval(() => {
const elements = document.querySelectorAll('head > style[data-primereact-style-id]');
if (elements.length >= 3) {
document.body.style.display = 'block';
clearInterval(intervalId);
}
}, 50);
});
`,
}}
/>
</head>
<body className={inter.className}>
<PrimeReactProvider>{children}</PrimeReactProvider>
</body>
</html>
);
}
@melloware looking forward for next release. Is that real soon? know any rough ETA?
I don't work for PrimeTek so I don't know the internal details of their schedule or roadmap.