What is asynchronous javascript loading. Let's take advantage of the dependence of other scripts on jQuery. Getting rid of the external file

12/25/2012 job 18355

Let's talk a little about optimizing page loading in Joomla. For today it will be JavaScript connection. First of all, I will draw the attention of the layout designers to the correctness of the template construction. And then we’ll look at the ability built into the engine to use asynchronous loading of external scripts. I won’t go into why optimization is needed.

Building a template

As a rule, Joomla designers do not pay attention to the loading order of styles and scripts, and this important aspect optimizations for parallelization of loading. CSS files should always be included before JavaScript files.

If in your template loading css and javascript looks like this:

I want to assure you that this is not correct! Because you load external files after the page has been rendered, which means that the head block has already been formed, hence the chaos of loading in a checkerboard pattern.

Here's how to correctly include files in rendering:

We do not pay attention to the validity of doctype and html, I wrote it briefly for example.

Asynchronous loading

But here I would pay more attention and read the article to the end! Often, optimization clients require asynchronous javascript loading. Oddly enough, Joomla developers have provided for this possibility, but developers of third-party components, modules and plugins forget about this functionality, which is probably why Jooml is often criticized for low optimization, which I would argue with.

As discussed earlier in document rendering there is a function addScript();. But apparently some people don’t even suspect that it has four variables - $url, $type, $defer, $async.

$this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js"); $this->addScript($this->baseurl."/templates/beez_20/js/script.js");

But in our case, we need to queue the loading of scripts by the browser; for this we need to use the attribute async and/or defer. Both differ only in that defer preserves the order in which scripts are executed. Defer is needed if script.js the jQuery framework is used, which will prevent it from loading before the library itself, and if it is necessary to maintain a certain sequence.

And so, to enable asynchronous loading, you need to use all the variables

$this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript"); // or $this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript", false, false); // Prints $this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript", true, false); // Prints $this->addScript($this->baseurl."/templates/beez_20/js/jquery-latest.min.js", "text/javascript", false, true); // Outputs

And one more small moment. In principle, these attributes are HTML5 elements, therefore there is no point in using the form async="async" and defer="defer", async and defer are enough, respectively.

Let's make adjustments to the joomla library. Opening site.ru/libraries/joomla/document/html/renderer/head.php

We are looking for (about line 150):

// Generate script file links foreach ($document->_scripts as $strSrc => " . $lnEnd; )

replace with:

// Generate script file links foreach ($document->_scripts as $strSrc => $strAttr) ( $buffer .= $tab . "" . $lnEnd; )

That's all the salt. All the manipulations were carried out by me in Joomla 2.5, I didn’t consider how it would work in 1.5 xs, and it’s time to forget about it))). And the technique described above is not a panacea at all; everyone needs an individual approach.

Thank you for your attention!

/ 26.01.2018

With the increase in Internet connection speed and the increase in power not only of desktop, but also mobile devices Web pages are becoming heavier. The number and size of connected files is growing: JavaScript files, css files, images, third-party site widgets, iframes. On this moment The specifics of how browsers work is such that when loading a js file, rendering is blocked until the script is executed. Modern browsers V background will parse the document and download scripts and styles, but rendering will be blocked. Comparison network parameters For different browsers can be viewed at browserscope.org. We cannot eliminate blocking completely, but we can optimize the server and client parts of the application so that render blocking takes the shortest amount of time.

Server side solutions:
— Reduce size transferred files
— Use CDN
— Place static files on separate domain or under a domain, thus increasing the number of simultaneous browser connections.
— Enable compression of transferred files (gzip)

Solutions for the client side:
— Reduce the number of requests.
- Cache files on the client side using the Expires and Etags headers.
— Use publicly available CDNs (Google CDN, Yandex CDN). So there is a possibility that the file from the public CDN will already be stored in the browser cache.

One way to optimize site loading speed is to load files asynchronously, which does not block rendering.

JavaScript asynchronous loading script:

(function() ( var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = ' File URL'; document.getElementsByTagName('head').appendChild(script); ))();

If JavaScript needs to be executed after the entire page has loaded, including content, images, style files, and external scripts, then the onload event needs to be added to the loader.

if (window.addEventListener) ( window.addEventListener('load', async_load, false); ) else if (window.attachEvent) ( window.attachEvent('onload', async_load); )

