Что такое HTML импорт и как это работает? Сценарий #2: у вас есть скрипты в элементе или по ходу тела документа. Браузерное кеширование импорта

Правило CSS import позволяет импортировать внешние таблицы стилей не только на HTML-страницу , но и в другой стилевой документ. Это упрощает управление файлами и их интеграцию.

Импорт в HTML

Чтобы воспользоваться правилом @import в HTML-файле , добавьте следующий код в шапку страницы:

@import url("/styles/default.css");

Данный код импортирует CSS для использования на HTML-странице . Это позволяет редактировать все ее стили при помощи отдельного файла. Недостаток такого подхода заключается в отсутствии параллельной загрузки. То есть, страница не начнет загружаться до тех пор, пока браузер не загрузит файл CSS полностью. Это негативно скажется на скорости загрузки сайта и общей производительности.

В качестве альтернативного способа применения import url CSS в HTML можно сослаться на таблицу стилей следующим образом:

Эта ссылка работает по принципу @import , и позволяет управлять всем CSS-кодом с помощью отдельного файла. Данный метод предпочтительнее с точки зрения параллельной загрузки. Если вам все еще хочется распределить CSS по отдельным файлам, то можно воспользоваться @import внутри основного стилевого файла.

Импорт в CSS

Применение в приведенном выше примере позволит внедрить файл «default.css » в HTML-страницу . Внутри этого CSS-файла находятся различные правила стилизации. Эти стили можно разместить как на одной странице, так и разбить их на отдельные фрагменты. А также импортировать в основной файл CSS .

Предположим, что мы используем четыре отдельных CSS-файла : один для разметки, второй для шрифтов и третий для картинок. Четвертым будет основной файл, в котором указаны ссылки на все остальные файлы. В самом верху основного файла (так как правила импорта должны размещаться над всем остальным содержимым ) добавьте следующий код CSS import :

@import url("/styles/layout.css"); @import url("/styles/type.css"); @import url("/styles/images.css");

Уже после этих правил можно добавлять любой CSS-код для оформления страниц.

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

Используем @import в медиа-запросах

Разделение основного CSS-файла может пригодиться при адаптации сайта под мобильные устройства, где для разных разрешений и размеров экрана применяются различные стили. Главная проблема заключается в том, что подключения CSS import расположены в самом верху страницы, поэтому медиа-запросы будут загружены после стилей. При разработке адаптивных дизайнов важно учитывать производительность сайта. Рекомендуется не разделять CSS адаптивного сайта и использовать @import для их загрузки на ресурс.

Всегда ли нужно использовать @import?

Вовсе нет. На многих сайтах весь CSS расположен прямо в коде страниц, и в этом нет ничего страшного.

Поддержка браузерами

У старых браузеров наблюдаются некоторые проблемы поддержки правила CSS import , но сейчас этими версиями программ практически никто не пользуется. Времена Internet Explorer уже давно позади.

Перевод статьи “Using @import in Cascading Style Sheets ” был подготовлен дружной командой проекта .

Хорошо Плохо

    Подключение CSS-кода на странице можно производить четырьмя способами: в тело документа, встроить код в заголовочную часть страницы (header), указать ссылку на внешний…

HTML импорт является одним из способов включить внешний HTML-документ и его веб-компоненты на странице без соответствующего AJAX запроса или загрузки IFRAME. Ввиду этой возможности, импорт HTML может послужить ускорению времени загрузки страницы, открыть новые возможности для повторного использования кода, а также улучшить интеграцию некоторых популярных сервисов, таких как Google Maps.

На момент написания статьи, технология импорта HTML является рабочим проектом W3C, а это значит, что она ещё не является веб-стандартом и пока не поддерживается во всех браузерах . Однако, HTML импорт можно уже сейчас использовать через Polymer .

HTML импорт как инструмент для повторного использования и агрегирования

Разработчики программного обеспечения, в том числе и веб-разработчики, стараются не дублировать код, а скорее распределять его по моделям, объектам, функциям. Благодаря разработчикам Дэйву Томасу и Эндрю Ханту, этот подход обычно называют DRY-разработкой или DRY-программированием, что значит в переводе с английского "не повторяй себя".

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

Для примера возьмём HTML-файл с названием messages.html:

Success

Whatever you just did worked.

Failure

What a disappointment.

You are amazing.

Для повторного использования контента из messages.html, для начала включите документ через HTML импорт. Это осуществляется добавлением тега с атрибутом rel, равным "import" и атрибутом href, принимающим значение messages.html:

