I have a few external js files running: facebook's all.js, maps.google, authentication from various external services running.

Sometimes these external js files load slowly.

I am noticing that when I select bundle external js to load at the top, anyone of the js blocks the page load.

Is there anyway to set 'async' for certain external scripts so that they might load in parallel.

There are few modules that do something like this but I don't know how they interact with advagg:
https://www.drupal.org/project/async_js
https://www.drupal.org/project/async_script_shim

Or is there a way to do this which I am not aware of with the current module

Comments

mikeytown2’s picture

Category: Bug report » Feature request

The async shim is built into advagg_mod. On the admin/config/development/performance/advagg/mod the "Rewrite asynchronous script tags to inline, old-browser-compatible scripts" checkbox will do what those projects do; this is only needed for older browsers.

To get what you want currently you would need to implement hook_js_alter() and add in the async = TRUE key to the external file.

/**
 * Implements hook_js_alter().
 */
function socialnicheguru_js_alter(&$javascript) {
  foreach ($javascript as $name => $values) {
    // Skip if not external.
    if ($values['type'] != 'external') {
      continue;
    }
    // Set async to true if file is connect.facebook.net/en_US/all.js
    if (strpos($name, 'connect.facebook.net/en_US/all.js') !== FALSE) {
      $values['async'] = TRUE;
      // Stop processing once we've modified facebook's all.js.
      break;
    }
  }
}
socialnicheguru’s picture

Thanks. I need a little more clarification.

There is an expermintal settings adding async to all js. This break my site.
I want to be more strategic about which js have the async attribute added. I can use the above code for that correct?

You wrote: "The async shim is built into advagg_mod. On the admin/config/development/performance/advagg/mod the "Rewrite asynchronous script tags to inline, old-browser-compatible scripts" checkbox will do what those projects do; this is only needed for older browsers."

Does that mean that setting "Rewrite asynchronous tags ..." adds async to all js? I don't think it does. Maybe I misread the statement.

mikeytown2’s picture

There is an experimental settings adding async to all js. This break my site.
I want to be more strategic about which js have the async attribute added. I can use the above code for that correct?

This is correct; it will async just the external js. And from here you can start to modify things if you desire to.

This setting

Rewrite asynchronous script tags to inline, old-browser-compatible scripts.
Rewrites all scripts in the page with an "async" attribute to an inline JavaScript loading the script asynchronously in an old browser compatible way. List of supported browsers. Once all commonly used browsers support the "async" attribute you can happily disable this checkbox.

Leave unchecked. Not needed as async has been supported for several years now & doing it the old way is not ideal. Look at this D8 module to get an idea on what this setting does: https://www.drupal.org/project/async_script_shim

Under Experimental Settings is where the all to async is located.

mikeytown2’s picture

Status: Active » Closed (duplicate)

You're sorta asking for something like this #2149321: Create a submodule allowing one to modify every CSS & JS asset
Going to mark it as a duplicate.

Narek’s picture

Hi Mikey

I am having hard time making this work.
1) I checked this box "Asynchronous JavaScript Execution: Add The async Tag To All Script Tags"
2) I tried to use hook_js_alter in my theme to disable sync for some of js files.
but even though the hook alters the variable, drupal still prints async=1 for the js file. I tried other way around and disabled the option and tried to make the async=true for some js files, and it doesn't print async=1 at all.

How should I fix this?

Thank you

mikeytown2’s picture

Uncheck "Asynchronous JavaScript Execution: Add The async Tag To All Script Tags".
Use hook_js_alter to set the async key to TRUE for the files you want.

When adding a new hook call to drupal you'll need to flush caches. To see if the hook is working put in a drupal_set_message or an echo for testing purposes & make sure advagg is not using the aggressive cache while developing the hook.

harrick’s picture

I'm also having trouble with this. I'm trying to add the async tag to one specific external JS file only and have followed the instruction above but no luck.

I have the hook_js_alter function above in a custom module, flushed cache and tested that its registered by using dsm. I can define the async attribute in hook_js_alter as instructed above and this value can be seen in the dsm array. However it doesn't seem to make any difference to the script tag output to the browser as the async attribute is still missing.

I have advagg and advagg_mod modules enabled and my drupal_add_js function is as below:

drupal_add_js('//platform.twitter.com/widgets.js', array('type' => 'external', 'weight' => -15, 'group' => JS_THEME, 'scope' => 'footer'));

I tried a number of different settings for the advagg and advagg_mod without success so have now returned them to their defaults.

This is my first use advagg so I suspect I'm missing something very obvious. Any pointers would help.

Many thanks.

UPDATE:

I've just noticed that the above code is missing the & form the $values variable. The hook_js_alter code should therefore be as follows (Note &$values):

/**
 * Implements hook_js_alter().
 */
function socialnicheguru_js_alter(&$javascript) {
  foreach ($javascript as $name => &$values) {
    // Skip if not external.
    if ($values['type'] != 'external') {
      continue;
    }
    // Set async to true if file is connect.facebook.net/en_US/all.js
    if (strpos($name, 'connect.facebook.net/en_US/all.js') !== FALSE) {
      $values['async'] = TRUE;
      // Stop processing once we've modified facebook's all.js.
      break;
    }
  }
}

This change fixes the problem. Note to self: don't just blindly cut and paste!

mikeytown2’s picture

What version of advagg are you using? 7.x-2.8 is recommended.

harrick’s picture

Thanks for the speedy response Mikey. I noticed the cause was a missing & from the above code which I had just cut and pasted. All fixed and works as expected.

RAWDESK’s picture

subscribing #7

mikeytown2’s picture

@RAWDESK
Is there anything you're looking for? This issue is over 2 years old.

RAWDESK’s picture

Just noting it down in my issue queue, because I have a case here where the async tag was not set, although configured in the UI.
Something I'll further dig into next week..

mikeytown2’s picture

FYI: async is only supported in AdvAgg and not in Drupal 7 Core.

RAWDESK’s picture

I know mikeytown2. I was referring to the AdvAgg UI settings. Not D7 core.

mikeytown2’s picture

What part of the UI can you set async other than the part that says here there be dragons (as in I never got it to reliably work)?