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

Flicker of Unstyled Content #5667

Closed
mbuttler opened this issue Jun 1, 2018 · 48 comments
Closed

Flicker of Unstyled Content #5667

mbuttler opened this issue Jun 1, 2018 · 48 comments
Labels
stale? Issue that may be closed soon due to the original author not responding any more. type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@mbuttler
Copy link

mbuttler commented Jun 1, 2018

Summary

I have a gnarly flash of unstyled content when I load my page from a gatsby build. I can replicate it in both brower-sync locally and with my AWS bucket that I use to host it on my company intranet.

Relevant information

I am using Material UI V1 components. I tried this plugin that was suggested in this thread but like... It doesn't solve my problem.

Gatsby Develop doesn't show the problem because of the way it builds, I guess.

I had a look at my dev tools network tab and saw that component-src-layouts is loading slightly slower than my component-src-page, so the page content is loading before the layout or something?

So I'm thinking that if I block component-src-layouts, I never get my CSS and it remains 'unstyled'... is there a way to load this component first? That might be the trick here.

Environment (if relevant)

  • Gatsby version 1.9.238
  • gatsby-cli version 1.1.45
  • Node.js version: 8.11.1
  • Operating System: MacOS High Sierra

File contents (if changed)

gatsby-config.js:

module.exports = {
    siteMetadata: {
        title: 'My Site Title Here',
    },
    plugins: [
        {
            resolve: 'gatsby-plugin-typography',
            options: { pathToConfigModule: './src/utils/typography.js' },
        },
        'gatsby-plugin-react-helmet',
        {
            resolve: 'gatsby-transformer-remark',
            options: {
                plugins: [
                    'gatsby-remark-prismjs',
                    'gatsby-remark-copy-linked-files',
                    {
                        resolve: 'gatsby-remark-images',
                        options: {
                            maxWidth: 800,
                            linkImagesToOriginal: false,
                        },
                    },
                ],
            },
        },
        {
            resolve: 'gatsby-source-filesystem',
            options: {
                path: `${__dirname}/src/docs`,
                name: 'docs',
            },
        },
    ],
};

package.json: N/A

gatsby-node.js:

require('dotenv').config({
    path: `.env.${process.env.NODE_ENV}`,
});

// Static Site Markdown Helper

const path = require('path');
exports.createPages = ({ boundActionCreators, graphql }) => {
    const { createPage } = boundActionCreators;
    const docTemplate = path.resolve('src/templates/docs-template.js');
    return graphql(`
        {
            allMarkdownRemark(
                sort: { order: DESC, fields: [frontmatter___title] }
                limit: 1000
            ) {
                edges {
                    node {
                        excerpt(pruneLength: 250)
                        html
                        id
                        frontmatter {
                            path
                            title
                        }
                    }
                }
            }
        }
    `).then(result => {
        if (result.errors) {
            return Promise.reject(result.errors);
        }
        result.data.allMarkdownRemark.edges.forEach(({ node }) => {
            createPage({
                path: node.frontmatter.path,
                component: docTemplate,
                context: {},
            });
        });
    });
};

gatsby-browser.js: N/A
gatsby-ssr.js: N/A

@m-allanson m-allanson added the type: question or discussion Issue discussing or asking a question about Gatsby label Jun 7, 2018
@m-allanson
Copy link
Contributor

What happens when you use that plugin? If you disable JavaScript and reload the page, do the styles download? If it's running Material UI's server side rendering that should fix the issue you're seeing, I think.

The plugin you linked looks to be using Gatsby's replaceRenderer API to implement Material UI's SSR functionality.

@mbuttler
Copy link
Author

mbuttler commented Jun 8, 2018

Maybe I'm a bit confused about how this plugin works. I don't really use a 'theme' to power my Material UI components-- I'm grabbing them from the examples and using them that way, and defining my own colours using Styled Components.

I defined a theme as per their spec and the problem persists.

If it helps, I basically built my site using this article as guidance.

