-
-
Notifications
You must be signed in to change notification settings - Fork 974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(Almost) unavoidable FOUC and my "fix" - Blogpost style issue #3592
Comments
Self triage:
|
To further expand on this: I think that the I'm guessing this issue is Firefox specific. |
You can use a regular css file to apply the background style to the main div:
Static site generation (SSG) is a much more robust solution to this problem. It generates all static content on pages at build time to speed up initial load times. With SSG you can link to stylesheets with the normal |
Thanks for your thoughts on this and apologies for the late reply.
That sounds like a better alternative. I just upgraded to dioxus-cli 0.6.2 (from 0.6.1) and realised that this won't work for much longer. The
I 100% agree. After taking a look at your example, I started setting it up for myself. As it seems SSG requires the fullstack feature. I think this shouldn't be the case. I am developing front and backend independently from each other and thus use Dioxus web, desktop and hopefully some day mobile. Now whenever I run
Best, Edit: For anyone else migrating from just a client to Edit 2: There seems to be some kind of issue related to this that I am discussing over on Discord |
SSG enables fullstack which builds the html initially on the server and then hydrates it on the client. To do that, you need to set up a temporary pre-render server for the build. That is why the fullstack feature is required and a server is required at build time. You don't need to deploy the server the CLI builds. DioxusLabs/docsite#394 adds more docs about the server setup required for ssg Because ssg prerenders the html on the server, all components need to be runnable on the server. They can't use web specific libraries like web-sys outside of effects. The server and client also need to produce exactly the same html or it will cause hydration issues. DioxusLabs/docsite#397 adds more docs about hydration
That is what the original implementation of ssg did. The new version of ssg that lives in the CLI could do something similar as the default |
Hi,
I have been fighting with a FOUC (Flash Of Unstyled Content) for the past few hours and finally found a solution that somewhat works for me but has to be reapplied each time I recompile.
In this issue I am both looking for a better and more permanent fix as well as to help out anyone else experiencing this issue. This may be a long read since I intend on explaining the issue, the fix and how I got there. You can find the TL;DR at the end.
L;R
It all began with my 404 page. It's a simple page. A black background with white text. I am using TailwindCSS here, in this case with a different behavior for dark and light mode. Ofc. this issue will only be noticable when loading in dark mode.
This component is the catchall in my router and will always be displayed on its own without any styling around it.
Now when loading an unknown route and getting to this page, (on Firefox) the following happens:
My first thought was that this issue was caused by the stylesheet being loaded too late. After wasting a lot of time trying to get it to load any earlier than it already is, I noticed that this was not the cause. In fact, the cause was something else entirely:
The page was ready to be rendered and the styles were injected only after that. How so? Well,
dx
will generate anindex.html
for you that loads the resources you specified in thedioxus.toml
, specifies a<div id="main"></div>
and a<script>
that loads and initializes the WASM SPA.Now this is where the issue arrises. In Firefox that script doesn't seem to be blocking. As an effect, you have a page that is ready to render with no content and firefox will display just that. An empty, white page. Rather bright after you had just been looking at the pitch black dark mode page.
At this time the HTML will look more or less like this:
If you would like to take an extended look at the page as it would be rendered, you can just remove the script so the WASM is never launched.
Next, the script finishes and Dioxus will fill the
<div id="main"></div>
with the contents of your SPA. This is when the styles you applied inside your Rust code become part of the HTML. This may look like this:As you can see, your styles are only applied AFTER the Dioxus app has finished loading and initializing. Now what can we do about it? For starters, we can apply a style to our unstyled
<div id="main"></div>
.In my case, using TailwindCSS, that would be the following classes:
class="w-screen h-screen bg-white dark:bg-black"
The only thing they are doing is to ensure the entire screen is either black or white depending on your settings for light or dark mode.
Now your
index.html
should look like this:But this is where the next issue arrises: Now your entire page is going to have a black or white background unless you override this behavior in your components. We don't want that. These styles are only here to prevent flashing the user until the WASM has loaded. We need to get rid of them at the right moment in time.
Our savior:
document::eval()
Using JavaScript, we can remove the classes we applied earlier from the
div
at runtime.Place the above snippet in your main dioxus component. It is usually called
App
. The snippet will remove the classes we applied from the<div id="main"></div>
as soon as the SPA is loaded. No more inheriting classes we don't want or need anymore. The same could probably also be done withstyle
directly so we don't even depend on loading the css file first.Take a look at the TL;DR (next) section for a more complete code snippet.
TL;DR
Edit the
index.html
by adding your TailwindCSS classes to the<div id="main"></div>
and add adocument::eval
with the following contents to your main dioxus component, usually calledApp
This may look like so:
The remaining issue:
index.html
every time you recompile by hand.As for the second issue, there are only two ways I can think of to defeat it. One is to use the SSR feature, the other to ensure that loading the SPA is blocking.
Conclusion
We defeated the FOUC. But at what cost?
Now we have to edit our
index.html
each time we recompile. To my knowledge, there is no way to specify the classes/styles that are to be applied by default in ourdioxus.toml
. This is where I think an enhancement can be made by either finding a way to make the loading a blocking operation so the browser, specifically Firefox, doesn't render the unstyled, empty page immediately but instead waits for the SPA to show up or by providing a way to apply the default classes/styles for<div id="main"></div>
in thedioxus.toml
.Generated - and especially frequently re-generated - files should never need to be edited by hand.
Best,
Gab
The text was updated successfully, but these errors were encountered: