[Разработка веб-сайтов, JavaScript, Accessibility] Безжалостное избавление от Layout Shift на netlify.com (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
04-Дек-2020 05:31

Приветствую. Представляю вашему вниманию перевод статьи «Ruthlessly Eliminating Layout Shift On Netlify.com», опубликованной 25 ноября 2020 года автором Zach Leatherman.На сайте Netlify у нас есть небольшой баннер, который появляется вверху для привлечения трафика к новым и интересным вещам, происходящим в мире Netlify.
Этот баннер состоит из двух частей:
  • Расширенная фича HTML, о которой знают только разработчики старой школы: гиперссылка.
  • Кнопка закрытия (которая сохраняет предпочтение для будущих загрузок страницы)
В жизненном цикле этого компонента есть несколько ключевых этапов производительности, и вот как это работало раньше:
  • Первоначальный рендеринг страницы. По умолчанию баннер ⚠️⚠️⚠️ скрыт. До загрузки JavaScript или без JavaScript баннер не отображается.
  • После загрузки JavaScript мы проверяем localStorage, чтобы узнать, закрывал ли пользователь баннер ранее. Значение - URL-адрес ссылки, чтобы при изменении баннера он снова отображался, даже если пользователь его закрыл. Если нужно - рендерим баннер.
  • Наконец, мы вешаем события на кнопку закрытия. Для гиперссылки это не нужно, потому что ее поведение предоставляется исключительно в HTML (вааау).
Шаги 2 и 3 объединены и выполняются вместе в одном компоненте. В некоторых предедущих версиях сайта время между шагами 1 и 2 могло достигать ~600 мс.
При редизайне нашего сайта (заметьте, быстрее) мы вставили JavaScript шагов 2 и 3 в конец <body>, и задержка все еще была:
РешениеЧто нам нужно сделать? Сделать поведение наоборот. Обычно баннер по умолчанию скрыт. Мы должны сделать баннер видимым по умолчанию и с помощью JavaScript скрывать его, если нужно.Это изменяет наш выше упомянутый Шаг 1, первоначальный рендеринг страницы. Теперь без JavaScript или до загрузки JavaScript баннер будет виден.Мы также разделили код JavaScript-компонента на две отдельные части: в одной проверяем, есть ли у пользователя флаг для скрытия, и отдельный веб-компонент для привязки событий.Update: Я собрал этот код и выложил на GitHub для повторного использования.HTML и CSSМы используем opacity для скрытия кнопки закрытия, чтобы изза неё не перерисовывался компонент, когда он отобразится с помощью JavaScript.
.banner--hide announcement-banner,
announcement-banner[hidden] {
  display: none;
}
[data-banner-close] {
  opacity: 0;
  pointer-events: none;
}
.banner--show-close [data-banner-close] {
  opacity: 1;
  pointer-events: auto;
}
<announcement-banner>
  <a href="https://www.netlify.com/sustainability/">Read about our Sustainability</a>
  <button type="button" data-banner-close>Close</button>
</announcement-banner>
JavaScriptbanner-helper.js, вставленный в <head> страницы:
// Адрес CTA ссылки, мы инжектим его из JSON файла
let ctaUrl = "https://www.netlify.com/sustainability/";
let savedCtaUrl = localStorage.getItem("banner--cta-url");
if(savedCtaUrl === ctaUrl) {
  document.documentElement.classList.add("banner--hide");
}
banner.js, отоложен на потом (на сколько позже - зависит от вас):
class Banner extends HTMLElement {
  connectedCallback() {
    // Независимо от того, когда это выполняется, кнопка закрытия будет скрыта,
    // пока этот класс не будет добавлен - он предотвращает призрачные клики
    // по кнопке до добавления обработчика событий.
    this.classList.add("banner--show-close");
    let button = this.getButton();
    if(button) {
      button.addEventListener("click", () => {
        this.savePreference();
        this.close();
      });
    }
  }
  getButton() {
    return this.querySelector("[data-banner-close]");
  }
  savePreference() {
    let cta = this.querySelector("a[href]");
    if(cta) {
      let ctaUrl = cta.getAttribute("href");
      localStorage.setItem("banner--cta-url", ctaUrl);
    }
  }
  close() {
    this.setAttribute("hidden", true);
  }
}
window.customElements.define("announcement-banner", Banner);
Внимательные читатели заметят, что это веб-компонент, но давайте оставим это между нами.РезультатОбратите внимание, что первый рендер содержит баннер! Это одинаковый рендеринг вне зависимости от того, задействован ли JavaScript или нет.
На этой диаграмме видно, что мы снизили показатели Layout Shift до нуля.
И поскольку мы вставили скрипт для повторных просмотров в <head>, когда пользователь скрывает баннер и переходит на новую страницу, баннер также будет скрыт перед первым рендерингом.Довольно неплохо для таких маленьких изменений!Следующей целью будет улучшение отображения веб-шрифтов.
===========
Источник:
habr.com
===========

===========
Автор оригинала: Zach Leatherman
===========
Похожие новости: Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_accessibility, #_netlify, #_html, #_lighthouse, #_dostupnost (доступность), #_accessibility, #_razrabotka_vebsajtov (
Разработка веб-сайтов
)
, #_javascript, #_accessibility
Профиль  ЛС 
Показать сообщения:     

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

Текущее время: 22-Ноя 14:05
Часовой пояс: UTC + 5