Are you enjoying the extensions? Did you like the support? Help others decide.

Leave a review
05Nov2022
Information
Print

Loading scripts and the use of the 'defer' attribute with jQuery Easy Profiles

Information
First published July 27, 2022
4638 hits - No rating
 

In Joomla, scripts are added to the <head> tag on a page.

When the browser's HTML parser finds the <script> tag, it downloads the script and executes it. After the task is done, it goes on and parses the remaining HTML.

[code]<html>
<head>
<title>Title</title>
<script src="/script.js"></script>
</head>
<body>
...
</body>
</html>[/code]

There are many ways scripts are added in the <head> of a document in Joomla.

  • Some templates can manually add the scripts in the index.php file,
  • Some extensions can also add scripts manually via the <script> tag (a bad way to add scripts on a page),
  • Scripts can be added directly via the API such as JFactory::getDocument()->addScript() or the HTMLHelper class,
  • Scripts are added via web assets in Joomla 4 (but all methods can co-exist, and jQuery Easy needs to take all of them into account).

Delay is introduced and it can have a negative impact on the perception users have of the visited page.

One solution widely used has been to add the scripts before the end of the <body> tag. It forces the scripts to get fetched and executed once the whole page has been parsed (in Joomla, you need an additional extension to do that).

[code]<html>
<head>
<title>Title</title>
</head>
<body>
...
<script src="/script.js"></script>
</body>
</html>[/code]

Modern browsers have other ways to delay the execution of scripts with two attributes: defer and async.

[code]<html>
<head>
<title>Title</title>
<script defer src="/script.js"></script>
</head>
<body>
...
</body>
</html>[/code]

if you specify both attributes, async takes precedence on modern browsers, while older browsers that support defer but not async will fallback to defer.

How loading times are spent

In the following graphs, you will find:

  •      the HTML being parsed
  •      the HTML being paused
  •      a script being downloaded
  •      a script being executed

<script>

The script tag without any specific attribute
The script tag without any specific attribute

When defined without any specific attribute, the script is downloaded/fetched as soon as it is 'hit' during HTML parsing. It is then executed before parsing is resumed.

<script async>

The script tag with the async attribute
The script tag with the async attribute

The script file is fetched during HTML parsing. Parsing is paused while the script file is executed. Async scripts are executed as soon as they finish downloading.
The order of execution is not guaranteed (it depends on the size of the scripts and speed downloads).

<script defer>

The script tag with the defer attribute
The script tag with the defer attribute

The script file is fetched during HTML parsing as well, without pause, and is executed after the HTML has been parsed (right after the domInteractive event, once the DOM has been built).
Scripts are guaranteed to execute in the order they appear in the document (unless IE9 and under are used).
Note: at this point, images have not yet been parsed and loaded.

<script> before </body>

The script tag before the end of the body tag
The script tag before the end of the body tag

The HTML is fully parsed then scripts are fetched and executed.
This solution will allow the HTML to be parsed in the fastest way possible, but scripts will take longer to execute, compared to the defer method. Depending on what the scripts are supposed to do, the user may perceive the difference.

Using defer in jQuery Easy Profiles

You may now have a better understanding of the way scripts are loaded on a page. But can you defer jQuery and Bootstrap with the help of jQuery Easy Profiles?

The answer is yes (in jQuery Easy Profiles v5.1 and over), but in some cases, you may not be able to (especially under Joomla 3).

For instance, if MooTools is loaded on the page or jQuery script declarations are in the <head>, you will end up with errors if the jQuery scripts are using defer.

If jQuery can use defer, Bootstrap should as well (unless Bootstrap 5 is loaded, in which case you can do whatever, since it does not rely on jQuery anymore in Joomla 4).

Why only defer in jQuery Easy Profiles?

jQuery Easy ensures scripts are loaded in the proper order. Therefore, it makes sense to use defer over async when loading scripts that have been 'fixed' by the plugin. But you can still add your own scripts and use either method.

Content Delivery Networks for loading scripts

Using CDNs removes any maintenance overhead. But because they are not on the same origin as the rest of your resources, loading files from a public CDN comes with a network cost. The browser needs to perform a DNS lookup, establish a new HTTP connection, and, on secure origins, perform an SSL handshake with the vendor's server.

Whenever you can, use the libraries already available in the Joomla version you are using or download and store those scripts on your own server. It will reduce DNS lookups and you can have more control over caching.

Advanced tweaks

For advanced users, and especially under Joomla 3, you can get an optimal setup by using JCH Optimize in combination with jQuery Easy. Script declarations can be merged with JCH Optimize, and scripts can be excluded from that plugin, allowing jQuery Easy to thoroughly clean and defer those scripts.

jQuery Easy's main purpose is to fix issues that can arise when extensions 'collide' or add scripts that interfere with other ones or the template. jQuery Easy makes fixes 'on-the-fly' without caching the results, therefore there is an additional execution time overhead on the server that is small, but which exists. It can be reduced by using external services like Cloudflare, which cache content.

For more information and for reference