JavaScript asynchronous loading script based on the onload event

(function() ( function async_load())( var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = 'File URL'; document.getElementsByTagName ('head').appendChild(script); ) if (window.addEventListener) ( window.addEventListener('load', async_load, false); ) else if (window.attachEvent) ( window.attachEvent('onload', async_load ); ) ))();

But this is an isolated case when downloading a single file is required. Often in practice many files are connected.

Script for asynchronously loading multiple JavaScript files included

(function() ( function async_load())( [ 'URL_1.js', 'URL_2.js', 'URL_3.js' ].forEach(function(src) ( var s = document.createElement('script'); s .type = 'text/javascript'; s.async = true; document.getElementsByTagName('head').appendChild(script)); 'load', async_load, false); else if (window.attachEvent) ( window.attachEvent('onload', async_load); ) ))();

But there is a minus in this implementation - the scripts will be loaded in random order and, accordingly, they will be executed randomly in time. This asynchronous loading script is ideal if JavaScript execution files do not depend on one another and do not depend on the DOM. Otherwise, its use may lead to errors on the page or unexpected execution results. For sequential execution, but asynchronous downloading, you need to specify async=false, then the files will be downloaded in random order, but executed in turn.

The HTML 5 standard supports asynchronous loading of JavaScript. This can be done by adding keyword async or defer. For example:

.jpg" type="text/javascript" defer>

A script that is connected with the defer attribute will be executed without disturbing the order of execution in relation to other scripts and its execution will occur after full load and parsing the page, but before DOMContentLoaded is called.

A script that is connected with the async attribute will be executed as soon as possible after it has been fully loaded, but it does not wait for the document parsing to finish and before the window object is loaded. Browsers do not guarantee that scripts will be executed in the same order in which they are connected.

Libraries for asynchronous JavaScript loading

RequireJS is a JavaScript loading module. Optimized for browsers, but it can be used in other environments such as Node, Rhino.

require(["script"], function(script) ( console.log("start after load script.js"); ));

extsrc.js is a library that runs scripts to be executed after the page is loaded and displayed to the user. Works correctly with document.write.

.jpg">.jpg">

yepnope.js - allows for asynchronous loading of JavaScript and CSS files.

yepnope([ 'script.js', 'style.css' ]);

An easy way to load JavaScript scripts

It turns out that in practice, achieving optimal cross-browser loading of JavaScript scripts that do not block display is difficult, and sometimes impossible..jpg"> to the end of the document before closing body tag. Due to restrictions different browsers and HTML itself, such a loading option that does not block display can be considered the simplest.

Google PageSpeed: CSS styles and JavaScript scripts blocking page loading on WP

This post will assume that you are familiar with Google tool to optimize site page loading speed - PageSpeed ​​Insights. Listen, right now enter your website there and click the “Analyze” button.

Okay, now what is this post about?

It is quite possible that in the results of checking your site there is an item “Eliminate render-blocking JavaScript and CSS in above-the-fold content”.

I noticed that this point is one of the most intractable (time-consuming) and is present on almost all sites, even very fast ones.

