Drupal main javascript file can't be loaded with "defer" attribute after upgrade to 8.8.1

Created on 8 January 2020, almost 5 years ago
Updated 13 August 2024, 3 months ago

What are the steps required to reproduce the bug?

Add a defer tag to the script tag of the main js file e.g. with ADVAGG module or via EventSubscriber.

What behavior were you expecting?

No problems with the former domready handler (Drupal 8.7.10). Alle Drupal behaviors were added and executed.

What happened instead?

With Drupal 8.8.1 the attachBehaviors function is executed but the behaviors variable contains an array and not an object which is required for attaching all behaviors in the loop.

---

This is a massive performance issue and should be looked at ASAP.

πŸ› Bug report
Status

Fixed

Version

9.5

Component
JavascriptΒ  β†’

Last updated 3 days ago

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡²πŸ‡ͺMontenegro adubovskoy Budva

    Patch for D9.5.

  • πŸ‡ΊπŸ‡ΈUnited States wesleymusgrove

    Unless we have many developers not using advagg that ran into this issue I don't see core are the place to fix this

    Since AdvAgg is no longer recommended for D10 (and causes issues like not saving newly generated bundles of JS to disk unless you uncheck "Enable advanced aggregation" πŸ“Œ Document which parts of the module are still relevant after aggregation changes in 10.1.0 Needs review ), I've completely uninstalled it, but still needed a way to defer all JS as @nod_ mentioned in #42 πŸ› Drupal main javascript file can't be loaded with "defer" attribute after upgrade to 8.8.1 Fixed .

    So I added this simple hook to `defer` all scripts:

    <?php
    /**
     * Implements hook_js_alter().
     */
    function custom_js_alter(array &$javascript) {
      foreach ($javascript as &$js) {
        if (is_array($js) && isset($js['attributes'])) {
          $js['attributes']['defer'] = 'defer';
        } 
      }
    }
    ?>
    

    Before uninstalling AdvAgg, I had previously applied the core patch from #45 β†’ , which I re-rolled for D10.

    After uninstalling AdvAgg and adding my `custom_js_alter` hook, I started seeing this issue happen again where Drupal behaviors weren't executing if they were attached after drupal.init.js had loaded, as would be the case for all the deferred scripts.

    Since @nod_ mentioned that

    it is safe to call multiple time[s]

    on #38 πŸ› Drupal main javascript file can't be loaded with "defer" attribute after upgrade to 8.8.1 Fixed , would a custom module adding some JS like this to call `Drupal.attachBehaviors` one last time after the document is `complete` be an appropriate solution?

    (function (Drupal, drupalSettings) {
      var domReady = function domReady(callback) {
        var readyStateCheckInterval = setInterval(function () {
          if (document.readyState === 'complete') {
            callback();
            clearInterval(readyStateCheckInterval);
          }
        }, 100);
      };
    
      domReady(function () {
        Drupal.attachBehaviors(document, drupalSettings);
      });
    })(Drupal, window.drupalSettings);
    
    If someone aggressively defer all scripts without using advagg I would hope they know what they are doing. the drupal.js/drupalsettings scripts are light enough to not have to defer them

    I realize this technique _does_ aggressively defer all scripts and that is my goal. Is there a list of core drupal JS files that should be excluded from getting the `defer` attribute for D10 core's `Drupal.attachBehaviors` to continue working as expected even for deferred scripts that define new behaviors?

    Thanks! I know this has been closed for a while, but it seemed relevant to this conversation.

Production build 0.71.5 2024