Разница между async и defer у тега script

What do defer and async mean?

By default, a tag is evil! The browser must halt parsing the HTML until the script is downloaded and executed (since the script might call or define global variables that later scripts depend on). This means that any images and stylesheets that are after the script tag don’t start downloading until after the script has finished downloading and executing. External scripts typically make the Web load much more slowly, which is why NoScript has become so popular.


Microsoft introduced to solve the problem. If you use , you promise not to call . A external script will start downloading immediately but won’t execute until after the page is rendered. After the page has rendered, all scripts are executed in the same order that they were declared. Not all browsers implement yet.

HTML5 introduced the attribute which may execute any time—possibly before the page has finished parsing or even before other / scripts that are still downloading. But it’s harder to use multiple scripts because their execution order is not guaranteed. Like , not all browsers implement yet.

After all and scripts have executed, the and events fire.

de•fer1

(dɪˈfɜr) v.t. -ferred, -fer•ring. 1. to postpone; delay. 2. to exempt temporarily from induction into military service. [1325–75; Middle English deferren, variant of differren to differ] de•fer′rer, n. syn: defer, delay, postpone imply keeping something from occurring until a future time. To defer is to decide to do something at a more convenient time in the future; it often suggests avoidance: to defer making a payment. delay is sometimes equivalent to defer, but it usu. suggests a hindrance or dilatory tactic: Completion of the work was deferred by bad weather. To postpone is to put off to a particular time in the future, often to wait for new information or developments: to postpone a trial.

So what should a web developer use?

There’s no single rule to follow at this time. You have to choose the solution that best balances simplicity, page render latency, and script execution latency for the set of browsers that access your website.

  • The simplest way to have the page render before the scripts execute, as others have pointed out, is to put your scripts at the bottom of the page. But if the scripts are essential, or the webpage contains lots of HTML, then you should put your scripts higher up on the page.
  • If your script is standalone and your customers use IE or new versions of Firefox, use : This allows rendering to continue in parallel to script downloading for IE and the newest HTML5 browsers but causes pre-HTML5 browsers (including all versions of Opera) to block.
  • If one external script depends on another, mark them both (but not ) and they will be executed in the order that they were declared (except IE<=9 in certain conditions can execute them out of order). Again, this allows rendering to continue in parallel to script downloading in IE and HTML5-aware Gecko/Webkit, but older browsers and Opera will suffer. It’s a good idea to use even if the scripts are at the bottom of the page so that they download in parallel with each other.
  • Never use for inline scripts because the HTML5 draft has taken away the execution order guarantee.
  • If your audience includes many Opera or old Firefox/Safari users, the following snippet will execute the script after parsing the document on most pre-HTML5 browsers (IE, Webkit, need to test old Firefox), while the newest HTML5-aware browsers start downloading immediately but won’t block to execute the script because of the attribute. In other words, most older browsers treat it like a script at the bottom of the page, and newest browsers recognize the . But Opera users get the worst of both worlds, because Opera begins execution immediately and doesn’t understand . This is the pattern recommended by Google Analytics for the urchin on many webpages.

snippet:

  • If another script depends on the first script to load, then you can use the same pattern as above, but listen to the onload event of the first script element before executing the second script. See the LABjs example for how to wait for another script to load.
  • If you have multiple scripts with complicated dependencies, use LAB.js or the YUI Loader to make them download in parallel and execute in some valid order.
  • If you’re using a popular library such as jQuery, consider using Google’s copy rather than your own to increase the likelihood that the browser has already cached it.

async

The attribute means that a script is completely independent:

  • The page doesn’t wait for async scripts, the contents is processed and displayed.
  • and async scripts don’t wait each other:
    • may happen both before an async script (if an async script finishes loading after the page is complete)
    • …or after an async script (if an async script is short or was in HTTP-cache)
  • Other scripts don’t wait for scripts, and scripts don’t wait for them.

So, if we have several scripts, they may execute in any order. Whatever loads first – runs first:

  1. The page content shows up immediately: doesn’t block it.
  2. may happen both before and after , no guarantees here.
  3. Async scripts don’t wait for each other. A smaller script goes second, but probably loads before , so runs first. That’s called a “load-first” order.

Async scripts are great when we integrate an independent third-party script into the page: counters, ads and so on, as they don’t depend on our scripts, and our scripts shouldn’t wait for them:

In Conclusion

By now, you know the answers to the questions “How can I make JavaScript load faster?” and “What is JavaScript defer?”

