Инженерный блог web.dev №1: Как мы создаем сайт и используем веб-компоненты

Это первая запись в инженерном блоге web.dev. В ближайшие месяцы мы надеемся поделиться практической информацией о нашей работе, поэтому следите за публикациями с тегом «Инженерный блог» ! Здесь мы рассмотрим процесс сборки нашего статического сайта и (необязательно!) JavaScript, лежащий в основе наших веб-компонентов.

web.dev предоставляет контент о создании современного веб-интерфейса и позволяет измерять производительность вашего сайта. Опытные пользователи, возможно, поняли, что наша страница «Измерение» — это всего лишь интерфейс для Lighthouse , который также доступен в Chrome DevTools. Вход в web.dev позволяет вам регулярно проводить аудит Lighthouse на вашем сайте, чтобы вы могли видеть, как его оценка меняется с течением времени. Я вернусь к странице «Измерение» чуть позже, так как мы считаем ее особенной. 🎊

Введение

По сути, web.dev — это статический сайт, созданный из набора файлов Markdown. Мы выбрали Eleventy, потому что это совершенный расширяемый инструмент, который позволяет легко превратить Markdown в HTML.

Мы также используем современные пакеты JavaScript, которые мы предоставляем только браузерам, поддерживающим type="module" , включая async и await . Мы также с радостью используем функции, которые поддерживаются постоянно обновляемыми браузерами, но не поддерживаются меньшинством старых версий. Поскольку мы статический сайт, JavaScript не требуется для чтения нашего контента.

После завершения процесса сборки, который включает в себя генерацию статического HTML и объединение нашего JavaScript с Rollup, web.dev можно разместить на простом статическом сервере для тестирования. Сайт почти полностью статичен, но у нас есть несколько особых потребностей, которые по-прежнему могут быть решены с помощью специального сервера Node.js. К ним относятся перенаправления для недействительных доменов, а также код для анализа предпочтительного языка пользователя для будущей функции интернационализации.

Статическая генерация

Каждая страница на web.dev написана в Markdown. На всех страницах есть вступительная часть , в которой описываются метаданные о каждом сообщении. Эти метаданные встраиваются в макет каждой страницы, создавая заголовки, теги и т. д. Вот пример:

---
layout: post
title: What is network reliability and how do you measure it?
authors:
  - jeffposnick
date: 2018-11-05
description: |
  The modern web is enjoyed by a wide swath of people…
---