Can you tell me a bit more about server side rendering? I'm not too familiar with it when it comes to React and MUI. That might be part of the solution I'm looking for.

I also tried out the plugin for styled components but that doesn't seem to work for me either-- it also conflicts with the MUI plugin.

@tetreault
Copy link

I have this issue on a super lightweight page in regards to fonts. It takes a second for the fonts to be applied even though the page is just literally 5 images and small amounts of text. How can i avoid this? It looks pretty bad. I'm using the google font node module for the typeface

@karin-n
Copy link

karin-n commented Jun 18, 2018

I have the exact same issue, super small page and terrible FOUC, only when deployed to Netlify, no problems on local dev environment. Also using Material UI v1 components.

@jigz
Copy link
Contributor

jigz commented Jul 2, 2018

I think gatsby-plugin-material-ui needs an update.

@pdhodgkinson
Copy link

pdhodgkinson commented Jul 3, 2018

So, I work with @mbuttler and spent some time looking into the issue and got everything working. There were actually a few issues for us that lead to the problem.

  1. We are using Styled-component for most of our styling. The Gatsby styled components plugin we were originally using replaces the ssr replaceRenderer function. Because Gatsby doesn't allow you to override the replaceRenderer function twice, we couldn't use a plugin or our own custom gastby-ssr.js file to apply the Material-UI JSS SSR.
  2. Using the Material-UI gastby plugin has the same problem as above. In isolation it applied our custom material ui theme correctly on the SSR side but then when the application client-side javascript loaded it was being overridden by the default Material UI theme. This was causing the FOUC and actually wasn't applying the theme we wanted in the end. I think we could have fixed this by wrapping our App component in a <MuiThemeProvider> tag (as is done in the gatsby-ssr.js file in the plugin). I didn't dig enough to figure out if we could disable the client side loading altogether somehow, or what value there is having client side re-loading of JS if you are pre-compiling.

What we ended up doing is writing a custom gatsby-ssr.js that applied the styled-components plugin wrapper and the code from the material-ui gatsby example. Also using the (pageContext)[https://github.com/mui-org/material-ui/blob/master/examples/gatsby/src/getPageContext.js] and (withRoot)[https://github.com/mui-org/material-ui/blob/master/examples/gatsby/src/withRoot.js] files from the example. This helps ensure that the SSR themes that are applied in the gatsby-ssr file are same ones that are applied on the client-side rendering so you don't get a flicker of changed style when the client-side js is loaded.

Our resulting gatsby-ssr.js file looks like this:

import React from 'react';
import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
import { renderToString } from 'react-dom/server';
import { JssProvider } from 'react-jss';
import theme from './src/themes/default' // eslint-disable-line
import getPageContext from './src/themes/getPageContext';

exports.replaceRenderer = ({
    bodyComponent,
    replaceBodyHTMLString,
    setHeadComponents,
}) => {
    
    const sheet = new ServerStyleSheet(); //styled-components
    
    const pageContext = getPageContext();
    
    const app = (
        <JssProvider registry={pageContext.sheetsRegistry} generateClassName={pageContext.generateClassName} >
            <StyleSheetManager sheet={sheet.instance}>
                {React.cloneElement(bodyComponent, {
                    pageContext,
                })}
            </StyleSheetManager>
        </JssProvider>
    );
    
    const body = renderToString(app);
    
    replaceBodyHTMLString(body);
    setHeadComponents([
        <style
            type="text/css"
            id="server-side-jss"
            key="server-side-jss"
            dangerouslySetInnerHTML={{ __html: pageContext.sheetsRegistry.toString() }}
        />,
        sheet.getStyleElement()
    ]);
    
    return;
};

@natterstefan
Copy link

natterstefan commented Jul 3, 2018

Thank you very much @pdhodgkinson for the great insights and your results. I have still some problems though and I am not sure yet how to solve them. Maybe you can spend some minutes and help me?

It is about the following page: natterstefan/react-trello-multiboard-page#1. I am trying to add pages with *.md files. According to the docs I needed to create a gatsby-node.js. Do you have an example for this as well?

My problem is, that the result on the ssr generated page from the markdown content does not match the client-side version. When you open a page directly the css is not correct (eg. material-ui elements completely messed up), only as soon as you navigate from one to another page it looks the way it is planned...

I ask you, because the example you linked to does not use markdown files... :/

@pdhodgkinson
Copy link

pdhodgkinson commented Jul 4, 2018

@natterstefan I'm not a gatsby expert, just spent a day trying to understand and figure out this one issue for a teammate. Therefore I can't really offer much advice outside of this particular problem I was trying to solve. I did notice you were using gatsby 2.0 beta? Maybe that's an issue? Maybe the plugin system is different enough that my fix won't apply there?
Just a thought! Good luck :)

