Esta é a primeira postagem no blog de engenharia do web.dev. Nos próximos meses, vamos compartilhar insights úteis do nosso trabalho. Fique de olho nas postagens com a tag do blog de engenharia. Aqui, vamos abordar o processo de build do nosso site estático e o (opcional!) JavaScript por trás dos nossos componentes da Web.
O web.dev oferece conteúdo sobre a criação de experiências modernas da Web e permite medir o desempenho do site. Os usuários experientes podem ter percebido que nossa página de medição é apenas uma interface do Lighthouse, que também está disponível no Chrome DevTools. Ao fazer login no web.dev, você pode realizar auditorias regulares do Lighthouse no seu site para conferir como a pontuação muda ao longo do tempo. Voltaremos à página "Medir" novamente mais tarde, já que achamos que ela é bastante especial. 🎊
Introdução
Basicamente, o web.dev é um site estático gerado a partir de uma coleção de arquivos Markdown. Escolhemos o Eleventy porque é uma ferramenta refinada e extensível que facilita a conversão de Markdown em HTML.
Também usamos pacotes JavaScript modernos que só são exibidos em navegadores compatíveis com type="module"
, o que inclui async
e await
.
Também usamos recursos que têm suporte de navegadores evergreen, mas não de uma minoria de versões mais antigas.
Como somos um site estático, o JavaScript não é necessário para ler nosso conteúdo.
Depois que o processo de criação, que envolve a geração de HTML estático e o agrupamento do nosso JavaScript com o Rollup, é concluído, o web.dev pode ser hospedado com um servidor estático simples para teste. O site é quase totalmente estático, mas temos algumas necessidades especiais que ainda se beneficiam de um servidor personalizado do Node.js. Isso inclui redirecionamentos para domínios inválidos, bem como código para analisar o idioma de preferência de um usuário para um recurso de internacionalização futuro.
Geração estática
Cada página em web.dev está escrita em Markdown. Todas as páginas incluem material de abertura, que descreve os metadados de cada postagem. Esses metadados são processados no layout de cada página, criando títulos, tags e assim por diante. Veja um exemplo:
---
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...
Neste documento, podemos definir propriedades arbitrárias, como autores, data de publicação e tags. O Eleventy expõe convenientemente o front matter como dados em quase todos os plug-ins, modelos ou outros contextos em que gostaríamos de fazer algo inteligente. O objeto de dados também contém o que o Eleventy descreve como a cascata de dados, uma variedade de dados extraídos de cada página individual, do layout usado pela página e dos dados encontrados na estrutura hierárquica de pastas.
Cada layout único descreve um tipo diferente de conteúdo e pode herdar de outros layouts. No web.dev, usamos esse recurso para enquadrar corretamente diferentes tipos de conteúdo (como postagens e codelabs) e compartilhar um layout HTML de nível superior.
Coleções
O Eleventy oferece uma maneira programática de criar coleções arbitrárias de conteúdo. Isso nos permitiu criar suporte para paginação e gerar páginas virtuais (páginas que não têm um arquivo Markdown correspondente no disco) para autores de postagens. Por exemplo, criamos nossas páginas de autores usando um modelo que contém uma expressão para o permalink (para que o modelo seja renderizado novamente para cada autor) e uma coleção de suporte.
Isso resulta, por exemplo, em uma página simples com todas as postagens de Addy.
Limitações
No momento, não podemos conectar facilmente o processo de build do Eleventy porque ele é declarativo, e não imperativo: você descreve o que quer, e não como quer. É difícil executar o Eleventy como parte de uma ferramenta de build maior, porque ele só pode ser invocado pela interface de linha de comando.
Criação de modelos
O web.dev usa o sistema de modelos Nunjucks desenvolvido originalmente pelo Mozilla. O Nunjucks tem os recursos típicos de criação de modelos, como loops e condicionais, mas também permite definir shortcodes que geram mais HTML ou invocam outra lógica.
Como a maioria das equipes que criam sites de conteúdo estático, começamos com pouco e adicionamos códigos curtos ao longo do tempo. Até agora, são cerca de 20. A maioria deles gera mais HTML (incluindo nossos componentes da Web personalizados). Veja um exemplo:
{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}
O resultado será parecido com este:
Mas ele está criando um HTML parecido com este:
<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>
Embora esteja fora do escopo desta postagem, o web.dev também usa códigos curtos como um tipo de linguagem de metaprogramação. Os Shortcodes aceitam argumentos, sendo que um deles é o conteúdo contido. Os códigos de acesso não precisam retornar nada, então eles podem ser usados para criar estados ou acionar outros comportamentos. 🤔Conceitos
Roteiro
Como mencionado anteriormente, como o web.dev é um site estático, ele pode ser veiculado e usado sem JavaScript e por navegadores mais antigos que não oferecem suporte a type="module"
ou a outros códigos modernos.
Essa é uma parte muito importante da nossa abordagem para tornar o web.dev acessível a todos.
No entanto, nosso código para navegadores modernos consiste em duas partes principais:
- Código de inicialização, que inclui código para estado global, Google Analytics e roteamento de SPA
- Código e CSS para componentes da Web que aprimoram o site progressivamente
O código de inicialização é bastante simples: o web.dev pode carregar novas páginas como um aplicativo de página única (SPA). Por isso, instalamos um listener global que detecta cliques em elementos <a href="...">
locais.
O modelo de SPA nos ajuda a manter o estado global sobre a sessão atual do usuário. Caso contrário, cada nova carga de página acionaria chamadas para o Firebase para acessar o estado de login de um usuário.
Também especificamos alguns pontos de entrada diferentes no site com base no URL que você acessou e carregamos o correto usando import()
dinâmico.
Isso reduz o número de bytes de que os usuários precisam antes de aprimorar o site com código.
Componentes da Web
Os componentes da Web
são elementos personalizados que encapsulam a funcionalidade de execução fornecida em JavaScript e são identificados por nomes personalizados, como <web-codelab>
.
O design se adapta bem a sites bastante estáticos, como o web.dev: seu navegador gerencia o ciclo de vida de um elemento à medida que o HTML de um site é atualizado, informando corretamente os elementos quando eles são anexados ou removidos da página.
E os navegadores antigos simplesmente ignoram os componentes da Web e renderizam o que resta no DOM.
Cada componente da Web é uma classe com métodos que incluem connectedCallback()
, disconnectedCallback()
e attributeChangedCallback()
.
Os elementos personalizados de web.dev herdam principalmente de LitElement, que fornece uma base simples para componentes complexos.
Embora o web.dev use componentes da Web em muitas páginas, em nenhum lugar ele é mais necessário do que na página Medir. Dois elementos fornecem a maior parte da funcionalidade que você encontra nesta página:
<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>
Esses elementos criam outros elementos que oferecem mais funcionalidade. Esses elementos fazem parte do código-fonte Markdown normal, e nossa equipe de conteúdo pode adicionar funcionalidades estendidas a qualquer página, não apenas ao nó de medição.
Nossos componentes da Web geralmente usam o modelo de componente de contêiner, popularizado pelo React, embora esse modelo agora esteja um pouco desatualizado.
Cada elemento -container
se conecta ao nosso estado global (fornecido pelo unistore) e renderiza um elemento visual que, por sua vez, renderiza os nós DOM reais que têm estilo ou outra funcionalidade integrada.
Nossos componentes mais complexos da Web existem para visualizar ações e estados globais. Por exemplo, o web.dev permite que você audite seu site favorito e depois saia da página "Medir". Se você retornar, vai ver que a tarefa ainda está em andamento.
Nossos componentes simples aprimoram o conteúdo estático ou criam visualizações incríveis (por exemplo, cada gráfico de linhas é um <web-sparkline-chart>
), que não tem relação com o estado global.
Vamos conversar
A equipe de engenharia do web.dev (Rob, Ewa, Michael e Sam) vai publicar mais detalhes técnicos em breve.
Esperamos que o que contamos sobre como fazemos as coisas tenha dado algumas ideias para seus próprios projetos. Entre em contato com a gente no Twitter se tiver dúvidas ou sugestões de temas para este blog.