The modern web is enjoyed by a wide swath of [people](https://www.youtube.com/watch?v=dQw4w9WgXcQ), using a range of different devices and types of network connections.

Your creations can reach users all across the world...

Этот вводный вопрос позволяет нам определять произвольные свойства, такие как автор(ы), дата публикации и теги. Eleventy удобно отображает основную информацию в виде данных практически в каждом плагине, шаблоне или другом контексте, где мы хотели бы сделать что-то интеллектуальное. Объект данных также содержит то, что Eleventy называет каскадом данных — различные данные, полученные с каждой отдельной страницы, из макета, который использует страница, и из данных, найденных в иерархической структуре папок.

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

Коллекции

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

В результате, например, получится простая страница, содержащая все сообщения Адди !

Ограничения

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

Шаблонизация

web.dev использует систему шаблонов Nunjucks, первоначально разработанную Mozilla. Nunjucks имеет типичные функции шаблонов, такие как циклы и условные выражения, но также позволяет нам определять короткие коды , которые генерируют дополнительный HTML или вызывают другую логику.

Как и большинство команд, создающих сайты со статическим контентом, мы начинали с малого и со временем добавляли шорткоды — на данный момент их около 20. Большинство из них просто генерируют дополнительный HTML (включая наши пользовательские веб-компоненты). Вот пример:

{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}

В конечном итоге это будет выглядеть так:

Но на самом деле он создает HTML, который выглядит так:

<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>

Хотя это выходит за рамки этой статьи, web.dev также использует шорткоды как тип языка метапрограммирования. Шорткоды принимают аргументы, причем один из их аргументов является содержащимся в них содержимым. Не требуется, чтобы короткие коды что-либо возвращали, поэтому их можно использовать для создания состояния или запуска другого поведения. 🤔💭

Сценарии

Как упоминалось ранее, поскольку web.dev является статическим сайтом, его можно обслуживать и использовать без JavaScript и в старых браузерах, которые не поддерживают type="module" или другой наш современный код. Это невероятно важная часть нашего подхода к тому, чтобы сделать web.dev доступным для всех.

Однако наш код для современных браузеров состоит из двух основных частей:

  1. Код начальной загрузки, который включает код для глобального состояния, аналитики и маршрутизации SPA.
  2. Код и CSS для веб-компонентов, которые постепенно улучшают сайт.

Код начальной загрузки довольно прост: web.dev может загружать новые страницы как одностраничное приложение (SPA), поэтому мы устанавливаем глобальный прослушиватель, который прослушивает клики по локальным элементам <a href="..."> . Модель SPA помогает нам поддерживать глобальное состояние текущего сеанса пользователя, поскольку в противном случае каждая новая загрузка страницы будет вызывать вызовы Firebase для доступа к состоянию входа пользователя.

Мы также указываем несколько разных точек входа на наш сайт в зависимости от того, какой URL-адрес вы нажали, и загружаем правильную точку с помощью динамического import() . Это сокращает количество байтов, которые нужны нашим пользователям, прежде чем сайт будет дополнен кодом.

Веб-компоненты

Веб-компоненты — это пользовательские элементы, которые инкапсулируют функциональные возможности среды выполнения, предоставляемые в JavaScript, и идентифицируются специальными именами, такими как <web-codelab> . Дизайн хорошо подходит для преимущественно статических сайтов, таких как web.dev: ваш браузер управляет жизненным циклом элемента по мере обновления HTML-кода сайта, правильно информируя любые элементы, когда они прикреплены или отсоединены от страницы. А устаревшие браузеры просто игнорируют веб-компоненты и отображают все, что осталось в DOM.

Каждый веб-компонент представляет собой класс с методами, включая connectedCallback() , disconnectedCallback() и attributeChangedCallback() . Пользовательские элементы web.dev в основном наследуются от LitElement , который обеспечивает простую основу для сложных компонентов.

Хотя web.dev использует веб-компоненты на многих страницах, нигде это не является более необходимым, чем на странице «Измерение» . Два элемента обеспечивают основную часть функциональности, которую вы видите на этой странице:

<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>

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

В наших веб-компонентах чаще всего используется модель «Контейнерный компонент» , ставшая популярной благодаря React, хотя сейчас эта модель немного устарела . Каждый элемент -container подключается к нашему глобальному состоянию (предоставленному unistore ), а затем отображает визуальный элемент, который, в свою очередь, отображает реальные узлы DOM, имеющие стили или другие встроенные функции.

Диаграмма, показывающая связь между глобальным состоянием и элементами HTML, которые его используют.
Глобальное состояние и веб-компонент

Наши самые сложные веб-компоненты предназначены для визуализации глобальных действий и состояний. Например, web.dev позволяет вам провести аудит вашего любимого сайта, а затем уйти со страницы «Измерение». Если вы вернетесь, вы увидите, что задача все еще выполняется.

Наши простые компоненты просто улучшают статический контент или создают удивительные визуализации (например, каждый линейный график представляет собой отдельный <web-sparkline-chart> ), который не имеет никакого отношения к глобальному состоянию.

Давай общаться

Команда инженеров web.dev ( Роб , Ева , Майкл и Сэм ) вскоре продолжит более глубокие технические погружения.

Мы надеемся, что рассказ о том, как мы работаем, натолкнул вас на идеи для ваших собственных проектов. Напишите нам в Твиттере, если у вас есть вопросы или пожелания по теме для этого блога!