You also know how to defer parsing of JavaScript or to defer loading of JavaScript WordPress files. Not only that, but you can resolve the “remove render-blocking JavaScript” and “eliminate render-blocking resources” WordPress site results in page speed diagnostic tools.

You’re ready to speed up your WordPress site.

Were you able to successfully defer parsing of JavaScript or defer loading of JavaScript WordPress files? Were you able to resolve the “eliminate render-blocking resources” WordPress site warning? Share your experience in the comments below.

July 15, 2020

Taking care of your website’s performance is a key point to take your online business to the next level. To do so, you need a cache and performance optimization plugin like WP Rocket.

Last updated on July 13, 2020

PHP accelerators substantially improve the performance of PHP-based software such as WordPress. In this article you’ll learn how PHP accelerators work, why you need them, which PHP accelerators are the best for your WordPress site, and how you can install and configure them.

July 7, 2020

Confused by what cache-control HTTP headers are? In this post, we’ll explain what they are, how they work, and how they connect to WordPress.

Last updated on June 22, 2020

Do you want to get started with setting a performance budget for your site? Our tutorial will tell you how to do that in 4 steps and achieve your business goals efficiently.

June 9, 2020

Redis Full-Page Cace vs NGINX FastCGI Cache: Which is faster? They both have their pros and cons, but there’s only one winner. Find it out with now!

Last updated on May 22, 2020

Caching isn’t just for static sites anymore. There are many options to cache highly dynamic WordPress sites. While it requires some configuration and tweaks initially, the final result is worth the effort. Check our guide to learn how to do it.

То же самое с Deferred


Аналогичный пример с объектом выглядел бы так

function vote(id) {
	var deferred = sendData("http://site.ru/vote.php", id)
	deferred.addCallback(processResult)
	deferred.addCallback(updateVoteInfo)

	deferred.addErrback(handleError)
}



function sendData(url, data) {	
	var xhr = new XmlHttpRequest()
	xhr.open("POST", url, true); 
	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

	var deferred = new Deferred()

	xhr.onreadystatechange = function() {
		if (xhr.readyState==4) {
			if (xhr.status==200) {
				deferred.callback(xhr.responseText)  
			} else {
				deferred.errback(xhr.statusText)
			}
		}			
	}

	xhr.send("data="+encodeURIComponent(data))

	return deferred
}


function processResult(data) {
	var data = eval( '('+data+')' )
	showMessage(data.text)         
	return data
}

Смысл объекта — состоит в исключении всей асинхронности из кода. Асинхронностью занимается объект . А сам код становится проще, понятнее и позволяет легко организовывать цепочки асинхронных вызовов.

Changelog

2.20.03.01

  • extra security measure; check the nonce when saving settings/ going through wizard.
  • wizard: if something fails then communicate this onscreen instead of on the console.
  • autoptimize integration: change copy to explain this might or might not be helpful.

2.18.12.10

  • the “happy birthday to me” edition
  • new: added option to disable Async JS for logged in users
  • new: added option to disable Async JS on shop cart/ checkout pages (woocommerce, edd & wp ecommerce)
  • added ‘settings’-link to plugin overview screen (hi Mike!)
  • updated the chosen JS library to 1.8.7
  • confirmed working with WordPress 5.0

2.18.04.23

  • Re-arrange content on the different tabs of the settings page.
  • Continued refactoring of backend code, no functionality should be affected.
  • Remove all images from the project such as the animated hands and progress bar gif.
  • Remove empty rows that added unnecessary space.
  • Switch buttons to use WordPress button styles.
  • Fix broken Dashboard Widget from 2.18.03.15 and reduce font-size to fix text overflow.
  • Remove all CSS !important declarations for easier CSS styling.
  • Remove inline CSS styles.
  • Switch to a CSS based progress bar.
  • Spell check readme.
  • Remove almost all tables from files.
  • Refactor JavaScript.
  • Add wormeyman as a contributor (thanks man!).

2.18.03.15

  • bugfix: only load asyncjs’ JS & CSS on own settings page as reported by Marat Petrov
  • bugfix: check if jQuery chosen is correctly loaded before using it (based on same report, thanks Marat!)
  • update jQuery Chosen lib
  • small readme tweaks

2.18.03.10

  • ASync JS is now maintained by Frank Goossens (Optimizing Matters), thanks for the great job done David!
  • Moved all Pro features into the standard version.
  • Some code refactoring
  • Made strings ready for translations