How to fix it in theory:

  • We combine all the JavaScript files and place what we got before the closing tag of the site.
  • We combine all the CSS, put it right in front of the JavaScript that we have already moved, then select from them those styles that are necessary for the correct display of the page, and especially its top part (the first screen) and place them in a tag in the site.
  • How does this work in practice, and in this particular case - for WordPress sites?

    1. Let's take advantage of the dependence of other scripts on jQuery

    In correctly concocted WordPress theme all CSS and JS files are connected via wp_head() and wp_footer() - that is, at and at the end, respectively.

    Also, the files have dependencies, that is, for example, the plugin must be connected after, which means that if jQuery library is in wp_footer(), then FancyBox can’t get into wp_head().

    Moving jQuery to the site footer

    This is done very simply - using the functions wp_deregister_script(), wp_register_script(), wp_enqueue_script() and a hook (sometimes a hook is used in conjunction with is_admin()). All you need to do is paste the following code into your website file.

    I would like to draw your attention to the fact that this automated solution, and although it works in almost 100% of cases, it happens that some scripts do not want to be transferred to the site footer. Then you will need to be more attentive to each of your JavaScript files.

    This is where our work with JS ends, of course, merging scripts will also give a speed boost (that is, you unregister them all and then simply connect your combined version) - but Google no longer requires this.

    2. Combining CSS in WordPress

    If combining all JavaScript into one file is not always good idea, then I would recommend combining CSS whenever possible.

    Remember the screenshot at the very beginning of the article ( 10 blocking CSS resources)? Where do so many style files come from, since the theme developer probably knew what he was doing?

    The answer is from plugins.

    For example, the plugin Contact Form 7" includes its own style sheet, and although it is not large in itself, it is still better to avoid unnecessary HTTP requests.

    Let's look at how step by step.

  • Copy the contents of the plugin's style sheet and paste it at the end of the main style file - .
  • Check whether these styles contain relative links to images, for example. If yes, then either replace them with absolute ones, or move the images from the plugin to the theme folder.
  • Go to the plugin settings and see if there is an option to uncheck the box somewhere and not include the plugin’s CSS. There is no such option in Contact Form 7, which means we move on to the next point.
  • We chop off files via. For Contact Form 7 styles the code will be as follows:
  • Also, sometimes using conditional tags, plugin files (both CSS and JS) are disabled only from those pages where they are not used.

    Ok, we’ve sorted out Contact Form 7, but how can you find out the IDs of the CSS files of other plugins?

    It's easy, let's open it source page and we see a similar picture there:

    There is also a plugin that will allow you to combine CSS and JavaScript automatically - JS & CSS Script Optimizer.

    If you have any questions or I forgot to mention anything in this article, please leave a comment.

    How the browser loads the page

    The browser loads the page sequentially. This is especially true for external links for files - css and javascript. Let's take for example a block for the site lesnoy.name.

    Blog of Lesnoy Vladislav

    This site only loads three external files.

    2 of them - css styles, and one is a js file. But this is an example of a simple site, often dozens of external files are loaded and this significantly affects the page loading speed.

    Speed ​​up page display in the browser

    Everything would be fine, but the main problem is that the browser works as follows: when it encounters a link to an external file, it downloads and processes it, pausing rendering of the rest of the page.

    That is, from the example above it is clear that the browser will load the site title (title), then encounter a link to external css main.css file and will go to load it. After loading, it processes it and moves on - it encounters the second css file, again postpones processing the page until later and works with prettify.css. Same with prettify.js. And only then does it begin to display the rest of the page, already applying all the previously processed CSS rules from css files and js-col from javascript file ov.

    If the Internet is slow or large quantities external files, the time between going to the page and rendering it can reach tens of seconds, or even more than a minute. But isn’t it possible, while external files are loading, to display the text from the page that the visitor actually came for?

    Of course it is possible. The most banal, but no less effective method— transfer of all non-priority external files from the site header to the footer. Those. from the head block as close to the tag as possible.

    By non-priority files I mean those that are not critical to functionality or appearance site. Good way divide a large css or js file into two - the first small one stores what should load as quickly as possible and is placed in the head section, and the second and voluminous one contains everything else and is located as low as possible in the html code of the page without affecting page content display speed.

    But with the advent of html5 you can do it easier and more beautiful. The script tag has an async and defer parameter added.

    async attribute

    The script async attribute makes loading js files asynchronous. Those who know how to program in JS know exactly how it is - asynchronously. For those who don’t know how, I’ll tell you: the browser encounters a link to an external javascript file (script tag with the src parameter), begins loading and processing it, but does not stop loading and processing the main page.

    Those. does this in parallel. Just what we need! And at the same time, there is no need to move this tag to the footer (especially not in all CMS systems this is easy to do).

    Disadvantage of the async attribute

    For asynchronous loading of a js file, asynchrony is both a plus and a minus. After all, file sizes are most likely different, and the speed of downloading and processing files is also not deterministic. This means that when loading several files asynchronously, there is no guarantee that a file that starts loading later will not end up loading earlier (mainly due to its size).

    IN in this example I can't say exactly what the execution sequence of these js files will be. All I can say for sure is that script4 will load after script3 due to the lack of an async attribute. But I don’t know which file from script1.js, script2.js and script5.js will load first, because they are loaded asynchronously.

    Insert/edit link

    “And what difference does it make to us?” - you ask. But it appears if the execution of one js script depends on another. This happens all the time now, and the simplest example of such a dependence is jQuery.

    IN in this case there is a very high probability of receiving JavaScript errors due to the fact that any of jQuery plugins will start executing before jQuery itself loads.

    What to do?

    defer attribute

    This is where another attribute of the script tag comes to our rescue - defer.

    Deferred to be transferred from in English as "deferred".

    Respectively deferred javascript load- lazy loading javascript. If the browser encounters a defer attribute on a link to an external js file, it defers loading and executing these files until the entire page has been loaded and displayed. At the same time, it guarantees the same order of script execution, which was originally set in the html code.

    Accordingly, in our example with jQuery and its plugins, defer helps us out by performing two tasks: the page display time is significantly reduced (the browser does not block the rendering of the page for loading js files, it postpones loading until later) and at the same time we get rid of possible errors related to asynchronous loading of mutually dependent js files.

    In the example above, the other_script.js script will load asynchronously, because it does not depend on any other file, and jQuery and its plugins will be loaded immediately after the page is rendered in the following order: first jquery.min.js, then in order plugin1.jquery.js, plugin2.jquery.js, plugin3.jquery. js.

    As a result, with the advent of html5 and the defer and async attributes, we can control the loading order of external js files much more flexibly, thereby increasing the speed of web page rendering. And, most importantly, the user will get the impression of a significant increase in the loading speed of the entire website as a whole, because in just a few seconds he will see what he came to the site for - information.

    If you have ever thought about problems with the page loading speed of your website, then you are probably already familiar with such a service from Google as PageSpeed ​​Insights. And if so, then you are probably familiar with the problem when the main content of the page is loaded after certain scripts and styles have been loaded.

    Google, in turn, is trying to poke its nose into this disgrace and offers its own solution to the problem - Delete JavaScript code and CSS that blocks the top of the page from being rendered.

    What to do about it? Of course, you can go the most labor-intensive way, but in an effective way– go through the entire Joomla engine, make changes to extensions, and so on. This method is really good, but to be honest it is so labor-intensive that there is no desire to mess with it, and for beginners this method is not at all an option.

    The simplest and no less the right way This is to use certain extensions that will do all (or almost all) the work for us. One of these extensions is the Javascript Async & Defer plugin, with which you can run scripts asynchronously or delay their launch, but provided that this does not harm the operation of the site.

    First you need to download the Javascript Async & Defer plugin and then install it. But installation alone will not be enough, the main thing is to configure it correctly this extension. I will now try to explain how to do this.

    Settings Javascript plugin Async and Defer

    After installing the plugin, you can start configuring it, because it will not be able to configure itself. To do this, in the control panel, go to the “Plugin Manager: Plugins” page (Extensions -> Plugins). We just found installed extension in the form of the “Javascript Async and Defer” plugin.

    As you can see, the plugin is disabled by default, but as I said, one enable for proper operation won't be enough. Let's open the editing plugin and see what we have. And we have no less than just one “Plugin” tab with a few settings.

    In the plugin settings we see a message from the developers, which tells us that this plugin will add asynchronous or delayed launch tags to the specified scripts. But there is also a warning that setting up this plugin is best done by experts and with caution, otherwise errors in the operation of the site are possible.

    First, let's figure out what and how to configure here, how to find out which scripts are launched and how to register them. First, let's look at the essence of each setting:

    – this switch makes it possible to load scripts in asynchronous mode.– lazy loading of specified scripts
  • Scripts to modify – you must enter in this text field relative path to the scripts that we will process.
  • Debug – debugging mode, useful for identifying scripts that are run before loading content.
  • The first thing we need to find out is what scripts are launched when a particular page is loaded; for this we need to use the “Debug” debugging mode. In this mode on the site in the region system messages(notifications) a list of scripts that are loaded along with the page will be displayed.

    But not everything is so simple, to be honest, this very list will be displayed only if you specify at least one script to modify in the Scripts to modify field. But what if you don’t know what script to indicate there? It’s okay, for starters, you can write anything in this field, any word or symbol, then turn on the debugging mode, activate the plugin and save the result.

    Now you can go to the site and look at the result.

    The easiest option is to copy all the scripts that the plugin gave us and add them to the “Scripts to modify” field for modification. Then select the loading mode (asynchronous, delayed, or both), save the changes and check the result.

    But in this case, you will inevitably notice some errors on the site, for example, pop-up windows that do not work correctly, and so on. This is due to the fact that the page loaded before certain scripts were executed, and therefore the functions for which they are responsible will not work.

    The main thing here is not to panic, carefully study the list of scripts to understand what each of them is responsible for and modify only those that will not violate the functionality of the site.

    Most (if not all) modern websites use Javascript. Buttons social networks? Plugins? Even templates! 99% of the time these components will use Javascript. This means that your sites use scripts. But scripts slow down the speed of the site. Today we want to introduce you to 2 plugins that will take care of this problem.

    Asynchronous and deferred... what?

    Before we begin, there are three things you should consider:

  • Parser is HTML in loading stage
  • Net is the time it takes for your script to load
  • Execution is the time during which the script is fully loaded to work in the browser.
  • As part of the normal operating environment of a website, HTML parsing is suspended while scripts are running. If your site is like mine, then this means that the user will have to wait a bit (for your code, design, content, etc.) to load before they can use your site. Let's take a look at what a typical script loading looks like:

    Lazy loading simply allows your HTML code load before the scripts start running. The advantage here is that the site will instantly be displayed in the browser window, as if demonstrating lightning-fast performance. Personally, I recommend using lazy loading if some of your users are using browsers that don't support asynchronous loading of scripts. Let's take a look at how lazy loading works:

    Asynchronous loading of scripts is best option. HTML parsing and script loading will continue, but script execution will only be possible when all loading is complete. This will allow you to present your site content to your visitors as quickly as possible. However, not all browsers support asynchronous loading of scripts. Let's take a look at how asynchronous loading works:

    • I certainly recommend that you optimize your scripts using both methods.

    When using these attributes, 3 modes will be available to you. If you use the async attribute, the script will be executed asynchronously as soon as possible. If you don't use the async attribute, and use defer instead, the script will be executed when the page has finished parsing. If you don't use any of these attributes, the script will load and execute instantly, even before the browser starts parsing the page.

    Where to begin?

    So if Asynchronous javascript is the best option, let me introduce you best WordPress plugin for asynchronous Javascript loading. Who would have thought that it was called !

    Download it, install it and you are ready to go! However, it will conflict with some plugins, especially if you use sliders. In settings WordPress templates often such a function is present. You can exclude scripts that should load instantly.

    Next, I would like to move on to lazy loading of Javascript. I've looked into plugins and found that plugins with exact name matches work best. The best plugin in this category seemed to me called .

    Download it, install it, and it will start working without any settings, because it simply doesn’t have any. It will automatically launch for those users whose browsers do not support asynchronous javascript loading. I decided to keep this post as short as possible, but at the same time I presented you with truly the most best plugins to optimize the operation of scripts on your sites.

    Now I will tell you about in an interesting way, which will help you speed up your WordPress site by loading scripts in parallel.

    What is it for?

    Everything is very simple. A modern website is a collection of a wide variety of scripts, tags, snippets, styles, fonts and everything else. As you understand, the more “goodies”, the longer it takes for your site to load. As for JavaScript, that's a different matter. Have you ever noticed such a jamb when the page seems to have loaded, but the tab shows that the page is still loading? This happens when a particular script has not loaded to the end. It would be fine, sometimes the page is completely idle until that same, seemingly not very important script is loaded. And your users simply may not have enough patience.

    This concept completely opposite to synchronous loading, which is a regular script like:

    Asynchronous call the script looks like this:

    Now scripts will not force your users to wait for their full loading, everything will happen in parallel.

    How to automate the process?

    It’s clear that if you connect scripts manually and there are not many of them, then you can do this manually, simply by adding the appropriate attribute to the call code. But how can you automate this if, for example, you have WordPress with a bunch of scripts that, in addition, are called automatically?

    Find the already familiar functions.php file of your theme and insert the following code there (for example, at the end):

    // asynchronous javascript function wcs_defer_javascripts ($url) ( if (FALSE === strpos($url, ".js")) return $url; if (strpos($url, "jquery.js")) return $url; return "$url" async="async"; ) add_filter("clean_url", "wcs_defer_javascripts", 11, 1);

    Conclusion

    What can I add in conclusion? This script may not be suitable for everyone, because who knows what scripts you have connected, so install it and experiment. There can be no downside to such a script, except perhaps incompatibility with a specific site due to its specifics. This was another small step towards big optimization of your website.