@natterstefan
Copy link

natterstefan commented Jul 5, 2018

Thanks @pdhodgkinson, yeah I am not an expert either. So you are not using gatsby 2.0 beta (yeah I do, thought what could go wrong ^^).

Trying to downgrade and build it again could be a path to follow. Let's see, thank you.

@markthomasmiller
Copy link

I'm also seeing the FOUC when loading a small page and some fonts. Looks gnarly.

It only happens when I load a page from gatsby build. I'm using Gatsby 2.0 Beta and CSS Modules and hosting on Netlify, if that matters.

@KyleAMathews
Copy link
Contributor

@markthomasmiller your site is only using CSS module's? Is it open source?

@natterstefan
Copy link

Hey @markthomasmiller,

I stumbled upon this comment from @cpboyd a few days ago and finally resolved it.

The important learnings for me were (using Gatsby 2.0):

(...) due to the v2 changes regarding ES6 & CommonJS separation, you'll need to use require() syntax (rather than import) and getPageContext.default() in gatsby-ssr.

You can read more about it here in the official migration guide.

use withRoot.js, getPageContext.js in the pages files (eg. src/pages/index.js) as well as in gatsby-ssr.js

I needed to add them as well to make it work.

Additionally, I had to not remove the SSR css styling in the client. But this could probably be solved by trying another solution proposed by @cpboyd:

it'd probably be safest to move it to onInitialClientRender in gatsby-browser.js like gatsby-plugin-jss so that it doesn't accidentally remove the styles from the server version.

Right now I have not tested this but I will. You can find my current project with the tips applied from above here: https://github.com/natterstefan/react-trello-multiboard-page.

@ng-hai
Copy link
Contributor

ng-hai commented Aug 6, 2018

I have this issue too, I use Gatsby v2 and gatsby-plugin-styled-components@next, no UI Framework.

kapture 2018-08-07 at 0 13 52

@ng-hai
Copy link
Contributor

ng-hai commented Aug 6, 2018

Turn out I forgot to add gatsby-plugin-styled-components in gatsby-config.js. Now it works 😓

@charlesgiroux
Copy link

@pdhodgkinson that fixed my issue, thank you!

I was able to apply withRoot on my layouts only so that I don't have to apply it to each pages.

@adrienpoly
Copy link

I am having a similar FOUC problem with Gatsby 2 and Material UI.

my gatsby-srr.js file is similar to @pdhodgkinson recommendation

const React = require('react')
const { renderToString } = require('react-dom/server')
const JssProvider = require('react-jss/lib/JssProvider').default
const getPageContext = require('./src/getPageContext').default

function replaceRenderer({
  bodyComponent,
  replaceBodyHTMLString,
  setHeadComponents,
}) {
  // Get the context of the page to collect side effects
  const muiPageContext = getPageContext()

  const bodyHTML = renderToString(
    <JssProvider registry={muiPageContext.sheetsRegistry}>
      {bodyComponent}
    </JssProvider>
  )

  replaceBodyHTMLString(bodyHTML)
  setHeadComponents([
    <style
      type="text/css"
      id="jss-server-side"
      key="jss-server-side"
      dangerouslySetInnerHTML={{
        __html: muiPageContext.sheetsRegistry.toString(),
      }}
    />,
  ])
}

