Open bradennapier opened 7 years ago
Understand it's annoying, but I don't want to introduce hacks around this.
Let's update the FAQ though.
How about using something like isomorphic-style-loader, which is used in react-starter-kit? I'd happily work on a PR, but am not comfortable with isomorphic apps enough to give it a shot just yet. Can anyone assess this approach? Will it work well? Is it worth to try? @ctrlplusb
Something like this in the HTML component will lessen the effect, if not solve it completely.
${
_.keys(assets.css).length === 0 ?
`<style>${
// $FlowIssue
require('../styles/normalize.css')._style +
// $FlowIssue
require('../components/App/styles.scss')._style +
// $FlowIssue
require('../components/Home/styles.scss')._style +
// $FlowIssue
require('../components/NotFound/styles.scss')._style
}</style>` : ''
}
Hard-coding css file imports is not a solution IMO.
You need to enable extract-text-plugin on the server end, something along these lines:
// ./internal/webpack/configFactory.js
// in plugins
ifElse(isDev && isServer)(
() => new ExtractTextPlugin({
filename: 'dev-styles.css', allChunks: true,
}),
),
// in module.rules css section
ifElse(isDev && isServer)(() => ({
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader/locals'], // You have to use locals on the server (no window).
}),
})),
// ./server/middleware/reactApplication/ServerHTML.js
const headerElements = removeNil([
// ...
onlyIf(process.env.BUILD_FLAG_IS_DEV, () => stylesheetTag('/dev-styles.css')),
]);
@birkir @strues @ctrlplusb can anyone more knowledgeable than me please have a look at my suggestion above to solve this without reinventing the wheel? :wheel_of_dharma:
I'm not a fan of isomorphic style loader HOC s method so i cannot really comment on the issue. If what we already have can be configured to work rather than bringing in another dependency, I would rather support that :)
Did the above solution not work for you?
I'm probably going to present an unpopular opinion, but I've basically grown accustomed to the FOUC. It's been so common that I've accepted it as part of the game. I do know you can avoid it by adding BrowserSync to the mix, but that itself can be another headache.
@birkir,
I'm not a fan of isomorphic style loader HOC s method
Can you please elaborate? I haven't tried using it myself, so don't have an informed opinion :(. I just saw it is in use in the very popular react-starter-kit universal boilerplate and thought we can use it to solve the same issue.
@strues Same for me and other devs at Ueno., we actually like the flash of unstyled content. We have had some issues when we're calculating element dimensions in componentDidMount with something like getBoundingClientRect
, as the styles have not loaded so we get incorrect dimensions. So we are forced to think about this, as this will happen with clients with slow network as well.
@elektronik2k5 In components that will be using styles you have to add higher order component (export default withStyles(styles)(MyComponent)
). I am fine with HOC's in general for special occasions, but every damn component is brutal if you think about that the below example will fail:
// Demo.js
import s from './Demo.css';
class Demo {
render() {
return <div className={s.foo}>Node 1</div>;
}
}
export default withStyles(s)(Demo);
// Demo.spec.js
test('Demo component has div.foo', () => {
const component = shallow(<Demo />);
expect(component.childAt(0).equals(<div className={s.foo} />)).to.equal(true);
});
Some will be fine with using contains, find, etc. This is just my personal opinion.
Wondering if anyone here has figured out a solution to this FoUC yet?
@ctrlplusb Would you consider hiding the DOM node with the app until style has loaded in 'development' mode a hack? 😄
Accept that it happens in development. 9.9999/10 if will not happen in production. Most of the time during development the cause is styled-components or a Webpack loader. Once the styles are compiled and served, you wont be experiencing it.
Alternatively, here's a solution:
${
_.keys(assets.css).length === 0 ?
`<style>${
// $FlowIssue
require('../styles/normalize.css')._style +
// $FlowIssue
require('../components/App/styles.scss')._style +
// $FlowIssue
require('../components/Home/styles.scss')._style +
// $FlowIssue
require('../components/NotFound/styles.scss')._style
}</style>` : ''
}
Load each and every individual style 👎 .
@strues It seems like it shouldn't be happening with styled-components according to these comments in that repo?
An update:
So, I've fixed the FoUC with Styled-Component as part of #505. It turns out the SC styles were never being rendered on the server, only the client. With that fixed, FoUC from SC is gone in that feature branch. Check out https://github.com/ctrlplusb/react-universally/pull/505
Now that leaves three other sources of FoUC - Normalize.css
, Globals.css
, and Milligram
.
For the SC feature branch: The first two of these can be fixed by using Polished
(or other similar styled-components normalize/reset libraries), and using injectGlobal
for globals.css. Solution for
Milligrammight also be
injectGlobal`.
Not sure about solutions in the master
branch.
May not be worth adding since I believe this should only happen during development - but it does annoy me quite a bit. It could be worth looking into implementing a solution similar to what was done by universal-webpack