Webpack 4 operates in a nonsequential manner when loading pages

Recently, I made the switch to webpack 4 for my Rails project where Vue.js 2 is utilized. In addition, I have configured chunks in my setup. However, after the upgrade, I noticed that the page loading sequence seems off. The HTML contents load before styles and JavaScript, unlike the previous behavior. To better understand the issue, I have provided links to videos showcasing the before and after scenarios.

I've scoured various platforms but have been unable to find anyone facing a similar issue...

With Webpack 3 (before)

With Webpack 4 (after)

Below are snippets of my configuration files:

Development Configuration

const environment = require('./environment')
const BundleAnalyzerPlugin =
  require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

environment.plugins.append(
  'BundleAnalyzerPlugin',
  new BundleAnalyzerPlugin()
)


module.exports = environment.toWebpackConfig()

Environment (Shared) Configuration

const { environment } = require('@rails/webpacker')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const vue = require('./loaders/vue')

// Additional configurations...

Pack Related to the Page in the Video

// Code related to packs...    

Rails View for That Page

#app{ data: { signed_in: "#{user_signed_in?}", errors: flash[:errors] } }
  // Rails view content...

Update

Through my research, it seems like the issue lies within:

This is happening because you're bundling with style-loader, which puts your CSS as a string inside your Javascript bundle.

As a result, the HTML renders quickly while the browser parses your JS bundle slowly. Eventually, towards the end of the bundle, the browser encounters the module containing your CSS string, parsing it and applying the styles via Javascript.

Currently, I haven't found an effective solution, so temporarily, I've moved the required CSS files into the Rails app/assets folder to load them separately from webpack and Vue. Although this has somewhat resolved the popping-in issues, I still believe it's more of a workaround rather than a proper fix...

Answer №1

To ensure the proper functioning of the stylesheet, I recommend adding the following code snippet:

= content_for :head
  = stylesheet_packs_with_chunks_tag 'landing_page'

Next, in the application layout (or main layout), include:

= yield :head

This will guarantee that stylesheets are loaded prior to the DOM being ready for javascript execution.

Answer №2

It seems like there is a difference in how webpack3 and webpack4 handle CSS injection in the generated html. Moving

= stylesheet_packs_with_chunks_tag 'landing_page'
to the top may resolve this issue. Make sure to review the content of the landing_page tag, as some CSS might be loaded asynchronously from JavaScript. Compare the HTML code produced by webpack3 and webpack4 to identify any discrepancies in the order of CSS chunks being loaded.

Answer №3

Although I haven't completely resolved this issue yet, I have discovered a temporary solution to revert back to the original webpack 3 behavior of JS/CSS blocking the loading of the page. This idea was inspired by a question on Stack Overflow.

window.addEventListener('load', () => {
  ### Initialize Vue app
});

This approach ensures that the browser waits for all JS and CSS assets to load before initializing my Vue application. It has been effective for all pages except one, which is primarily constructed from Vue components.

To address the issue on the landing page, I followed @Berto's suggestion to defer the loading of JS/CSS packs to the head section with a yield. This modification now blocks the execution on the landing page as well, resulting in the same loading behavior as previously observed.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Modal Component remains unchanged despite being connected to useContext for data, as the Array is being modified through the useReducer Hook

In search of an elegant solution, the title speaks for itself - I am on a mission to create a practice food order App (consider me a novice in this field). This App boasts a Cart feature where users can add items for ordering. The nav-bar conveniently disp ...

Command to conceal components for users visiting as guests

I'm looking to develop a directive that hides specific elements for guest users. Here is the current code I have: angular.module('someMod') .directive('premiumUser', premiumUser) .controller('PremiumUserCtrl', Pr ...

Validation in Laravel and Vue.js

When I receive validation errors from my Laravel api in json format, it looks like this: { "error": { "billabletime": [ "The billabletime field is required." ], "time": [ "time must be an integer." ] } } Now, I am trying t ...

Issue with Material UI Autocomplete: onChange event not firing

When using Material UI's Autocomplete example, I am trying to choose an option using keyboard events: Navigate through options with the Up and Down arrow keys Press ENTER to select the desired option However, the onChange event is not being triggere ...