2.17.05.08

  • NEW: Added quick settings buttons to allow common settings to be quickly applied
  • NEW: Added current version info to help page

2.17.05.06

MOD/FIX: On some WordPress installs is_plugin_active function being called too early. Moved is_plugin_active into a dedicated function called via admin_init as per codex: https://codex.wordpress.org/Function_Reference/is_plugin_active

Использование defer для очистки ресурсов

Использование для очистки ресурсов часто применяется в Go. Вначале рассмотрим программу, которая записывает строку в файл, но не использует для очистки ресурсов:

main.go

В этой программе имеется функция , которая вначале пытается создать файл. При возникновении ошибки функция выводит сообщение об ошибке и закрывается. Затем она пытается записать строку в указанный файл. При возникновении ошибки функция выводит сообщение об ошибке и закрывается. Затем функция пытается закрыть файл и вернуть ресурс в систему. В заключение функция возвращает значение , подтверждая выполнение функции без ошибки.

Хотя этот код работает, в нем есть небольшая ошибка. Если вызов не обрабатывается надлежащим образом, функция прекращает работу без закрытия файла и возврата ресурса в систему.

Эту проблему можно решить, добавив еще одно выражение , которое позволит решить проблему без использования :

main.go

Теперь программа закроет файл, даже если вызов не будет обработан надлежащим образом. Хотя эту ошибку было относительно легко найти и исправить, в более сложной функции ее можно было и пропустить.

Вместо добавления второго вызова мы можем использовать выражение , чтобы вызывать вне зависимости от хода выполнения функции.

Вот версия, использующая ключевое слово :

main.go

В этот раз мы добавили строчку кода: . Это указывает компилятору, что функцию нужно выполнить перед выходом из функции .

Теперь программа всегда будет очищать ресурсы и закрывать файл, даже если мы добавим дополнительный код и создадим другое ответвление кода с выходом из функции.

Однако, добавив defer, мы внесли в код еще одну ошибку. Мы больше не проверяем ошибки, которые может возвратить метод . Это связано с тем, что при использовании нет способа передать в функцию какое-либо возвращаемое значение.

В Go считается безопасным и приемлемым вызывать функцию несколько раз, и это не повлияет на поведение программы. Если возвратит ошибку, это произойдет при первом вызове. Это позволит нам явно вызвать эту команду на успешном пути выполнения нашей функции.

Теперь посмотрим, как мы можем вызов и при этом сообщить об ошибке, если она возникнет.

main.go

Единственное изменение этой программы мы внесли в последнюю строку, где мы возвращаем . Если при вызове возникает ошибка, она будет возвращена вызывающей функции, как и ожидается. Необходимо помнить, что выражение также будет выполняться после выражения . Это означает, что функция может быть вызвана дважды. Хотя это не идеально, эта практика является допустимой, поскольку она не создаст никаких побочных эффектов для вашей программы.

Если ошибка возникнет раньше, например при вызове , функция выведет сообщение об ошибке и попытается вызвать , поскольку это отложенная команда. Хотя может также возвратить ошибку, и скорее всего это произойдет, нам больше не нужно беспокоиться о причинах, поскольку сообщение об ошибке укажет на них.

Мы посмотрели, как использовать одно выражение для правильной очистки ресурсов. Далее мы посмотрим, как использовать несколько выражений для очистки нескольких ресурсов.

JavaScript

JS Array concat() constructor copyWithin() entries() every() fill() filter() find() findIndex() forEach() from() includes() indexOf() isArray() join() keys() length lastIndexOf() map() pop() prototype push() reduce() reduceRight() reverse() shift() slice() some() sort() splice() toString() unshift() valueOf()

JS Boolean constructor prototype toString() valueOf()

JS Classes constructor() extends static super

JS Date constructor getDate() getDay() getFullYear() getHours() getMilliseconds() getMinutes() getMonth() getSeconds() getTime() getTimezoneOffset() getUTCDate() getUTCDay() getUTCFullYear() getUTCHours() getUTCMilliseconds() getUTCMinutes() getUTCMonth() getUTCSeconds() now() parse() prototype setDate() setFullYear() setHours() setMilliseconds() setMinutes() setMonth() setSeconds() setTime() setUTCDate() setUTCFullYear() setUTCHours() setUTCMilliseconds() setUTCMinutes() setUTCMonth() setUTCSeconds() toDateString() toISOString() toJSON() toLocaleDateString() toLocaleTimeString() toLocaleString() toString() toTimeString() toUTCString() UTC() valueOf()

JS Error name message

JS Global decodeURI() decodeURIComponent() encodeURI() encodeURIComponent() escape() eval() Infinity isFinite() isNaN() NaN Number() parseFloat() parseInt() String() undefined unescape()

JS JSON parse() stringify()

JS Math abs() acos() acosh() asin() asinh() atan() atan2() atanh() cbrt() ceil() cos() cosh() E exp() floor() LN2 LN10 log() LOG2E LOG10E max() min() PI pow() random() round() sin() sqrt() SQRT1_2 SQRT2 tan() tanh() trunc()

JS Number constructor isFinite() isInteger() isNaN() isSafeInteger() MAX_VALUE MIN_VALUE NEGATIVE_INFINITY NaN POSITIVE_INFINITY prototype toExponential() toFixed() toLocaleString() toPrecision() toString() valueOf()

JS OperatorsJS RegExp constructor compile() exec() g global i ignoreCase lastIndex m multiline n+ n* n? n{X} n{X,Y} n{X,} n$ ^n ?=n ?!n source test() toString() (x|y) . \w \W \d \D \s \S \b \B \0 \n \f \r \t \v \xxx \xdd \uxxxx

JS Statements break class continue debugger do…while for for…in for…of function if…else return switch throw try…catch var while

JS String charAt() charCodeAt() concat() constructor endsWith() fromCharCode() includes() indexOf() lastIndexOf() length localeCompare() match() prototype repeat() replace() search() slice() split() startsWith() substr() substring() toLocaleLowerCase() toLocaleUpperCase() toLowerCase() toString() toUpperCase() trim() valueOf()

18.1 Introduction to scripts

script

Scripts offer authors a means to extend HTML documents in highly active and interactive ways. For example:

  • Scripts may be evaluated as a document loads to modify the contents of the document dynamically.
  • Scripts may accompany a form to process input as it is entered. Designers may dynamically fill out parts of a form based on the values of other fields. They may also ensure that input data conforms to predetermined ranges of values, that fields are mutually consistent, etc.
  • Scripts may be triggered by events that affect the document, such as loading, unloading, element focus, mouse movement, etc.
  • Scripts may be linked to form controls (e.g., buttons) to produce graphical user interface elements.

There are two types of scripts authors may attach to an HTML document:

  • Those that are executed one time when the document is loaded by the user agent. Scripts that appear within a element are executed when the document is loaded. For user agents that cannot or will not handle scripts, authors may include alternate content via the element.
  • Those that are executed every time a specific event occurs. These scripts may be assigned to a number of elements via the attributes.

Note. This specification includes more detailed information about scripting in sections on .

The Fix: Defer and Async your JavaScript


The first thing to understand is the alternatives to render-blocking JS: and . We’ll explain the difference, but both work similarly: They let the browser load a JS resource “as time permits,” while attending to other things (like page rendering) as well. This means that you can’t rely on a deferred or asynced JavaScript file being in place prior to page render, as you could without these attributes—but the advantage is that the file won’t slow the speed at which the page becomes visible to users.

Those are concepts—now for code. (The full code is available on GitHub.)

1. Getting Your Script Handles

Every properly enqueued WordPress script has a handle: a “nickname” that the site knows to call it by. We’re going to need these handles for all scripts, and getting them isn’t dead-simple, unfortunately.

It is possible, though:

This code prints out a list of enqueued handles, separated by , right into the of every page:

You’ll only do this once, then use “View Page Source” to copy and paste the handles themselves.

Once you’ve done this, deactivate this section of the code: we’ve got our handles, so let’s not clog up our with them anymore. That’s why this section is commented out in the code on GitHub—I don’t want it to run every time!

2. Deferring and Asyncing Render-Blocking JavaScript

We found that we needed to use and not  for WPShout, so I’ll walk through the code. Most of the heavy lifting here is from an article by Scott Nelle; thanks, Scott!

The line tells us that this code should run anytime an enqueued JavaScript file is about to be printed onto the page as an HTML element. Letting us filter that HTML is what is for. (If you need an update on filters and WordPress’s hooks system in general, start here!)

The biggest check in this code is doing a single thing defining the array. This array lists out the handles of all the elements we want to defer—the handles we found in step 1. (Your handles will, of course, vary!)

The logic below the array definition (beginning with ) searches for the current script’s handle attribute in the array we’ve just defined. If the handle matches an element in the array, then we modify the script to have the same source, but with a new property: , which will cause the script not to block rendering. With this change made, we the HTML back, and we’re good to go!