exports.replaceRenderer = replaceRenderer

in development, I don't have any FOUC problem only when I build and serve the production files.
after doing some investigation I was able to remove the FOUC effect by turning of the offline support in my gatsby-config.js.

I have tried to play a bit with the options of the Workbox but without any major success in removing this FOUC effect unless disabling it.

Not sure if this can help finding a complete solution to this FOUC issue

Thanks

@Orlandohub
Copy link

Orlandohub commented Nov 15, 2018

I'm in desperate need of some help! I've been so many hours around this flickering issue and honestly not sure what else to do...

On development it works fine but once I build and serve either locally or on Surge or Netlify it just looks so bad.

here it's a preview:
http://recordit.co/SXMXizwWrq
http://recordit.co/VrY32HxxEN

I'm using Emotion and bootstrap css, here it's my repo:
https://github.com/Orlandohub/haha-studio

I was thinking maybe to implement something like window.onLoad to wait for every thing to load and then render, but not really sure how to approach this issue. I just started using Gatsby, it seems great but really need to solve this flickering issue. @ng-hai could you manage to make it work?

@KyleAMathews thanks for this great stuff, I'm in love with Gatsby

@rexsuit
Copy link

rexsuit commented Nov 18, 2018

Update: Fixed this with adding gatsby-plugin-emotion to gatsby-config, as an object with an empty options property, as in the example on the gatsby-plugin-emotion page.

Wanted to chime in with the same issue as described here, especially as @Orlandohub. The repo is not public, but the site I'm working on (beta.mathematic.org) is using gatsby v2, emotion and bootstrap for css, and it is getting a FOUC. The site is pretty light so its not that long lasting, but it's pretty unfortunate. If anybody has any idea why this is, that would be very appreciated be cause this is a blemish on an otherwise amazing suite of technologies.

@Orlandohub
Copy link

@orshick can you please tell me how are you importing the bootstrap css? More precisely, on what component, layout or html and are you importing it via CDN or do you have the file on your local project? I did what you said with the gatsby.config.js and no luck... I will start experimenting with other things I have in mind on how to solve this issue, but I have a feeling this is happening due to the fact I'm importing the styles via a css file which is not loading fast enough.
So even if I do use a different approach, if for some reason, in the future I end up by having the necessity to import css files again, would be great to know how to over come this issue.

@ljaniszewski
Copy link

@Orlandohub I doubt this is due to css not loading fast enough, as the problem occurs also on fresh project made with gatsby starter and gatsby-plugin-sass. Altough I am suspecting that it could be happening only when building develop

@rexsuit
Copy link

rexsuit commented Nov 20, 2018

