(Товары для галантереи) Запишите вопросы интервью фронтенд-инженеров и попросите всех вместе их понять.

сервер HTTP JavaScript браузер

Эта статья предыдущая. Как получить вопросы для интервью о большом заводском предложении | Техническое эссе. Затем обновите оставшиеся вопросы и ответьте на идеи.

1. Пожалуйста, кратко опишите формат состава сообщения запроса и сообщения ответа протокола http?

Сообщение HTTP-запроса

Сообщение HTTP-запроса состоит из четырех частей: строки запроса, заголовка запроса, пустой строки и данных запроса.На следующем рисунке показан общий формат сообщения запроса.

Английский:





<пустая строка>


1. Заголовок запроса

Строка запроса состоит из трех полей: поля метода запроса, поля URL и поля версии протокола HTTP, разделенных пробелами. Например, GET /index.html HTTP/1.1.

Методы запроса протокола HTTP включают GET, POST, HEAD, PUT, DELETE, OPTIONS, TRACE и CONNECT.

2. Заголовок запроса

Заголовок запроса состоит из пар ключевое слово/значение, по одной паре в строке, а ключевое слово и значение разделяются английским двоеточием ":". Заголовки запроса информируют сервер о клиентском запросе. Типичные заголовки запроса:

User-Agent: тип браузера, выполнившего запрос.

Принять: список типов контента, распознаваемых клиентом.

Хост: запрошенное имя хоста, несколько доменных имен могут использовать один и тот же IP-адрес, то есть виртуальный хост.

3. Пустая строка

После последнего заголовка запроса находится пустая строка, отправляющая возврат каретки и новую строку, чтобы сообщить серверу, что ниже больше нет заголовков запроса.

4. Запросить данные

Данные запроса используются не в методе GET, а в методе POST. Метод POST подходит для ситуаций, когда от клиента требуется заполнить форму. Наиболее часто используемые заголовки запроса, связанные с данными запроса, — это Content-Type и Content-Length.

HTTP-сообщение

Ответ HTTP также состоит из трех частей: строки состояния, заголовка сообщения и тела ответа.

Как показано ниже, формат ответа HTTP очень похож на формат запроса:

Английский:





<пустая строка>

Как видите, единственная реальная разница в ответе — это замена информации о запросе на информацию о состоянии в первой строке. Строка состояния описывает запрошенный ресурс, предоставляя код состояния.

Формат строки состояния следующий:

HTTP-Version Status-Code Reason-Phrase CRLF

Среди них HTTP-Version представляет версию HTTP-протокола сервера, Status-Code представляет собой код состояния ответа, отправленный обратно сервером, Reason-Phrase представляет собой текстовое описание кода состояния. Код состояния состоит из трех цифр, первая цифра определяет категорию ответа, и есть пять возможных значений.

  • 1xx: Индикационная информация — указывает, что запрос получен и обработка продолжается.
  • 2xx: Успех. Указывает, что запрос был успешно получен, понят и принят.
  • 3xx: перенаправление. Для выполнения запроса необходимо предпринять дополнительные действия.
  • 4xx: Ошибка клиента — запрос содержит синтаксическую ошибку или запрос не может быть выполнен.
  • 5xx: Ошибка на стороне сервера — серверу не удалось выполнить допустимый запрос.

Ниже приведены описания общих кодов состояния и описания состояний.

  • 200 OK: запрос клиента выполнен успешно.
  • 400 Bad Request: запрос клиента содержит синтаксическую ошибку и не может быть понят сервером.
  • 401 Unauthorized: запрос не авторизован. Этот код состояния ДОЛЖЕН использоваться вместе с полем заголовка WWW-Authenticate.
  • 403 Forbidden: сервер получил запрос, но отказался его обслуживать.
  • 404 Not Found: запрошенный ресурс не существует, например: был введен неправильный URL.
  • 500 Внутренняя ошибка сервера: на сервере произошла непредвиденная ошибка.
  • 503 Сервер недоступен: сервер в настоящее время не может обработать запрос клиента и может вернуться в нормальное состояние через некоторое время, например: HTTP/1.1 200 OK (CRLF).

