You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The same CSS files are injected several times when switching pages聽#2006
Alright, go ahead, click on Docs (https://v2.docusaurus.io/docs/introduction) in navbar and check the styles in devtools again, now the styles are duplicated several times (+3 new)!
Expected behavior
Styles should not be duplicated (re-injected) when moving to other pages.
Actual Behavior
For some reason, the same styles are injected, which overridden the earlier ones.
First of all, this requires a high level understanding of how webpack works.
The thing is, webpack mini-css-extract-plugin create one css file per js file and then the splitChunk try to cleverly take out a common one if possible but the algorithm is much more complicated than that because it tries to minimize number of request too https://webpack.js.org/plugins/split-chunks-plugin/#defaults
This is just an illustration but i guess this can serve the purpose
Example /docs/introduction requires final css like this
.body {
margin:0;
}
.content {
flex:10 auto;
}
And / final required css is like this
.body {
margin:0;
}
.github {
color: red
}
Here is the question. Do you think webpack will take out the common body { margin: 0;} ?
Such that if i go to /docs/introduction, it will request a.css and this common.css ? and if i go to /, it will just request b.css since common.css has been loaded before
Turns out that it doesn't, because the common.css is too small. and its just better to focus on one css request on first initial page load, thats why the reinjection happens.
Actually this is not happening to CSS only, there are lot of duplicated JS out there for all generated webpack projects.
It's what you said was true, it's weird behavior by webpack though. Reinjecting styles is a bad idea as precedence ordering matters. And I'd assume webpack wouldn't reinject the same style module again if the module has already been loaded before.
Regardless, this issue is probably something to do with webpack.
Another solution is to extract all css into single file. But that is not a good idea as well since that means a lot of unused css in certain page. All has pros and cons.
Its a very weird bug, although its not breaking any website. In fact, requesting one css file is better than requesting two files. Its also very small in size. It just happens to be the body selector so its noticeable.
It's what you said was true, it's weird behavior by webpack though. Reinjecting styles is a bad idea as precedence ordering matters. And I'd assume webpack wouldn't reinject the same style module again if the module has already been loaded before.
Regardless, this issue is probably something to do with webpack.
But its actually two different files.
Page a need a.css
.body {
margin:0;
}
.content {
flex:10 auto;
}
Page b need b.css
.body {
margin:0;
}
.github {
color: red
}
That's why going from pageA to pageB kinda override the same css.
I did an investigation. So the assumption was right, our best solution could possibly be grouping all the css file only into one file. Otherwise, code-splitting CSS will result all of above.
Activity
endiliey commentedon Nov 17, 2019
Well, it's mostly because of code splitted css. example from
docusaurus/packages/docusaurus-theme-classic/src/theme/Layout/styles.css
Lines 8 to 23 in 6204d9a
First of all, this requires a high level understanding of how webpack works.
The thing is, webpack mini-css-extract-plugin create one css file per js file and then the
splitChunktry to cleverly take out a common one if possible but the algorithm is much more complicated than that because it tries to minimize number of request too https://webpack.js.org/plugins/split-chunks-plugin/#defaultsSo https://v2.docusaurus.io/docs/introduction and https://v2.docusaurus.io/ actually both depends on Layout (which depends on that css) and both have their own extra css
This is just an illustration but i guess this can serve the purpose
Example
/docs/introductionrequires final css like thisAnd
/final required css is like thisHere is the question. Do you think webpack will take out the common
body { margin: 0;}?Such that if i go to
/docs/introduction, it will requesta.cssand thiscommon.css? and if i go to/, it will just requestb.csssincecommon.csshas been loaded beforeTurns out that it doesn't, because the common.css is too small. and its just better to focus on one css request on first initial page load, thats why the reinjection happens.
Actually this is not happening to CSS only, there are lot of duplicated JS out there for all generated webpack projects.
endiliey commentedon Nov 17, 2019
One solution is to move
docusaurus/packages/docusaurus-theme-classic/src/theme/Layout/styles.css
Lines 8 to 23 in 6204d9a
That's why people nowadays use css-in-js, it has better tree shaking 鉁岋笍 (and chunking)
yangshun commentedon Nov 17, 2019
It's what you said was true, it's weird behavior by webpack though. Reinjecting styles is a bad idea as precedence ordering matters. And I'd assume webpack wouldn't reinject the same style module again if the module has already been loaded before.
Regardless, this issue is probably something to do with webpack.
endiliey commentedon Nov 17, 2019
Another solution is to extract all css into single file. But that is not a good idea as well since that means a lot of unused css in certain page. All has pros and cons.
Its a very weird bug, although its not breaking any website. In fact, requesting one css file is better than requesting two files. Its also very small in size. It just happens to be the
bodyselector so its noticeable.Still better than going to https://docusaurus.io/docs/en/tutorial-setup and https://docusaurus.io/en/. Everytime new big css file is requested.
endiliey commentedon Nov 17, 2019
But its actually two different files.
Page a need
a.cssPage b need
b.cssThat's why going from pageA to pageB kinda override the same css.
lex111 commentedon Nov 17, 2019
In fact, I am observing such a issue in reusable components.
I have a Showcase component that is used on the home page and on the Users page.
If I go to the first page first, and why go to the latter and look at devtools, I will see the following result:
endiliey commentedon Nov 17, 2019
Let me put more investigation sometimes next week if i got the chance. I still suspect this is because all of that routes is code-splitted though
endiliey commentedon Nov 17, 2019
I did an investigation. So the assumption was right, our best solution could possibly be grouping all the css file only into one file. Otherwise, code-splitting CSS will result all of above.
I just checked Gatsby https://github.com/gatsbyjs/gatsby/blob/67d8b6be93bb4971dadf6aa8e305af2b53560155/packages/gatsby/src/utils/webpack.config.js#L494-L506 and Vuepress https://github.com/vuejs/vuepress/blob/d2fef5d8f6f00aca13b5594c6084a54e1c8c3b18/packages/%40vuepress/core/lib/node/webpack/createBaseConfig.js#L275-L291
They all created one css file only 馃槩
A very particular interesting stuff is that code-splitting css might cause issue on ordering

If we don't want to do this, there's no good solution to fix this problem :) (yet)
yangshun commentedon Nov 17, 2019
Yeah I agree. CSS is usually small in comparison to JS and it's ok to not split it.