Мы можем написать небольшой отрывок, используя JavaScript, который обращается к документу messages.html и загружает сообщения “success” на странице. Каждое из последующих сообщений (или все вместе) также могут быть загружены аналогичным образом, в зависимости от того, как вам хотелось бы использовать их. Вот код:

Var htmlImport = document.querySelector("link"); var htmlDoc = htmlImport.import; var htmlMessage = htmlDoc.querySelector(".message-success"); document.body.appendChild(htmlMessage.cloneNode(true));

Данный код выполняет следующие задачи:

  • Выбирает элемент link
  • Импортирует файл
  • Извлекает импортированный DOM
  • Вставляет содержимое на страницу

Вот таким образом, сообщение “success” теперь включено на странице, подобно тому, как это работает через AJAX запрос.

Этот пример, конечно, крайне упрощён. Если бы содержание в messages.html было значительно сложнее, например, в несколько сотен строк HTML, JavaScript и CSS, то наш код импорта выглядел бы чуть сложнее.

В качестве второго примера рассмотрим, как языки программирования часто используются для загрузки повторно-используемого контента. В приведённом ниже примере из файла single.php появляется выбор окна приветствия для WordPress:

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

Аналогично тому, как скрипт PHP обращается к внешнему ресурсу, HTML импорт может быть использован для добавления содержимого. Эта аналогия может стать яснее, если учесть, что HTML импорт являются частью проекта HTML

Веб-компонентов.

Подключение шаблонов Вложенный импорт

Иногда нужно импортировать что-нибудь внутри импорта. Например, если вы хотите повторно использовать или расширить компонент, вы можете использовать вложенный импорт.

Снизу представлен реальный пример из Полимера . Это компонент tab () использующий компоненты layout и selector . Эти зависимости загружаются при помощи HTML-импорта.

polymer-ui-tabs.html

Вот так разработчики могут использовать этот элемент:

Когда выйдет новая версия селектора, например Вы сможете подменить И сразу же начать пользоваться новой версией. Благодаря импорту и веб-компонентам, это обновление не заденет код использующий компонент polymer-ui-tabs .

Управление зависимостями

Как вы знаете, если дважды подключить JQuery, это приведет к ошибкам. Не будет ли это проблемой, если несколько компонентов используют одну библиотеку? Нет, если мы будем использовать HTML-импорт! Использование импорта само по себе разрешает проблему управления зависимостями.

Оборачивая используемые библиотеки в импорт, вы автоматически избегаете их повторной загрузки. Импортируемый документ парсится только один раз. Скрипты в нем тоже выполняются только раз. Для примера вы можете импортировать jquery.html, который загружает сам JQuery.

Данный импорт может быть использован в других импортируемых компонентах:

Hello, I"m import 2

ajax-element.html

var proto = Object.create(HTMLElement.prototype); proto.makeRequest = function(url, done) { return $.ajax(url).done(function() { done(); }); }; document.registerElement("ajax-element", {prototype: proto});

Если понадобится, главный документ также может использовать jquery.html:

... $(document).ready(function() { var el = document.createElement("ajax-element"); el.makeRequest("http://example.com"); });

Несмотря на то, что jquery.html подключается в нескольких разных документах, его загрузка и исполнение происходит только один раз. Это можно увидеть заглянув на панель network:

Соображения производительности

HTML-импорт - замечательная технология, но как и с любой новой веб-технологией, вы должны с умом подойти к её использованию. Лучшие практики веб-разработки никто не отменял. Вот несколько вещей, которые вы должны помнить, работая с импортом.

Объединение импорта

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

Браузерное кеширование импорта

HTML-импорт также хорошо справляется с логикой кеширования. Импорт http://cdn.com/bootstrap.html содержит вложенные ресурсы, но они так же кешируются.

Содержимое используется, только когда оно добавлено в DOM

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

Var link = document.createElement("link"); link.rel = "stylesheet"; link.href = "styles.css";

Браузер не запросит styles.css, до тех пор пока элемент link не будет добавлен в DOM:

Document.head.appendChild(link); // browser requests styles.css

Другой пример, это динамически созданная разметка:

Var h2 = document.createElement("h2"); h2.textContent = "Booyah!";

Элемент h2 ничего не изменит, пока вы не добавите его в DOM.

Оптимизация для асинхронной загрузки

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

console.log("I block page rendering");

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

Сценарий #1 (предпочтительный): у вас нет скриптов в элементе или по ходу тела документа

