1. какого черта
Сегодня, когда занимался мелкой нуждой, вдруг увидел код от своего предшественника, который висит на небе.
<script src="#link("xxxx/xx/home/home.js")" type="text/javascript" async defer></script>
Какого черта есть одновременноasync
а такжеdefer
Атрибут, я подумал, что это должна быть какая-то черная технология от старшего водителя, и какая-то волшебная химическая реакция обязательно произойдет вместе, поэтому я быстро перевернул книгу и документ с благоговением и сначала просмотрел их соответствующие определения.
2. Проведите исследование
Первый взглядasync
а такжеdefer
Давайте определим свои собственные, откроем телескоп с красной сокровищницей, это введение
2.1 defer
Назначение этого свойства — указать, что скрипт не повлияет на построение страницы при выполнении. То есть сценарий задерживается до тех пор, пока вся страница не будет проанализирована перед запуском. Таким образом, в
<script>
набор элементовdefer
свойство, что эквивалентно указанию браузеру немедленно загрузить, но отложить выполнение.Спецификация HTML5 требует, чтобы сценарии выполнялись в том порядке, в котором они появляются, поэтому первый отложенный сценарий выполняется до второго отложенного сценария, который, в свою очередь, выполняется до
DOMContentLoaded
исполнение события.в реальности, отложенные сценарии не обязательно будут выполняться по порядку и не будутDOMContentLoad
Выполняется до того, как сработает время, поэтому лучше просто включить сценарий задержки.
2.2 async
Это свойство связано с
defer
Точно так же оба используются для изменения поведения сценариев обработки. такой же какdefer
аналогичный,async
Работает только с внешними файлами сценариев и указывает браузеру немедленно загрузить файл. но сdefer
Разница в том, что помечено какasync
выполнение скриптов в их порядке не гарантируется.Второй файл сценария может выполняться перед первым файлом сценария. Поэтому важно убедиться, что они не зависят друг от друга. уточнить
async
Назначение атрибута — асинхронно загрузить остальную часть страницы, не заставляя страницу ждать загрузки и выполнения двух скриптов.
В двух словах, эти два свойства вызывают асинхронную загрузку тега скрипта, но время выполнения отличается. ЦитироватьsegmentfaultКартинка из ответа вышеСиняя линия представляет чтение из сети, а красная линия представляет время выполнения, как для скриптов, так и для скриптов; зеленая линия представляет
Разбор HTML.
то естьasync
вышел из строя, иdefer
выполняется последовательно, что также определяетasync
Он больше подходит для таких библиотек, как анализ Baidu или анализ Google, которые не зависят от других скриптов. Из рисунка видно, что общий<script>
Загрузка и парсинг тегов синхронизированы, что блокирует отрисовку DOM, поэтому мы часто используем<script>
написать на<body>
Одной из причин внизу является предотвращение длинного белого экрана, вызванного загрузкой ресурсов, а другой причиной является то, что js может выполнять операции DOM, поэтому он должен выполняться после полной визуализации DOM.
2.3 точно?
Однако, эта картинка (чуть ли не единственный ответ, найденный Baidu) не является строгой, это просто нормативная ситуация, и большинство браузеров будут ее оптимизировать при реализации.
Посмотрим, как это сделает хром.
«Инсайдер технологии WebKit»:
Когда пользователь вводит URL-адрес веб-страницы, WebKit вызывает свой загрузчик ресурсов для загрузки веб-страницы, соответствующей URL-адресу.
Загрузчики полагаются на сетевые модули для установления соединений, отправки запросов и получения ответов.
WebKit получает данные с различных веб-страниц или ресурсов, некоторые из которых могут быть получены синхронно или асинхронно.
Веб-страница превращается интерпретатором HTML в серию слов (токен).
Интерпретатор строит узлы из слов, формируя DOM-дерево.
Если узел представляет собой код JavaScript, вызовите механизм JavaScript для его интерпретации и выполнения.
Код JavaScript может изменить структуру дерева DOM.
Если узел должен зависеть от других ресурсов, таких как изображения, CSS, видео и т. д., вызовите загрузчик ресурсов для их загрузки, но они асинхронны и не помешают продолжению создания текущего дерева DOM; если это URL-адрес ресурса JavaScript (без пометки асинхронного метода), создание текущего дерева DOM необходимо остановить, и создание дерева DOM не будет продолжаться до тех пор, пока ресурс JavaScript не будет загружен и выполнен движком JavaScript.
так, Вообще говоря, браузер Chrome сначала запрашивает HTML-документ, а затем вызывает соответствующий загрузчик ресурсов для выполнения асинхронных сетевых запросов для различных ресурсов в нем и одновременно выполняет рендеринг DOM, пока не встретит<script>
Когда тег отображается, основной процесс останавливает рендеринг и ждет загрузки ресурса, затем вызывает движок V8 для анализа js, а затем продолжает анализ DOM. Мое понимание, если добавитьasync
Атрибуты эквивалентны открытию отдельного процесса для загрузки и выполнения независимо.defer
да и будет<script>
помещать<body>
Тот же эффект внизу.
3. Поэкспериментируйте с одним выстрелом
3.1 demo
Для проверки сделанного выше вывода проверим
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.css" rel="stylesheet">
<link href="http://cdn.staticfile.org/foundation/6.0.1/css/foundation.css" rel="stylesheet">
<script src="http://lib.sinaapp.com/js/angular.js/angular-1.2.19/angular.js"></script>
<script src="http://libs.baidu.com/backbone/0.9.2/backbone.js"></script>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
</head>
<body>
ul>li{这是第$个节点}*1000
</body>
</html>
Простая демонстрация, 2 CSS3 JS ссылаются на разные CDN, а в теле создается 1000 li. Используйте временную шкалу Chrome для проверки, изменив расположение внешних справочных ресурсов и добавив соответствующие свойства.
3.2 Место в<head>
Внутри
Асинхронно загружает ресурсы, но блокирует<body>
При рендеринге появится белый экран, скрипт будет выполнен сразу по порядку
3.3 Место в<body>
Нижний
асинхронно загружать ресурсы и т. д.<body>
После завершения рендеринга содержимого и завершения загрузки JS выполняется по порядку.
3.3 Место в<head>
голову и использоватьasync
Загружайте ресурсы асинхронно, и выполняйте ресурсы JS сразу после загрузки, не по порядку, кто быстрее, тот и пойдет первым
3.4 Место в<head>
голову и использоватьdefer
Загружайте ресурсы асинхронно и последовательно выполняйте JS после рендеринга DOM.
3.5 Место в<head>
голову и использовать обаasync
а такжеdefer
производительность иasync
Последовательны, откройте дырку в мозгу, поменяйте местами эти два атрибута, чтобы увидеть, будет ли эффект покрытия, и окажется, что они согласуются ==,
Подводить итоги, под движок webkit рекомендуемый способ все-таки поставить<script>
написать на<body>
Внизу вы можете использовать его, если вам нужно использовать независимые библиотеки, такие как Baidu Google Analytics или Buguanzi.async
свойства, если ваш<script>
Этикетки должны быть написаны на<head>
Можно использовать в головеdefer
Атрибуты
4. Совместимость
Итак, попробуйте разобраться в психологии предшественников, и в чем причина написания при этом совместимости?
на Каниусе,asyncНе поддерживается, когда IEdeferПоддерживается в IEissueВ нем есть описание, а значит, в "телескопе" рекомендовано только одноdefer
причина. Таким образом, оба свойства указаны для того, чтобыasync
Включить, если не поддерживаетсяdefer
,ноdefer
В некоторых случаях все еще есть ошибки.
The defer attribute may be specified even if the async attribute is specified, to cause legacy Web browsers that only support defer (and not async) to fall back to the defer behavior instead of the synchronous blocking behavior that is the default.
5. Вывод
На самом деле, самый безопасный способ<script>
написать на<body>
Внизу, никаких проблем с совместимостью, никаких проблем с белым экраном, никаких проблем с порядком выполнения, просто сядь и расслабься, ничего не делайdefer
а такжеasync
цветок~
В настоящее время изучается только механизм рендеринга веб-кита Chrome. Необходимо дополнительно изучить Firefox и IE. Необходимо изучить рендеринг изображений, CSS и других внешних ресурсов.
Больше информации наздесь