Skip to content
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

Big flash of unstyled content (FOUC) during HMR #7973

Closed
7 tasks done
jods4 opened this issue Apr 30, 2022 · 5 comments
Closed
7 tasks done

Big flash of unstyled content (FOUC) during HMR #7973

jods4 opened this issue Apr 30, 2022 · 5 comments
Labels
feat: hmr p2-nice-to-have Not breaking anything but nice to have (priority)

Comments

@jods4
Copy link
Contributor

jods4 commented Apr 30, 2022

Describe the bug

Problem

When my styles change, the page flashes without any styling for a second or so, it's verry jarring I thought it was actually reloading.

Cause

After some debugging I found out the cause:

When a css stylesheet is loaded through <link> (i.e. in the main HTML page), the HMR logic is simply to update its href but that can cause issues, here's what happens in my project:

  • Multiple css are HMR at the same time, some are imported by JS, the main one is <link> in index.html.
  • At HMR time, Vite fetches the imported ones, to later replace <style> nodes.
  • At the same time it fetches the updated style sources, Vite simply updates the href of <link>. This triggers a network request by the browser and on my project, it takes ~700ms to complete.
  • Before that completes, Vite receives some responses and starts updating <style> tags. This triggers a CSS repaint by the browser.
  • Because the <link href> was changed but has not completed fetch yet, the browser just ignores it. Old CSS rules are not applied anymore.
  • And this is why there is a lot of unstyled content on my page...
  • Until the <link> fetch completes, and browser repaints again with all CSS rules back in place.

Fix ideas

To avoid FOUC, one should not change href or remove <link> tags before the new styles are loaded.
Maybe Vite could add a new <link> tag with the new href just after the old one, and remove the old one when the new one finishes loading.

Reproduction

Sorry, no repro on this one. The setup is just to have link and imported style and trigger a reload of all, which is automatic if you use tailwind ;)
To make the effect clearly visible, you need to have larger styles in <link> (so it takes longer to reload than the styles), or use something to breakpoint the network request, e.g. Fiddler. Just let the style request go through and block (for a while) the <link> request.

You'll see that once the <style> request completes, the page repaints without styles, and it's fixed when the <link> request completes.

System Info

Vite 2.9.2

Used Package Manager

npm

Logs

No response

Validations

@timacdonald
Copy link
Contributor

Got a PR up for this, as we ran into the same issue: #8495

@sapphi-red sapphi-red added p2-nice-to-have Not breaking anything but nice to have (priority) and removed pending triage labels Jun 8, 2022
@sapphi-red
Copy link
Member

It seems this does not happen (or rarely happens) on chrome. But it happens on firefox.

@jods4
Copy link
Contributor Author

jods4 commented Jun 8, 2022

@sapphi-red For what it's worth, I'm having this issue in Edge Chromium.

@sapphi-red
Copy link
Member

@jods4 I confirmed #8495 fixes for me on firefox. Would you check if it fixes for you, too?

@jods4
Copy link
Contributor Author

jods4 commented Jun 8, 2022

@sapphi-red I'll try when it's merged into a published release, I don't have the time to make my own builds right now.

@github-actions github-actions bot locked and limited conversation to collaborators Jun 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feat: hmr p2-nice-to-have Not breaking anything but nice to have (priority)
Projects
None yet
Development

No branches or pull requests

3 participants