@Orlandohub For bootstrap I just installed it into my node modules (this is bootstrap 4 I'm talking about here), and imported only the parts of the css that I wanted in my layout file like so:

import 'bootstrap/dist/css/bootstrap-grid.min.css'
import 'bootstrap/dist/css/bootstrap-reboot.min.css'

You're right, looking at your repo you did do exactly as I did, so unfortunately I'm out of ideas for what the issue on your site could be.

@Orlandohub
Copy link

@orshick Thanks for the details, I managed to solve the issue by changing the way I was implementing my code. @ljaniszewski you're right, it's not due to the fact of css not loading fast enough.
It was down to conditional rendering issues based on different states.
I guess for now the key takeaway from all this is to really make sure your implementation it's clean and not trying to do unorthodox approaches.

@tetreault
Copy link

@Orlandohub even then its not a guarantee, i had a simple landing page for a project that had a handful of small pieces of text, literally only 4 PNGs, and only two fonts. Still couldn't get the FOUC to go away. I don't have this same issue with Nuxt at all.

@jonniebigodes
Copy link

@Orlandohub i was about to address the issue you had. I've been digging through your code and it was actually implementation issue than actually one with css. I fiddled with it and managed to get it to resolve the issue you had. But glad you figured it out

@KrzysztofWelc
Copy link

I resolved that problem, when i had got rid of styled components and replaced them with gatsby sass.

@Orlandohub
Copy link

@tetreault in your case all I can say it's if you're using typography for fonts there might be an issue the way they have their webpack setup, I read about some FOUC issues related to typography. Regarding your PNGs images are you using image plugin from Gatsby? If not, I strongly advise you.
Finally I suggest you strip down your project plugins one by one so you can understand where might be the culprit. @KrzysztofWelc I don't think the issue it's related to styled components directly. I believe you should not stop using a specific tool so this kind of FOUC issues go away, it's like hiding the dust under the carpet... If you have tough deadlines and need to make something work fast, it's understandable but my suggestion it's to try to understand how is that specific tool causing the issue, because you might end up solving a common issue and the community appreciates ;)

@kevinmichaelchen
Copy link

kevinmichaelchen commented Dec 19, 2018

@Orlandohub

I managed to solve the issue by changing the way I was implementing my code... it's not due to the fact of css not loading fast enough. It was down to conditional rendering issues based on different states.

In what way was your code doing "conditional rendering"? I have a generic Layout component that wraps its child (children) in a navbar and injects a width prop, but I don't see how that would cause issues.

My experience

One bug I'm observing is Bootstrap styles not being applied properly on initial page load. When I refresh, they are properly applied. The way I'm importing Bootstrap (3.3.7) is with

@import '~bootstrap/dist/css/bootstrap.min.css';

at the top of my scss file.

What I'm Seeing

Initial Load (styles look bad)

When I first open my app in a new incognito session, I see the bootstrap styles in a <style> element near the top of the <head> element. The Bootstrap styles appear before any of my app's styles.

After refreshing (styles look good)

When I refresh the page, it seems like the service worker has converted the <style> element to a <link> element. This makes sense because the CSS file should now be cached, and it would be wasteful to keep those styles bundled in the DOM.

The other difference is Bootstrap appears after my app:

<link as="script" rel="preload" href="/app-1a423a0e7e769206d760.js">
<link rel="stylesheet" type="text/css" href="/0.a37c6b632759115bdcf1.css">

Possible Leads

Style ordering bug in Gatsby

#8092 feels particularly relevant. Per this comment:

pushing all the styles straight to headComponents will fix the behaviour in the above demo.

Properly configuring gatsby-plugin-sass

Maybe I have to properly configure gatsby-plugin-sass?

Updates

  • I tried moving all of my imports of third-party styles from scss files into gatsby-browser.js, per this blog post.
  • I noticed that resizing the window width fixes all style-related issues, almost confirming that "conditional rendering" might be an "unorthodox approach". I'm using the react-sizes library to pass down the width and a corresponding media type string.

@Orlandohub
Copy link

@kevinmichaelchen have a look at this https://spectrum.chat/?t=7b865415-01c3-40e7-8a3b-7966756f6cf4 I think it might help you

@kevinmichaelchen
Copy link

@Orlandohub Thanks. I fixed my issue here. It seems mildly related to react-sizes, but I still can't figure out why.

@scttcper
Copy link
Contributor

struggling with this using emotion https://gatsby-casper.netlify.com/

The transition on the cards really exacerbates the issue.

repo: https://github.com/scttcper/gatsby-casper

@tujoworker
Copy link

@scttcper That really don't looks like a Gatsby nor a Emotion issue. You think about the wiggling of the text during the transition of the cards on hover? Looks to me as a common thing in CSS. You can try scale3d as this uses hardware acceleration, but I bet this will not help either.

@scttcper
Copy link
Contributor

scttcper commented Jan 22, 2019

@tujoworker i'm getting a much larger flash of unstyled content on initial load that doesn't happen w/ the development server.

Here is a gif with internet throttled in chrome.
https://imgur.com/cU8LQvv

Edit: ours was fixed by @geocine in scttcper/gatsby-casper#26 there was changes in the gatsby emotion plugin we weren't following correctly

@protoEvangelion
Copy link

Using styled components and following the docs fixed the issue for me: https://www.gatsbyjs.org/docs/debugging-replace-renderer-api/#fixing-the-replacerenderer-error

@lucasjohnston
Copy link

Sorry to add to the noise, but I'm also experiencing a rather unpleasant FOUC with Gatsby and styled-components (using gatsby-plugin-styled-components). Will continue to investigate 🔍

@protoEvangelion
Copy link

@lucasjohnston did you check if any of your plugins might be conflicting because they are using the same gatsby-node.js apis?

@lucasjohnston
Copy link

@protoEvangelion Yup - I'm not touching onCreateBabelConfig (which is the only node API I can see it touching 👀)

@lucasjohnston
Copy link

lucasjohnston commented Feb 6, 2019

I've just merged in the redesign (with the FOUC), you should see the error I'm encountering - https://github.com/monzo/progression-framework. I've also attached the Chrome Performance view.
I think I'll spend some time this week investigating with some colleagues too and see where we get to.
screenshot 2019-02-06 at 14 40 01

@gatsbot gatsbot bot added the stale? Issue that may be closed soon due to the original author not responding any more. label Feb 27, 2019
@gatsbot
Copy link

gatsbot bot commented Feb 27, 2019

Hiya!

This issue has gone quiet. Spooky quiet. 👻

We get a lot of issues, so we currently close issues after 30 days of inactivity. It’s been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

Thanks for being a part of the Gatsby community! 💪💜

@oliviertassinari
Copy link
Contributor

Regarding Material-UI, we are taking care of the problem in #8237 (comment).

@gatsbot
Copy link

gatsbot bot commented Mar 10, 2019

Hey again!

It’s been 30 days since anything happened on this issue, so our friendly neighborhood robot (that’s me!) is going to close it.

Please keep in mind that I’m only a robot, so if I’ve closed this issue in error, I’m HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

Thanks again for being part of the Gatsby community!

@gatsbot gatsbot bot closed this as completed Mar 10, 2019
@Omar-Gee
Copy link

Hi all,

[MY SOLUTION]

Installed and configured plugins as documented on https://www.gatsbyjs.org/docs/styled-components/

[THE ISSUE]

Migrated from CSS Modules to Styled Components and forgot to install and configure the corresponding plugins properly.

Hope this helps someone out there as this caused me a few days of annoyance.

@natharateh
Copy link

I was experiencing the same issue with a Gatsby site hosted on Netlify using gatsby-plugin-web-font-loader - using typefaces and hosting fonts locally solved the problem for me.

@good-idea
Copy link

good-idea commented Jun 6, 2019

With self-hosted fonts, I was getting consistent FOUT on my build. (On Netlify, but also when simulating the build locally). A peek at the network tab showed that they were being loaded much later than many of the initial requests.

A switch to simply loading them by importing a CSS file in my Layout component's module got them loading much sooner.

@aspiers
Copy link

aspiers commented Jun 6, 2019

A peek at the network tab showed that they weren't being loaded much later

They weren't? Did you mean they were?

@good-idea
Copy link

🤦🏼‍♂️Yup, were. I updated my comment. 🥴

@sahandnayebaziz
Copy link

A switch to simply loading them by importing a CSS file in my Layout component's module got them loading much sooner.

This worked for me too! even with a sass file!

Now I have this in one of my JS files:

import "../stylesheets/index.sass"

@nandorojo
Copy link
Contributor

nandorojo commented Aug 2, 2020

A bit random, but I ran into this issue, and I fixed it by deleting old pages in my src/pages folder that had messed up queries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale? Issue that may be closed soon due to the original author not responding any more. type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests