The sequence of CSS and deferred JavaScript execution in web development

Consider this scenario: you have a webpage with a common structure in the <head>:

<link rel="stylesheet" href="styles.css"> // large CSS bundle
<script defer src="main.js"></script> // small JS bundle with defer attribute

There is also a

<span id="element"></span>
on the page.

The CSS bundle includes #element { display: none; }.
The JS bundle contains (using jquery):

$(document).ready(() => {
  console.log($('#element').css('display'));
});

However, the outcome can vary. Sometimes the JS executes before the CSS, resulting in 'inline'. Other times, it executes after the CSS, yielding 'none' as desired.

To ensure that my JS bundle is non-blocking, I use the deferred attribute. Placing the JS bundle at the end of the page is not an option due to using turbolinks, which restricts this practice (source).

Using window:load isn't ideal either, as it fires once all resources are downloaded, including images.

I aim for a solution where the JS is non-blocking and executes after the CSS for consistent and predictable results. Is there a way to achieve this?

Answer №1

To ensure that a script is added to the head after a CSS file is loaded, you can use a load event handler for the link element. By doing this, the script will be dynamically inserted and automatically set as async, making it non-blocking and allowing it to execute once the CSS has been loaded.

<link id="stylesheet" rel="stylesheet" href="styles.css">

<script>
  var link = document.getElementById('stylesheet');

  link.addEventListener('load', function () {
    var script = document.createElement('script');
    script.src = 'main.js';
    document.head.appendChild(script);
  });
</script>

It's worth noting that there may be an issue if the stylesheet is cached, as it might not trigger a load event if already loaded. In such cases, you could consider checking for link.sheet.cssRules.

The reliability of load events on <link> elements has been a contentious topic in the past, so there's uncertainty about how well this approach will work consistently.

For a visual demonstration of this method, check out this CodePen showcasing JS loading with a check for link.sheet.cssRules. It has been tested and observed to function correctly in Chrome, FireFox, and Edge browsers.Link to CodePen

Answer №2

Here's a different approach I discovered. You can simply insert a script without the src attribute into the <head> section with some code, like an empty comment: <script>//</script>
That's all there is to it. Now all scripts, including deferred ones, will wait for styles to be applied.
I'm not entirely sure how this mechanism functions, but my understanding is that deferred scripts are placed in a queue after a script without a src attribute, which conventionally must wait for CSS to take effect.

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

Could you explain the distinction between push and offset within the grid system?

I'm currently diving into the world of Bootstrap grids and trying to wrap my head around the concepts of push and offset. In the showcase below, I have two rows that only differ in how the third column is positioned - one using a push and the other an ...

Prevent the reloading of the page by utilizing Ajax technology when submitting a form in Laravel

I'm facing a challenge with processing a form submit using ajax instead of Laravel to prevent page reloads. Unfortunately, it's not working as expected and I'm struggling to figure out the issue. Despite researching numerous examples online, ...

Using AngularJS to pass a parameter to a directive's template

My basic set looks like this HTML <linear-chart chartData="myArray" height="666"> </linear-chart> JS ... ... app.directive('linearChart', function($window){ return{ restrict:'EA', template:"<svg ...

Can someone explain why Array.from(classList)[0] is not changing to 'className'?

HTML Design <div class="custom-container color-red"> <h3>Hello, I am a customized container</h3> </div> Javascript Logic let element = document.getElementsByClassName('custom-container')[0]; let clas ...

React Router v6 is throwing an error stating that within the <Routes> component, all children must be either a <Route> or <React.Fragment>

While the code snippet below may have worked perfectly fine in React Router v5, it's causing an error in React Router v6. Error: [Player] is not a <Route> component. All component children of <Routes> must be a <Route> or <React ...

Tips for passing arguments to event handlers in React JS

While going through the React JS documentation, I came across the concept of "Lifting State Up" and I have some confusion about it. You can check out the codepen sample here: https://codepen.io/valscion/pen/jBNjja?editors=0010 In the TemperatureInput comp ...

How to trigger a JavaScript function when the UI-Router state is switched?

Within my Angular App, I am utilizing ui-router to manage navigation and other tasks. In a separate script file, there is a function that looks like this: $(function () { function doSomething(){ if ($('.thisclass').length) { $(' ...

Utilizing the onscroll feature to trigger a function within a ScrollView

I am facing an issue with an animated view where I need to execute multiple events within the onScroll property. The current onScroll implementation is as follows: onScroll={ Animated.event( [{ nativeEvent: { conten ...

Setting up multiple classes in my unique situation

Setting up an ng-class in my app My current setup looks like this: $scope.myClass = 'class-A'; Performing a task here... $scope.myClass ='class-B'; Performing another task here $scope.myClass ='class-C'; html <div n ...

Is there a way for me to choose a single file while executing the migrate-mongo up command?

Hey there! I'm looking to execute the command migrate-mongo up in just one specific file. Currently, when I run the command migrate-mongo up, it processes all pending migration files. Is there a way to target only one file for execution? For example: ...

Unable to create a horizontal navigation bar

After spending a considerable amount of time on this task, I am perplexed as to why the navbar is not aligning horizontally. I have tried various techniques such as floating to the left and using display inline, but nothing seems to be working. Could there ...

Resetting the randomness in a function within a sudoku generator implemented in JavaScript

I'm in the process of creating a unique Sudoku generator that incorporates randomness into its design. Within my code, there's a particular function responsible for generating the Sudoku puzzles. The issue I'm encountering is the inability t ...

Analyzing the differences in environment management between express and dotenv

Lately, I've noticed an abundance of tutorials and articles discussing NodeJS and the dotenv library. One common practice that keeps coming up is defining an ENV_MODE=development variable within the config.env file. However, it got me thinking - does ...

Having trouble with the functionality of the jQuery `has()` method?

Consider the following HTML code snippet: <div class="comment"> <span class="test">some content here</span> <p>Lorem ipsum</p> </div> <div class="comment"> <p>Lorem ipsum</p> </div> The ob ...

What steps can I take to stop my Details element from moving a nearby Div?

Within this setup, there is a div containing Details and Summaries to the left. Upon expanding the details, the text enlarges and the container moves, causing the image in the right div to shift downward. Is there a way to prevent this from happening? I ...

What is the best way to update $state in AngularJs when the user makes changes to the controller?

I am currently working on Angular UI Router and I want to refresh the current state by reloading it and rerunning all controllers for that state. Is there a way to reload the state with new data using $state.reload() and $stateParams? Here is an example ...

The ng-style directive is not functioning properly

After selecting a category, I attempted to change the color using "ng-style" in my HTML code. However, it seems that the color change is not taking effect. This is the snippet from my HTML code: <div ng-repeat="item in ListExpense" ng-class-odd="&apos ...

I am looking to concatenate the existing URL with the language segment using jQuery

Looking to update the URL when clicking on a language name? Simply add the current path after the language section. For example, change the URL https://example.com/de_DE/about-us/ to https://example.com/us_EN/about-us/ and vice versa. I attempted this code ...

Click Event for Basic CSS Dropdown Menu

My goal is to develop a straightforward feature where a dropdown menu appears below a specific text field once it is clicked. $(".val").children("div").on("click", function() { alert("CLICK"); }); .container { display: inline-block; } .val { d ...

Is there a way to shift a button within a div to the right while maintaining alignment?

After spending hours on this problem, I attempted to use "float: right" and successfully moved the button to the right. However, in doing so, the tag is no longer vertically centered. Can someone please assist me with this? Also, if there are multiple sol ...