вот пример:

... // Other scripts n" stuff. // Bring in the import content. var link = document.querySelector("link"); var post = link.import.querySelector("#blog-post"); var container = document.querySelector("#container"); container.appendChild(post.cloneNode(true));

Все скрипты расположены снизу.

Сценарий 1.5: импорт добавляется самостоятельно

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

... var me = document.currentScript.ownerDocument; var post = me.querySelector("#blog-post"); var container = document.querySelector("#container"); container.appendChild(post.cloneNode(true));

Сценарий #2: у вас есть скрипты в элементе или по ходу тела документа

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

function addImportLink(url) { var link = document.createElement("link"); link.rel = "import"; link.href = url; link.onload = function(e) { var post = this.import.querySelector("#blog-post"); var container = document.querySelector("#container"); container.appendChild(post.cloneNode(true)); }; document.head.appendChild(link); } addImportLink("/path/to/import.html"); // Import is added early:) // other scripts ...

Как вариант, вы можете добавить весь импорт в конце .

// other scripts ... function addImportLink(url) { ... } addImportLink("/path/to/import.html"); // Import is added very late:(

Примечание : Самый последний вариант - наименее предпочтителен. Парсер не начинает работать с содержимым страницы до самого окончания страницы.

Что стоит запомнить
  • mime-тип импорта, это text/html
  • Ресурсы с других доменов должны разрешать междоменное разделение ресурсов(CORS)
  • Импорт с одним URL запрашивается и выполняется только один раз. Это также значит, что скрипты внутри импорта выполняются только один раз.
  • Скрипты в импорте выполняются по порядку но не останавливают парсинг главного документа.
  • Элемент импорта не говорит браузеру "#добавь содержимое прямо сюда". Он говорит «пойди и возьми этот документ, чтобы я в дальнейшем мог его использовать». Скрипты в импорте выполняются автоматически, а разметка, стили и другие ресурсы должны быть явно добавлены на главную страницу. Примечание: элементы также добавляются автоматически. Это все составляет огромную разницу между HTML-импортом и , который говорит браузеру «загрузи и отобрази контент прямо здесь».
Заключение

HTML-импорт позволяет предоставлять набор HTML/CSS/JS кода, как единый ресурс. Это полезно, как само по себе, так и в контексте веб-компонентов. Разработчики могут создавать повторно используемые компоненты, для их потребления другими разработчиками при помощи .

HTML-импорт это простая идея, но она предоставляет нам несколько интересных полезностей.

Полезности


1 . В оригинале предложение звучит так «Yo dawg. I hear you like imports, so I included an import in your import.», это отсылка к известному выражению репера Xzibit

  • Перевод
  • Tutorial
Предоставление веб-компонентов HTML-импорт упрощает загрузку и повторное использование кода. В частности, это хороший способ распространения веб-компонентов. Это касается как простых HTML , так и полноценных кастомных элементов с теневым DOM [ , , ]. Когда эти технологии работают вместе, импорт становится инструментом для подключения веб-компонентов.Подключение шаблоновHTML-шаблоны это хороший пример того, где может пригодиться импорт. Тэг позволяет выносить определенные секции разметки для дальнейшего их использования. Шаблоны полезны тем, что их содержимое и скрипты не будут отображаться и выполняться до их добавления на страницу при помощи JS кода.

Import.html
Hello World! alert("Executed when the template is activated.");
index.html
var link = document.querySelector("link"); // Clone the in the import. var template = link.import.querySelector("template"); var clone = document.importNode(template.content, true); document.querySelector("#container").appendChild(clone);

Определение пользовательских элементовПользовательские элементы это еще одна технология веб-компонентов, которая отлично сочетается с HTML-импортом. Как мы знаем в импорте могут выполняться скрипты , таким образом мы можем объявлять и регистрировать пользовательские элементы, позволяя использовать их в разметке главного документа. Назовем это авторегистрацией.

Elements.html
// Define and register . var proto = Object.create(HTMLElement.prototype); proto.createdCallback = function() { this.innerHTML = "Hello, " + (this.getAttribute("name") || "?") + ""; }; document.registerElement("say-hi", {prototype: proto}); // Define and register that uses Shadow DOM. var proto2 = Object.create(HTMLElement.prototype); proto2.createdCallback = function() { var root = this.createShadowRoot(); root.innerHTML = "::content > *{color: red}" + "I"m a " + this.localName + " using Shadow DOM!"; }; document.registerElement("shadow-element", {prototype: proto2});
Данный импорт определяет (и регистрирует) два элемента: и . Мы можем использовать их прямо в разметке импортирующего документа без каких-либо дополнительных предусловий.

