Rocket Loader for Wordpress

Controlling Cloudflare Rocket Loader for WordPress

Ernest Marcinko Tutorials, Wordpress 18 Comments

What is Rocket Loader?

Automatically optimizes your pages to minimize the number of network connections and ensure even third party resources won’t slow down page rendering.Cloudflare

rocket.png.scaled500_1_[1]Rocket loader from Cloudflare is definitely worth some time for every WordPress site owner. Proper configuration is however a little bit tricky, as there is only a limited access to the WordPress header.

How does it work?

First of all, you need a Cloudflare account. After you managed to set up your domains to run wiht cloudflare, there is an option to turn on Rocket Loader. This snippet will grab all of your javascript files and load them asynchronously.

Why is that good, you ask? Well, javascript loading by default is blocking, which means, that the files are loaded and executed one by one. This takes time. There is a way to define asynchronous javascript loading with the HTML 5 async and defer attribute, but that is entirely different from what rocket loader does. The async attribute ignores the order of the javascript files, and the defer doesn’t, but there are still incompatibilities from browser to OS. Rocket Loader however provides a platform, which works for each browser and OS the same way.

The script currently has two possible active states:

  • Automatic – chooses most of your srcript files to load asynchronously
  • Manual (not working) – you can chose which files to load asynchronously

Rocket Loader

Automatic mode

If you enable automatic mode, you don’t have to do nothing else. Purge the cache in cloudflare, reload your page, and you should already experience a faster page load.

Don’t forget to check every javascript powered part of your site! Rocket Loader in some cases can cause issues with ceartain scripts, so always double check your site after loading it. But what should you do, if you want to load some of your assets non-asynchronously, or some of the scripts are not working with rocket loader? That’s what the manual mode is for.

How to control which scripts to ignore in automatic mode?

This thing is almsot broken, but here is the SOLUTION! On the cloudflare documentation page it is stated that the script tag must be in the following state to ignore rocket script auto mode:

<script data-cfasync="false" src="/javascript.js"></script>

That would be ok, but it won’t ignore the script if the type=’text/javascript’ attribute is present.

The problem is, that in WordPress we don’t have direct access to all javascript declarations, it’s only possible to modify the script url by using the clean_url filter. That’s not enough. We must also remove thetype attribute from the scripts. How should we do that?

Well, we must find the action that fires before the scripts are outputted, and the one that fires after the scripts are outputted:

  • wp_print_scripts – this one fires before the scripts are printed
  • wp_print_head_scripts – this one fires after the scripts are printed

Problem solved! All we need to do now is capture the output and replace the type attributes on scripts which we don’t want to use with rocket loader.

 

If you put this code into the themes function.php file, it will add the proper async attribues to each file, and you can also define the files to ignore as well:

function rocket_loader_attributes_start() {
    ob_start();
}

function rocket_loader_attributes_end() {
    $script_out = ob_get_clean();
    $script_out = str_replace(
      "type='text/javascript' src='{rocket-ignore}", 
      'data-cfasync="false"'." src='", 
      $script_out);  
    print $script_out;
}

function rocket_loader_attributes_mark($url) {
    // Set up which scripts/strings to ignore
    $ignore = array (
        'script1.js'
    );
    //matches only the script file name
    preg_match('/(.*)\?/', $url, $_url);
    if (isset($_url[1]) && substr($_url[1], -3)=='.js') {
      foreach($ignore as $s) {
         if (strpos($_url[1], $s)!==false)
           return "{rocket-ignore}$url";
      }
      return "$url' data-cfasync='true";
    }

    return "$url";

}
if (!is_admin()) {
  add_filter( 'clean_url', 'rocket_loader_attributes_mark', 11, 1);
  add_action( 'wp_print_scripts', 'rocket_loader_attributes_start');
  add_action( 'print_head_scripts', 'rocket_loader_attributes_end');
}

By editing the $ignore array, you can can manually add the script files/strings you want to ignore from Rocket Loader. I’m using this handy snippet on few sites, and it’s working nicely.