(And finally, if the handle isn’t found, we just return the original tag itself, unaltered.)

You’ll know this plugin is working when you view page source and see something like this in the :

When to Use Async Instead of Defer

You use when you’re linking directly to an external JavaScript library. That link would look something like: . Notice how it’s a link to the full URL, and the JavaScript will get pulled in

ing external JS is a lot less common, at least for us, since most of our enqueued JS is in themes and plugins that host their own code. At any rate, the code for is precisely the same as the code for —but with the two words switched out. So if you do happen to have a lot of externally hosted d scripts, getting them ed is a very similar technical process to the one we’ve just covered.

Which Scripts to Defer and Async

You’ll notice that we didn’t defer everything—a few scripts are still render-blocking. Here are rules of thumb on that:

  • Don’t do anything to jQuery. jQuery (handle ) is a key dependency for many other JS files, and you want to let it load early.
  • Any file that’s wrapped in a  call should be fine to defer. That code basically says “Wait until the entire document object model (DOM) loads,” so racing to get the JavaScript file loaded in the head doesn’t serve much purpose.
  • In general, you can defer JavaScript files that rely on user interactions, like clicks and mouse hovers—and files that fix layout details, like center or hide a set of element. Again, these rely on a loaded page to work anyway (which is why they’re almost all going to be wrapped in , or else they’re liable not to work), so you should be safe to get the page out beforehand.
  • It’s, unfortunately, impossible to use this method for JavaScript files that have been added some way other than the generally correct method of ing them. This is another reason to prefer that method over other ways of loading scripts that may appear to work fine at first glance.

Using a Plugin to Safely Defer Parsing of JavaScript

If you’re not keen on adding the code you need to defer parsing of JavaScript or to defer loading of JavaScript WordPress files, then you can use a plugin.

The trick is, many options out there can break your site. One reason is because you have to manually decide which files to defer. You may defer parsing of JavaScript files that are critical which would cause errors.


But, if you use WP Rocket, you can safely and appropriately defer JavaScript files in a couple clicks.

It also has the added benefit of helping your site load faster.

After installing the plugin, everything’s already set up for you and you can defer files. There’s an option to defer loading of JavaScript WordPress files instead of only letting you defer parsing of JavaScript.

Go to Settings > WP Rocket.

Then in the WP Rocket menu, click on the File Optimization tab.

You can optimize your site’s speed in many ways with WP Rocket.

Under JavaScript Files, check the Load JavaScript deferred box. It’s also recommended you check the Safe Mode for jQuery box that dynamically appears underneath the former option.

If you want to deactivate Safe Mode, be sure to test the changes on a staging site before you choose the safe mode option on a production site.

Finally, click Save Changes at the bottom of the page.

Load JavaScript deferred: WP Rocket settings

If for some reason you decide you want to revert the change, you can uncheck the Load JavaScript deferred box and click Save Changes. Then, clear your site’s cache.

What It Means to Defer Parsing of JavaScript

To understand what it means to defer parsing of JavaScript or to defer loading of JavaScript, (WordPress, web apps, and other types of websites included) it’s essential to get a refresher on what parsing is first.

A Quick Reminder on Parsing

Parsing is the process of converting human-readable code, in this case JavaScript, into a language that a computer can understand. That way, the functions your code is supposed to carry out can do just that.

You can also indicate in a file that you want to load one or more separate JavaScript files when the main file runs.

This lets an ordinary site with some text and images suddenly have a lot more robust capabilities that you can code with JavaScript.

Loading Multiple JavaScript Files

In a website file, when you set JavaScript files to load, there are two main types:

  • Critical – JavaScript files that are essential to load before all other types listed below since they are crucial to the functioning of the page.
  • Non-critical – Other JavaScript files that need to be loaded on a page, but aren’t considered essential.

There is also the inline option. This refers to JavaScript that’s delivered inline in an HTML file, for example, instead of having a separate JavaScript file that’s called in the main file.

Defer Loading of JavaScript: WordPress and Other Websites

When you indicate in your code that you want to load JavaScript files, you can choose when files are parsed and even when they’re loaded. That way, you can choose to execute critical JavaScript files first and delay the execution of non-critical files, which you can set to run after the primary content on the page has been displayed.

This process is what it means to defer parsing of JavaScript, at least when execution of JavaScript files are delayed.

To defer loading of JavaScript, WordPress and other types of websites included, would mean you’re delaying the files from being loaded (and then executed) until after the rest of the page has been displayed.


С этим читают