Index.html
(I"m in the light dom)
Как мне кажется, такой подход превращает HTML-импорт в идеальный способ предоставления веб-компонентов.

Работа с зависимостями и вложенным импортом Эй, ты, я вижу тебе понравился импорт, так что я вложил импорт внутрь импорта .Вложенный импорт Иногда нужно импортировать что-нибудь внутри импорта. Например, если вы хотите повторно использовать или расширить компонент, вы можете использовать вложенный импорт.

Снизу представлен реальный пример из Полимера . Это компонент tab () использующий компоненты layout и selector . Эти зависимости загружаются при помощи HTML-импорта.

Polymer-ui-tabs.html

Вот так разработчики могут использовать этот элемент:

Когда выйдет новая версия селектора, например Вы сможете подменить И сразу же начать пользоваться новой версией. Благодаря импорту и веб-компонентам, это обновление не заденет код использующий компонент polymer-ui-tabs .

Управление зависимостями Как вы знаете, если дважды подключить JQuery, это приведет к ошибкам. Не будет ли это проблемой, если несколько компонентов используют одну библиотеку? Нет, если мы будем использовать HTML-импорт! Использование импорта само по себе разрешает проблему управления зависимостями.

Оборачивая используемые библиотеки в импорт, вы автоматически избегаете их повторной загрузки. Импортируемый документ парсится только один раз. Скрипты в нем тоже выполняются только раз. Для примера вы можете импортировать jquery.html, который загружает сам JQuery.

Jquery.html

Данный импорт может быть использован в других импортируемых компонентах:

Import2.html
Hello, I"m import 2
ajax-element.html
var proto = Object.create(HTMLElement.prototype); proto.makeRequest = function(url, done) { return $.ajax(url).done(function() { done(); }); }; document.registerElement("ajax-element", {prototype: proto});
Если понадобится, главный документ также может использовать jquery.html:

... $(document).ready(function() { var el = document.createElement("ajax-element"); el.makeRequest("http://example.com"); });

Несмотря на то, что jquery.html подключается в нескольких разных документах, его загрузка и исполнение происходит только один раз. Это можно увидеть заглянув на панель network:

Соображения производительности HTML-импорт - замечательная технология, но как и с любой новой веб-технологией, вы должны с умом подойти к её использованию. Лучшие практики веб-разработки никто не отменял. Вот несколько вещей, которые вы должны помнить, работая с импортом.Объединение импорта Очень важно сократить количество запросов при загрузке страницы. Поэтому, если вам нужно импортировать большое количество компонентов верхнего уровня, постарайтесь объединить их в единственный файл для импорта.Браузерное кеширование импорта HTML-импорт также хорошо справляется с логикой кеширования. Импорт cdn.com/bootstrap.html содержит вложенные ресурсы, но они так же кешируются.Содержимое используется, только когда оно добавлено в DOM Содержимое никак не вызывается, до тех пор пока оно не использовано в скриптах. Для примера у нас есть динамически созданная таблица стилей:

Var link = document.createElement("link"); link.rel = "stylesheet"; link.href = "styles.css";
Браузер не запросит styles.css, до тех пор пока элемент link не будет добавлен в DOM:

Document.head.appendChild(link); // browser requests styles.css
Другой пример, это динамически созданная разметка:

Var h2 = document.createElement("h2"); h2.textContent = "Booyah!";
Элемент h2 ничего не изменит, пока вы не добавите его в DOM.

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

console.log("I block page rendering");
Есть несколько способов для оптимизации асинхронного поведения, использование которых зависит от структуры вашего приложения. Следующие техники помогут избежать блокировки отображения главной страницы.

Сценарий #1 (предпочтительный): у вас нет скриптов в элементе или по ходу тела документа
Я рекомендую использовать скрипты как можно ниже, чтобы предотвратить немедленную загрузку вашего импорта. Но вы ведь и так следуете этой практике, НЕ ТАК ЛИ!? ;)

Вот пример:
... // Other scripts n" stuff. // Bring in the import content. var link = document.querySelector("link"); var post = link.import.querySelector("#blog-post"); var container = document.querySelector("#container"); container.appendChild(post.cloneNode(true));
Все скрипты расположены снизу.

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

Import.html:
... var me = document.currentScript.ownerDocument; var post = me.querySelector("#blog-post"); var container = document.querySelector("#container"); container.appendChild(post.cloneNode(true));
index.html