Comments 18

  1. Pingback: Maximum performance with WordPress | WordPress Dreams

  2. Sarah Lorenzen

    I’m trying to implement your solution for my client’s website: www.globalwealthpartnersinc.com

    I’m using a child theme though, and I’m sure that will somehow change possibly the names of the script files from ‘script1.js’ to maybe ‘../script1.js’ or something entirely different?

    In your last bit of code with the ‘wp_print_scripts’, wouldn’t you want to use wp-enqueue instead?

    Also, when I tried to implement the code as-is then naming all the scripts I needed ignored, I got an error, across a white screen and the site was down.

    I am trying to have all the Layer Slider plugin scripts ignored. The rocket loader is awesome, except it then means I can’t have the Sliders showing up properly. Hope you can help me figure this out.

    1. Agostino Priarolo

      I’m trying to figure out exactly the same thing and I’m getting the same blank white page from the site! Everything works fine (or at least, I still didn’t manage to catch anything else) but the LayerSlider plugin (using Enfold…) while rocket loader is enable. I hate this, since with or without Rocket loader I get a huge difference in Gtmetrix…

  3. David

    Hi, for the $ignore array should it be just the file name or the full path to the scripts we want ignored? I’ve tried both but always still see data-rocketoptimized=”true” type=”text/rocketscript” etc added the scripts i’m trying to get it to ignore.

    Any help would be much appreciated.
    Thanks!

  4. AJ

    Hi Earnest,

    I took a look at your source code here and was wondering why you have the data-cfasync=”false” attribute on a few script tags but do not actually have Rocket Loader enabled at all.

    At any rate, the most elegant way to get Rocket Loader to ignore certain scripts would be for CloudFlare to be so overwhelmed with requests for one to be able to do this right within the CloudFlare dashboard that they have no choice but to implement such a change. Which would be extremely simple for them to do.

    In short, CloudFlare’s Rocket Loader scans a page for .js files, combines them into ‘bags’, then defers them. All CloudFlare has to do is enable an ‘exclude script from bag’ feature wherein one inputs the file to exclude and voilà – done.

    I do hope others reading this will be motivated to contact CloudFlare and request this very-easy-to-implement and user-friendly change to the Rocket Loader feature.

    Best,
    AJ

  5. Michael

    Awesome snippet!

    I have a few scripts in the footer and this script doesn’t work for them :S It doesn’t manage to perform the str_replace() on them and leaves src='{rocket-ignore}

    1. Ernest Marcinko Post
      Author
      Ernest Marcinko

      Hi Michael,

      I think you should consider moving them to the header, since the main purpose of the snippet is to make the blocking header scripts non-blocking, so there is no reason to have them in the footer. That’s probably the fastest and easiest solution.

    1. Ernest Marcinko Post
      Author
      Ernest Marcinko

      Try to add the script file names to the $ignore array in the rocket_loader_attributes_mark function:
      [code]
      $ignore = array (
      ‘script1.js’,
      ‘script2.js’,
      ‘script3.js’
      );
      [/code]

  6. Tom

    Please i have a problem when i activate Rocket Loader in cloudflare, my plugin WP Post plugin stop working correctly, and i don’t know how to insert the cloudflare script to ignore my plugin .

    please help

  7. George I Birnbaum

    Example of my working rocket loader ignore. The {rocket-ignore} in the return was causing an issue. Make sure to use full file paths. This works on WP-Engine should you care.

    Cheers

    function rocket_loader_attributes_mark($url) {
    // Set up which scripts/strings to ignore
    $ignore = array (
    ‘/wp-content/plugins/instagram-feed/js/sb-instagram.min.js’,
    ‘/wp-includes/js/jquery/jquery.js’
    );
    //matches only the script file name
    preg_match(‘/(.*)\?/’, $url, $_url);
    if (isset($_url[1]) && substr($_url[1], -3)==’.js’) {
    foreach($ignore as $s) {
    if (strpos($_url[1], $s)!==false)
    return “$url”;
    }
    return “$url’ data-cfasync=’true”;
    }

    return “$url”;

    }
    if (!is_admin()) {
    add_filter( ‘clean_url’, ‘rocket_loader_attributes_mark’, 11, 1);
    add_action( ‘wp_print_scripts’, ‘rocket_loader_attributes_start’);
    add_action( ‘print_head_scripts’, ‘rocket_loader_attributes_end’);
    }

  8. Lappy

    For those who are trying to make this work, you may check where your scripts are loading. Mine was at the footer. So I had to change the “print_head_scripts” to “print_footer_scripts”

    if (!is_admin()) {
    add_filter( ‘clean_url’, ‘rocket_loader_attributes_mark’, 11, 1);
    add_action( ‘wp_print_scripts’, ‘rocket_loader_attributes_start’);
    add_action( ‘print_footer_scripts’, ‘rocket_loader_attributes_end’);
    }

  9. Nim

    Thanks for this.

    In my case I was finding that the Like button generated by Jetpack on a WordPress site wasn’t working with RocketLoader on

    $ignore = array (
    ‘queuehandler.min.js’
    );

    Fixed it. Otherwise using the snippet as shown.

Leave a Reply to Marek Cancel reply

Your email address will not be published.