Closed doutatsu closed 3 years ago
My research led me to believe its this issue:
This is happening because you're bundling with style-loader, which puts your CSS as a string inside your Javascript bundle.
So the HTML will render (very fast) while the browser is parsing your JS bundle (very slow). Towards the end of that bundle, the browser will find the module containing your CSS string. Then it'll parse that and apply the styles with Javascript.
Following this, I came up with two solutions:
I've extracted the CSS I need into Rails app/assets
folder, to load outside of webpack and Vue. That's the critical CSS I wanted, like footer and header, and margin rules
While I didn't quite get to the bottom of this, but I have found an interim simple solution to get back to the original webpack 3 behaviours, of JS/CSS blocking the loading of the page:
window.addEventListener('load', () => {
### Initialise Vue app
});
It forces to wait till window loads all the JS/CSS assets, before loading my Vue. This worked on all, but one page, as everything except landing page is built from Vue components only.
For landing page, I've adopted another suggestion, to delegate JS/CSS pack load to the head, with a yield
. So now we are also blocking execution on the landing page as well. Combined, I am seeing exactly the same loading behaviour as before.
Hope this helps some of you here. The final solution I want to eventually do is to adopt a skeleton pattern, where I have only outline of my components to show and then they would fill out as the page loads.
From the v4 upgrade guide, did you have extract_css
set?:
Due to the change in #1625, you'll want to make sure that extract_css is set to true for the default environment in webpacker.yml if you want to have Webpacker supply your CSS.
Putting the extracted styles in the <head>
is the ideal solution. If your JS is too fast, you can defer it with https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script.
You can also break things up with dynamic import so that things load faster due to http/2.
I was stuck with the same problem in my react app and used the following plugin to extract the CSS (as webpack 4 requires it). Apparently, this is a required step to add in your webpack config, which I had missed earlier. https://github.com/webpack-contrib/mini-css-extract-plugin
@infantopratik, Webpacker should be automatically adding this plugin for you:
From the v4 upgrade guide, did you have extract_css set?:
@jakeNiemiec I was aware of this and kept it as false
in default, hence the development environment, just as the unedited webpacker.yml
is. But of course it's set to true
in production
environment.
That's the reason why production never looked as bad as on development, but it still had a bit of ordering issue, which I fixed by adding that extra load
and critical CSS.
I also do use chunks for more efficient caching.
@infantopratik as jake said, Webpack provides this by default and I didn't need to it manually myself. I also at some point thought I needed it, but looking into webpacker source, I saw that it gets added
Is this still an issue?
I've upgraded to webpack 4 for Rails. I use it with Vue.js 2. I also use chunks in my configuration. But since upgrading, I've noticed that the page load order is weird. The page loads HTML before styles and JS has been loaded, which is not what happened before. I've attached links to the videos for before and after to understand the issue better.
I've been looking in here and everywhere to find anyone with the same issue, but I couldn't...
With Webpack 3(before)
With Webpack 4(after)
As you can see, it starts of with just HTML, no css applied at all and then loads it bit by bit. ElementUI styles are applied at the very end, as can be seen from the Sign in button becoming styles...
Here are my configuration files:
Dev Config
Env (shared) Config
Pack related to the page in the video
Rails view for that page