Для получения подробной информации, пожалуйста, обратитесь к этомублог

2. Реализовать вертикальный эффект блок-бокса в игре тремя способами, предполагая, что высота бокса адаптируется в соответствии с содержимым.

Обратите внимание на совместимость, autoprefixer может обрабатывать только совместимость префиксов.Для браузеров, которые не поддерживают преобразование и сгибание, если вы хотите быть совместимым с этой частью браузера, выберите другие методы (большая часть того, что я делаю, это мобильные, следующие три, кроме Android 4.3. Следующие собственные ядра не поддерживают внешние и внешние ошибки совместимости, flex имеет некоторую совместимость с ядром X5 и ядром более ранней версии ios (например, flex-wrap, обратите внимание).

Первый: флекс

父元素设置以下属性
display:flex;
flex-direction:row //web 默认的值,rn默认column
align-items:center

Второй: абсолютный

父元素设置
position:relative
本元素
position:absolute;
top:50%;
transform:translateY(-50%);

Третье: используйте атрибут display:table-cell

display:table-cell;
vertical-alian:middle;

. . . Есть намного больше

3. Что означает код состояния 302 в http?

302 Redirect означает «Временно перемещено» и используется, когда URL-адрес веб-страницы необходимо изменить в течение короткого периода времени.

кстати 301

301 редиректы/переходы являются общими и указывают на то, что эта веб-страница постоянно переносится на другой адрес.

301 перемещается навсегда (Permanently Moved), распространенный шаг для SEO, который перенесет PR и другую информацию старой страницы на новую страницу.

Разница между переадресацией 301 и переадресацией 302

Перенаправление 301 — это постоянное перенаправление, при котором поисковые системы сканируют новый контент и заменяют старый URL-адрес перенаправленным URL-адресом.

302 перенаправления — это временные перенаправления, при которых поисковые системы сканируют новый контент, сохраняя при этом старые URL-адреса. Поскольку сервер возвращает код 302, поисковая система считает новый URL временным.

4. Что такое cookie и в чем разница между сеансом и сеансом

1. Сессия на стороне сервера, а куки на стороне клиента (браузера)

2. Сессия по умолчанию хранится в файле на сервере (не в памяти)

3. Работа сеанса зависит от идентификатора сеанса, а идентификатор сеанса хранится в куки, то есть если вы просматриваете

Отключенный файл cookie, сеанс одновременно завершится сбоем (но может быть реализован другими способами, такими как передача в URL-адресе

идентификатор сессии)

4 сеанс можно поместить в файл, базу данных или память.

5. В этом случае для аутентификации пользователя обычно используется сессия.

Поэтому ядром поддержания сеанса является уникальная идентификация клиента, то есть идентификатор сеанса.

5. Есть интерфейсы dom, которые могут получить размер (ширину и высоту) элемента

Предположим, что идентификатор элемента - это поле

1. Первый — через встроенные стили (примечание: если высота и ширина не заданы в объявлении css, вы не сможете его получить, и он не вернет ширину и высоту разных моделей боксов в соответствии со значением box-sizing)

    var box = document.getElementById('box');
    var w = box.style.width;
    var h = box.style.height;

2. По вычислению размера элемента (но есть проблема в случае с ie, то вернуть auto не прописав css ширины и высоты. Если getComputedStyle устанавливает единицу ширины и высоты в em под IE, то возвращаемое значение по-прежнему em, а не px);

    var style = window.getComputedStyle ? window.getComputedStyle(box,null) : null || box.currentStyle;
    var w = style.width;
    var h = style.height;


3.offsetHeight и offsetHeight

4. getBoundingClientRect (слева и сверху IE67 будут на 2 пикселя меньше, и здесь нет свойств ширины и высоты. Если вам нужна совместимость с этой частью браузера, вы должны отказаться) Объект DOMRect содержит набор свойств только для чтения для описания границы — левая, верхняя, правая и нижняя в пикселях. Все свойства, кроме ширины и высоты, относятся к верхнему левому углу окна просмотра.

. . .

6. Пожалуйста, опишите поток события dom, то есть весь процесс от срабатывания до завершения

Поток событий состоит из трех фаз: фаза захвата события, фаза на цели и фаза всплытия события. Первое, что происходит, это захват события,

Дает возможность перехватывать инциденты. Затем фактическая цель получает событие. Последняя стадия – стадия бульканья. раздел, можно найти здесь

Сцена реагирует на событие. Щелчок по элементу

будет выглядеть так:

В потоке событий DOM фактическая цель (элемент

) не получает события на этапе захвата. Это означает, что на этапе захвата

12 Событие останавливается после перехода от документа к к

. Следующим этапом является этап «у цели», поэтому

событие в

происходит в обработчике событий и считается частью фазы всплытия при обработке событий (эта концепция будет обсуждаться позже). Конечно

После того, как наступает фаза бульканья, Событие передается обратно в документ. 

Большинство браузеров, поддерживающих потоки событий DOM, реализовали определенное поведение, даже если спецификация «событие уровня DOM2» ясна.

Фаза захвата не включает цели событий, но IE9, Safari, Chrome, Firefox и Opera 9.5 и более поздние версии все это делают.

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

Выше приведено содержание возвышения.

7. Пожалуйста, опишите разницу между utf-8 и unicode

  • Юникод — это «набор символов».
  • UTF-8 - это "правила кодирования"

Юникод — это сложный набор стандартов кодирования символов, который сопоставляет каждый так называемый символ, используемый людьми, с неотрицательным целым числом и гарантирует, что целые числа, соответствующие разным символам, должны быть разными. UTF-8 — это кодировка этого целого числа, использующая от 1 до 4 байтов для выражения целого числа.

Взаимосвязь: UTF-8 — это одна из реализаций Unicode, которая определяет, как символы хранятся, передаются и т. д. в компьютере.

8. Расскажите о стратегиях оптимизации, которые вы используете в повседневной веб-разработке для загрузки и интерактивного взаимодействия.

1. Уменьшите количество HTTP-запросов

Эта стратегия в основном известна всем фронтендовцам, а также является самой важной и эффективной. Говорят, что это уменьшает HTTP-запросы, но что произойдет, если запросов будет слишком много? Во-первых, у каждого запроса есть стоимость, включая затраты времени и ресурсов. Полный запрос должен пройти «долгий» и сложный процесс адресации DNS, установления соединения с сервером, отправки данных, ожидания ответа сервера и получения данных. Затраты времени заключаются в том, что пользователю необходимо увидеть или "пощупать" ресурс и дождаться завершения процесса. Поскольку каждый запрос должен передавать данные, каждый запрос должен занимать полосу пропускания.

Кроме того, поскольку существует верхний предел количества одновременных запросов, отправляемых браузером, когда количество запросов увеличивается, браузер должен делать запросы пакетами, что увеличивает время ожидания пользователя и создает у пользователей впечатление, что Сайт работает медленно Даже если ресурсы на первом экране, который видит пользователь, были запрошены, индикатор выполнения браузера всегда будет существовать. К основным способам уменьшения количества HTTP-запросов относятся:

(1) Упростите страницу с уровня дизайна и реализации.

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

(2) Разумная настройка HTTP-кэша

Сила кэширования велика, а правильные настройки кэширования могут значительно сократить HTTP-запросы. Возьмем в качестве примера домашнюю страницу Youah, когда в браузере нет кеша, будет выдано в общей сложности 78 запросов с общим объемом данных более 600 тыс. (как показано на рис. 1.1), а при втором посещении это то есть после того, как браузер был кэширован, было всего 10 посещений запроса, всего более 20 тыс. данных (как показано на рисунке 1.2). (Здесь следует отметить, что если страница обновляется напрямую по F5, эффект другой. В этом случае количество запросов остается тем же, но сервер запросов для кэшированного ресурса — это ответ 304, только заголовок не имеет тела, что может сэкономить пропускную способность)

Что такое разумная установка? Принцип очень прост, чем больше вы можете кэшировать, тем лучше, и чем дольше вы можете кэшировать, тем лучше. Например, ресурсы изображения, которые редко изменяются, могут напрямую устанавливать заголовок с длительным сроком действия через Expires в заголовке HTTP; ресурсы, которые изменяются нечасто, но могут изменяться, могут использовать Last-Modifed для проверки запроса. Храните ресурсы в кеше как можно дольше.

(3) Консолидация и сжатие ресурсов

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

(4). CSS Sprites

Еще один отличный способ уменьшить количество запросов путем слияния изображений CSS.

(5). Inline Images

Использование схемы data: URL для встраивания изображений в страницы или CSS — хороший способ, если вы не рассматриваете вопросы управления ресурсами. Если он встроен в страницу, он увеличит размер страницы и не сможет использовать кеш браузера. Использование изображений в CSS более идеально.

(6). Lazy Load Images

Эта стратегия на самом деле не уменьшает количество HTTP-запросов, но может уменьшить количество HTTP-запросов при определенных условиях или когда страница только что загружена. Для изображений только первый экран может быть загружен, когда страница только что загружена, а последующие изображения могут быть загружены, когда пользователь продолжает прокручивать назад. Таким образом, если пользователя интересует только содержимое первого экрана, остальные запросы изображения сохраняются. Да, домашняя страница раньше кэшировала адреса изображений после первого экрана в теге Textarea при загрузке и «ленивую» загрузку, когда пользователь прокручивает экран вниз.

2. Положите внешний скрипт в самый низ

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

3. Выполняйте встроенные скрипты асинхронно

Влияние встроенных сценариев на производительность даже больше, чем влияние внешних сценариев. Домашняя страница, как и внешние скрипты, встроенные скрипты будут блокировать одновременные запросы при выполнении. Кроме того, поскольку браузер является однопоточным при обработке страницы, когда встроенные скрипты выполняются до рендеринга страницы, рендеринг страницы будет работать с задержкой. Короче говоря, когда встроенный скрипт выполняется, страница пуста. Ввиду двух вышеперечисленных причин рекомендуется выполнять встроенные скрипты с большим временем выполнения асинхронно.Существует много асинхронных методов, таких как использование атрибута defer элемента script (существуют проблемы совместимости и другие проблемы, такие как невозможность использовать document.write), Использование setTimeout, кроме того, механизм Web Workers, представленный в HTML5, может решить именно такие проблемы.

4. Lazy Load Javascript

С популярностью JavaScript Framework, все больше и больше сайтов используют рамки. Однако структура часто включает в себя много функциональности, которое не требуется для каждой страницы. Если нежелательный скрипт загружен, вычисляется, что это пустая трата ресурсов - она ​​тратит пропускную способность и тратить время., Вероятно, существуют две виды практики, чтобы настроить выделенную мини-версию для этих страниц, которые очень велики, а другая ленивая нагрузка. Yui использует второй путь. В реализации YUI только основной модуль изначально загружен, и другие модули могут быть загружены, когда их необходимо использовать.

5. Поместите CSS в HEAD

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

6. Уменьшите количество ненужных HTTP-переходов

Для HTTP-ссылок, доступ к которым осуществляется в виде каталогов, многие люди будут игнорировать наличие символа «/» в конце ссылки. Если ваш сервер обрабатывает это по-другому, вам также нужно обратить внимание. прыжок скрыт, добавляя избыточный запрос. Подробности смотрите на рисунке ниже, где доступ к первой ссылке осуществляется без окончания '/', поэтому на сервере есть переход.

7. Избегайте повторяющихся запросов ресурсов

Эта ситуация в основном из-за небрежности или того, что страница склеена несколькими модулями, и когда в каждом модуле запрашивается один и тот же ресурс, это приведет к повторным запросам ресурсов. Шансы на его появление малы, но все же стоит обратить внимание на расследование.

. . .

9. Что такое CSRF-атака и как ее предотвратить

CSRF весь процесс Подделка межсайтовых запросов, Подделка межсайтовых запросов CSRF — это метод атаки, который принуждает пользователей выполнять непреднамеренные операции в веб-приложении, вошедшем в систему. По сравнению с XSS, CSRF использует доверие системы к браузеру страниц, а XSS использует доверие системы к пользователю.

Защита от CSRF-атак:

В настоящее время существует три основных стратегии защиты от CSRF-атак: проверка поля HTTP Referer, добавление токена к адресу запроса и проверка, настройка атрибутов в HTTP-заголовке и проверка.

(1) Проверьте поле HTTP Referer

В соответствии с протоколом HTTP в заголовке HTTP есть поле Referer, которое записывает исходный адрес HTTP-запроса. В обычных условиях запрос на доступ к защищенной странице поступает с того же веб-сайта. Например, чтобы получить доступ к http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory, пользователь должен сначала войти в банк .example, а затем передать Нажмите кнопку на странице, чтобы инициировать событие передачи. В настоящее время значением Referer запроса на перевод будет URL-адрес страницы, на которой расположена кнопка перевода, обычно адрес, начинающийся с доменного имени bank.example. Если хакер хочет провести CSRF-атаку на веб-сайт банка, он может создать запрос только на своем собственном веб-сайте.Когда пользователь отправляет запрос в банк через веб-сайт хакера, референт запроса указывает на собственный веб-сайт хакера. Веб-сайт. Таким образом, для защиты от CSRF-атак веб-сайт банка должен только проверять свое значение Referer для каждого запроса на перевод.Если доменное имя начинается с bank.example, это означает, что запрос исходит от самого веб-сайта банка и является законным. Если реферером является другой веб-сайт, это может быть хакерская CSRF-атака и отклонить запрос.

Очевидным преимуществом этого метода является то, что он прост и легок в реализации, рядовым разработчикам сайта не нужно беспокоиться о CSRF-уязвимостях, им нужно только добавить перехватчик во все чувствительные к безопасности запросы в конце, чтобы проверить значение Реферера. Специально для текущей существующей системы нет необходимости менять какой-либо существующий код и логику текущей системы, нет риска, и это очень удобно.

Однако этот метод не является надежным. Значение Referer предоставляется браузером.Хотя в протоколе HTTP есть четкие требования, каждый браузер может иметь разные реализации Referer, что не гарантирует отсутствие дыр в безопасности самого браузера. Использование метода проверки значения Referer заключается в том, чтобы полагаться на третью сторону (например, браузер) для обеспечения безопасности, что теоретически небезопасно. На самом деле, для некоторых браузеров, таких как IE6 или FF2, уже есть способы изменить значение Referer. Если веб-сайт bank.example поддерживает браузеры IE6, хакеры могут полностью установить значение Referer браузера пользователя на адрес, начинающийся с доменного имени bank.example, чтобы они могли пройти проверку и провести CSRF-атаки.

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

(2) Добавьте токен к адресу запроса и проверьте

Причина успеха атаки CSRF заключается в том, что хакер может полностью подделать запрос пользователя.Вся информация об аутентификации пользователя в запросе содержится в файле cookie, поэтому хакер может напрямую использовать собственный файл cookie пользователя, не зная информации об аутентификации. проверка безопасности. Ключом к защите от CSRF является размещение в запросе информации, которую хакер не может подделать, и этой информации нет в файле cookie. В HTTP-запрос может быть добавлен случайно сгенерированный токен в виде параметра, а на стороне сервера может быть установлен перехватчик для проверки токена.Если в запросе нет токена или содержание токена неверно, считается атакой CSRF, и запрос отклоняется.

Этот способ более безопасный, чем проверка Referer.Токен может быть сгенерирован после авторизации пользователя и помещен в сессию, а затем токен выносится из сессии на каждый запрос и сравнивается с токеном в запросе, но это сложность этого метода заключается в том, как добавить токен в качестве параметра запроса. Для запросов GET токен будет добавлен к адресу запроса, так что URL-адрес станет http://url?csrftoken=tokenvalue. Для запросов POST добавьте в конце формы, чтобы токен добавлялся в запрос в качестве параметра. Однако на веб-сайте есть много мест, которые могут принимать запросы. Добавлять токен к каждому запросу очень проблематично, и его легко пропустить.Обычный метод — использовать javascript для обхода каждый раз при загрузке страницы. Для всего дерева dom добавьте токен после всех тегов a и form в dom. Это может решить большинство запросов, но для html-кода, который динамически генерируется после загрузки страницы, этот метод не работает и требует, чтобы программист вручную добавлял токен при написании кода.

Еще одним недостатком этого метода является сложность обеспечения безопасности самого токена. В частности, на некоторых форумах и других веб-сайтах, которые позволяют пользователям публиковать свой собственный контент, хакеры могут публиковать на нем адрес своего личного веб-сайта. Поскольку система также добавит токен на этот адрес, хакеры могут получить этот токен на своем собственном веб-сайте и сразу же запустить CSRF-атаки. Чтобы этого избежать, система может добавить суждение при добавлении токена: если ссылка ведет на собственный сайт, то он добавит токен позже, а если во внешнюю сеть, то не будет добавлен. Однако, даже если csrftoken не привязан к запросу в виде параметра, сайт хакера также может получить значение токена через Referer для запуска CSRF-атак. Это также причина, по которой некоторые пользователи предпочитают вручную отключать функцию реферера в своих браузерах.

(3) Настройте атрибуты в заголовках HTTP и проверьте

Этот метод также использует токен и выполняет проверку.Отличие от предыдущего метода заключается в том, что токен не помещается в HTTP-запрос в качестве параметра, а размещается в пользовательском атрибуте в HTTP-заголовке. Через класс XMLHttpRequest можно добавить атрибут заголовка HTTP csrftoken ко всем запросам этого типа одновременно, и поместить в него значение токена. Это решает неудобство добавления токена в запрос в предыдущем способе, при этом запрашиваемый через XMLHttpRequest адрес не будет записываться в адресную строку браузера, и можно не беспокоиться об утечке токена другим веб-сайты через Referer.

Однако ограничения этого метода очень велики. Запрос XMLHttpRequest обычно используется в методе Ajax для частичного асинхронного обновления страницы.Не все запросы подходят для инициации этим классом, и страница, полученная через этот класс запроса, не может быть записана браузером, так что вперед, назад и обновление , Избранное и другие операции доставят пользователям неудобства. Кроме того, для устаревших систем без CSRF-защиты для использования этого метода защиты все запросы необходимо изменить на запросы XMLHttpRequest, что практически переписывает весь сайт, что, несомненно, неприемлемо.

10. Какова функция и разница между тегом script и атрибутами defer и async

Атрибут async указывает, что загрузка и отрисовка последующих документов выполняются параллельно с загрузкой и выполнением js-скриптов, то есть асинхронное выполнение.

Атрибут defer, процесс загрузки последующего документа и загрузка js-скрипта (только загрузка, но не выполнение в это время) выполняются параллельно (асинхронно).Выполнение js-скрипта должно дождаться, пока все элементы document анализируются и до того, как событие DOMContentLoaded будет запущено для выполнения.

разница

1. defer и async согласованы в процессе загрузки сети и выполняются асинхронно;

2. Разница между ними заключается в том, что когда скрипт загружается и выполняется, отсрочка больше соответствует требованиям к загрузке и выполнению скрипта приложения в большинстве сценариев;

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