Сценарий #2: у вас есть скрипты в элементе или по ходу тела документа
Если у вас есть большой импорт, на загрузку которого нужно много времени, следующий за ним скрипт остановит рендеринг страницы. Google Analytics например, рекомендует добавлять отслеживающий код в элементе. Если вы не можете избежать размешения скриптов в элементе, динамическое добавление тега импорта предотвратит блокировку:

function addImportLink(url) { var link = document.createElement("link"); link.rel = "import"; link.href = url; link.onload = function(e) { var post = this.import.querySelector("#blog-post"); var container = document.querySelector("#container"); container.appendChild(post.cloneNode(true)); }; document.head.appendChild(link); } addImportLink("/path/to/import.html"); // Import is added early:) // other scripts ... Добавить метки

Перевод статьи «?», Paula Borowska.

Вы когда-нибудь замечали, что включение одной HTML страницы в другую, это какая-то инородная концепция? Это то, что должно быть просто, но не это не часто происходит. Это не невозможно, но трудно. К счастью есть HTML импорт , который позволяет запросто помещать HTML страницы, а также CSS и JavaScript файлы, внутрь других HTML страниц.

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

Интересно то, что HTML это самые простые файлы, но иногда с ними труднее всего работать. Даже PHP файлы имеют возможность включения, почему же HTML этого не может? Благодаря веб-компонентам, мы, теперь, можем включать одни HTML документы в другие . Также, при помощи этого же тега, мы можем подключать CSS и JavaScript. (Жить стало намного лучше.)

Обходные пути Раньше, одним из обходных путей было подключение при помощи iFrame; это тяжелые HTML элементы, загружаемые отдельным окном внутри текущего документа. Это немного не то, что нам нужно и при этом с ними, не очень то легко взаимодействовать. iFram"ы могут быть удивительно разочаровывающими, когда с ними приходится работать. Следующим вариантом был AJAX, это когда вы загружали страницу при помощи JavaScript и включали её контент. Это, на самом деле, довольно неудобный и утомительный способ.НачнёмБазовый синтаксис Прежде чем смотреть примеры, давайте глянем на синтаксис подгрузки файла через тег импорта. Импорт, это новый тип link тега, так что должно быть нетрудно понять следующую строчку:


Такие строки помещаются в шапке, как вы уже привыкли поступать с JavaScript или CSS файлами.

Базовый пример Чтобы импорт сработал, страницы должны находиться на одном и том же сервере. Начнем с файла index.html. Это простая HTML страница с базовым импортом:

What are HTML imports and how do they work Hello from Designmodo

Видите, я не врала о том, как все просто; это так же просто, как загрузка таблицы стилей или JavaScript-файла.

Внутри intro.html Что же внутри импортированной страницы?


Это просто div с текстом внутри. Не нужно body или head или чего-то ещё.

Вставка импортированного HTML Чтобы отобразить импортированный HTML, нам нужно написать несколько строчек на JavaScript. Этот код должен находиться в главном HTML-файле, в нашем случае, index.html. Данный код должен находиться в том месте, где мы хотим увидеть импортированный html. В нашем примере после ‘Hello from Designmodo.’

В нашем скрипте мы получаем контент и присваиваем его переменной. Потом мы просто добавляем содержимое переменной в HTML.
What are HTML imports and how do they work Hello from Designmodo var link = document.querySelector("link"); var content = link.import.querySelector("#intro-dm"); document.body.appendChild(content.cloneNode(true));

Переходим на следующий уровень Вы когда-нибудь слышали о CSS атрибуте scoped? Атрибут scoped позволяет вам ограничивать действие тега внутри элемента. Хорошо то, что scoped стили действуют только внутри элемента, в котором они заданы, а не во всем документе. Посмотрим, как атрибут scoped может помочь при работе с импортированными HTML-файлами.

Добавим h1 в импортированный документ , чтобы увидеть разницу между стилями импортированного файла и стилями index.html. Потом добавим стиль элементам импортированного HTML документа. Как видите находится внутри импортированной разметки, а не в head теге. Благодаря scoped, стили применятся только к h1 внутри импортированной разметки.

h1{ color: red; } p{ color: blue; } About us We"re an awesome blog about web design

Designmodo is a great resource of informative material for designers and web developers. We are makers of highly-rated User Interface Packs, you can get acquainted with Designmodo shop here, and you can download a couple of other ui packs for free.