CSS changes triggered by JQuery are ineffective

Having trouble modifying the CSS of a class in my HTML file. I've been struggling with this for quite some time and can't figure out what I'm doing wrong. (I've already attempted multiple versions, but nothing seems to work) Here' ...

Tips for incorporating a CSS transition when closing a details tag:

After reviewing these two questions: How To Add CSS3 Transition With HTML5 details/summary tag reveal? How to make <'details'> drop down on mouse hover Here's a new question for you! Issue I am trying to create an animation when t ...

Click once to expand all rows in the table with ease

I have successfully created a basic table using HTML. The table includes nested elements that are designed to open individually when clicked on the assigned toggle. Essentially, clicking on a '+' icon should reveal a sub-menu, and clicking on a & ...

Using conditional rendering to set an icon in a ChipField component in React Admin

One feature in my React Admin App is a Datagrid with a ChipField displaying a text property. I want to enhance this by adding an icon to the ChipField using the icon prop, which should change based on the text value. This is my current approach: expor ...

Associating the object key and value with distinct attributes within the component

person = {name: 'Alice', age: '19', weight: 52} I'm looking to display both the keys and values from the object in one label and input field respectively. I attempted using Object.entries, but couldn't figure out how to sepa ...

Validating Dropdowns in React: An Essential Guide

I am in the process of developing a React-based application and incorporating Yup for validation. However, I am encountering a Cyclic Dependency error during the validation process. Description: Users will be presented with two dropdown lists of colors, v ...

Error: Unable to locate script file with npm installation of AngularJS

After installing Angular using npm, I added the following script to my public/index.html file: <script src="/node_modules/angular/angular.js"></script> However, I am encountering a 404 error in the Chrome console. Does anyone have any suggest ...

Preserve the data integrity through two consecutive jsp pages

My task involves extracting a value from a table: <script type="text/javascript"> var activeRequest; $(document).ready(function(){ $(".i_search").on("click", function(event){ event.preventDefault(); acti ...

What is the process of connecting JSON keys to one another?

I am currently brainstorming a solution to link two distinct JSON formats with their respective keys. Here are the two formats: { "price": [ 511, 499, 419, 312 ], "paid": "OK", "contract": "year", "begindate": "01/01/2018", " ...

Is there a way to access multiple values from my function array in Javascript instead of just the first one?

function findDistinctElements(inputArray) { let distinctItems = []; for (let i = 0; i < inputArray.length; i++) { const currentItem = inputArray[i]; if (!distinctItems.includes(currentItem)) { console.log(`Argument ${i+1}: $ ...

Troubleshooting: Brackets Live Preview feature experiencing issues with jQuery

I have been working on a note-taking website as an experiment. Everything was running smoothly in the live preview from brackets until I saved the files, and now none of the jQuery functions are working. I suspect it's an issue with my code, but it co ...

Trouble maintaining router.params after page refresh

I'm experiencing a problem with vue-router. On the homepage, I have a list of posts. Whenever I click on one of them, it redirects me to the post page using this code: <router-link :to="{ name: 'article', params: {id: article.id, slug: ...

Only match the character if it is not at the beginning of the line and if another character is not on the

Is there a way to only match the character "=" in a string if it is not at the beginning of a line and no other character, for example "$", appears on the same line? The equal sign should not be at the beginning of a line No other character, such as "$", ...

The Nightwatch template project seems to have an unresolved function called .waitForElementVisible

After following the steps outlined in , I incorporated the code snippet from into my test file. module.exports = { 'Demo test Google' : function (browser) { browser .url('http://www.google.com') .waitForElement ...

Using knockoutjs to call a component on the home page

I am currently facing some challenges with knockoutjs components, as I am following the guidance provided in the official knockout component documentation. Could someone please advise me on how to correctly invoke my widget component on the main page? It ...

Generate a JSON object from a given JSON template

Hello, I am currently working on creating a JSON instance from a given JSON schema. I would greatly appreciate a Typescript solution, but I am open to any other suggestions as well. Below is a sample of the schema file: sample-schema.json. My goal is to ...