Questo è il primo post del blog di engineering di web.dev. Nel corso dei prossimi mesi, speriamo di condividere informazioni strategiche derivate dal nostro lavoro, quindi tieni d'occhio i post con il tag del blog di Engineering. Qui illustreremo la procedura di compilazione del nostro sito statico e la (facoltativa) JavaScript alla base dei nostri componenti web.
web.dev fornisce contenuti sulla creazione di esperienze web moderne e ti consente di misurare il rendimento del tuo sito. Gli utenti esperti potrebbero aver notato che la nostra pagina Misura è solo un'interfaccia per Lighthouse, che è disponibile anche in DevTools di Chrome. L'accesso a web.dev ti consente di eseguire controlli regolari di Lighthouse sul tuo sito in modo da poter vedere come cambia il suo punteggio nel tempo. Tornerò alla pagina Misura un po' più tardi, perché riteniamo che sia piuttosto speciale. 🎊
Introduzione
Fondamentalmente, web.dev è un sito statico generato da una raccolta di file Markdown. Abbiamo scelto di utilizzare Eleventy perché è uno strumento raffinato ed estensibile che consente di convertire facilmente Markdown in HTML.
Utilizziamo anche bundle JavaScript moderni che pubblichiamo solo nei browser che supportano type="module"
, tra cui async
e await
.
Utilizziamo anche funzionalità supportate dai browser permanenti, ma non da una minoranza di versioni precedenti.
Poiché siamo un sito statico, JavaScript non è necessario per leggere i nostri contenuti.
Una volta completato il processo di compilazione, che prevede la generazione di HTML statico e il raggruppamento di JavaScript con Rollup, web.dev può essere ospitato con un semplice server statico a scopo di test. Il sito è quasi completamente statico, ma abbiamo alcune esigenze speciali che possono essere soddisfatte con un server Node.js personalizzato. Sono inclusi i reindirizzamenti per i domini non validi, nonché il codice per analizzare la lingua preferita di un utente per una funzionalità di internazionalizzazione in arrivo.
Generazione di annunci statici
Ogni pagina su web.dev è scritta in Markdown. Tutte le pagine includono premessa, che descrive i metadati di ogni post. Questi metadati vengono importati nel layout di ogni pagina, creando intestazioni, tag e così via. Ecco un esempio:
---
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...
Questa parte iniziale ci consente di definire proprietà arbitrarie come autori, data di pubblicazione e tag. Eleventy espone comodamente la premessa come dati in quasi tutti i plug-in, modelli o altri contesti in cui vogliamo fare qualcosa di intelligente. L'oggetto dati contiene anche ciò che Eleventy descrive come cascata di dati: una serie di dati estratti da ogni singola pagina, dal layout utilizzato dalla pagina e dai dati trovati nella struttura gerarchica delle cartelle.
Ogni layout unico descrive un tipo diverso di contenuti e può ereditare da altri layout. Su web.dev, utilizziamo questa funzione per inquadrare correttamente diversi tipi di contenuti (come post e codelab) continuando a condividere un layout HTML di primo livello.
Raccolte
Eleventy fornisce un modo programmatico per creare raccolte arbitrarie di contenuti. In questo modo, abbiamo potuto creare il supporto della paginazione e generare pagine virtuali (pagine che non hanno un file Markdown corrispondente sul disco) per gli autori dei post. Ad esempio, costruiamo le pagine dei nostri autori utilizzando un modello contenente un'espressione per il suo permalink (in modo che il modello venga visualizzato nuovamente per ogni autore) e una raccolta di supporto.
Ne consegue, ad esempio, una pagina semplice contenente tutti i post di Addy.
Limitazioni
Al momento non possiamo collegarci facilmente al processo di compilazione di Eleventy perché è declarativo anziché imperativo: descrivi cosa vuoi, non come lo vuoi. È difficile eseguire Eleventy come parte di uno strumento di creazione più grande, poiché può essere richiamato solo tramite la sua interfaccia a riga di comando.
Modelli
web.dev utilizza il sistema di modelli Nunjucks originariamente sviluppato da Mozilla. Nunjucks offre le funzionalità di creazione di modelli tipiche, come i loop e i controlli condizionali, ma ci consente anche di definire shortcode che generano ulteriore codice HTML o invocano altra logica.
Come la maggior parte dei team che creano siti di contenuti statici, abbiamo iniziato in piccolo e abbiamo aggiunto gli shortcode nel tempo, fino ad arrivare a circa 20. La maggior parte di questi genera solo altro codice HTML (inclusi i nostri componenti web personalizzati). Ecco un esempio:
{% Aside %}
See how Asides work in the web.dev codebase
{% endAside %}
L'aspetto sarà simile al seguente:
In realtà, però, sta creando codice HTML simile al seguente:
<div class="aside color-state-info-text">
<p>See how Asides work in the web.dev codebase</p>
</div>
Anche se non rientra nell'ambito di questo post, web.dev utilizza gli shortcode come tipo di linguaggio di metaprogrammazione. I shortcode accettano argomenti, uno dei quali è costituito dai contenuti contenuti. Non è necessario che gli shortcode restituiscano nulla, quindi possono essere utilizzati per creare stati o attivare altri comportamenti. 🤔🏅
Definisci i tuoi contenuti
Come accennato in precedenza, poiché web.dev è un sito statico, può essere pubblicato e utilizzato senza JavaScript e da browser meno recenti che non supportano type="module"
o il nostro altro codice moderno.
Questa è una parte estremamente importante del nostro approccio per rendere web.dev accessibile a tutti.
Tuttavia, il nostro codice per i browser moderni è composto da due parti principali:
- Codice di bootstrap, che include il codice per lo stato globale, Analytics e il routing SPA
- Codice e CSS per componenti web che migliorano progressivamente il sito
Il codice di bootstrap è abbastanza semplice: web.dev può caricare nuove pagine come applicazione a pagina singola (SPA), quindi installiamo un ascoltatore globale che rileva i clic sugli elementi <a href="...">
locali.
Il modello SPA ci aiuta a mantenere lo stato globale della sessione corrente dell'utente, altrimenti ogni nuovo caricamento di pagina attiverebbe chiamate a Firebase per accedere allo stato di accesso di un utente.
Specifichiamo anche un paio di punti di contatto diversi nel nostro sito in base all'URL che hai visitato e carichiamo quello corretto utilizzando import()
dinamico.
In questo modo, riduciamo il numero di byte di cui hanno bisogno i nostri utenti prima che il sito venga migliorato con il codice.
Componenti web
I componenti web
sono elementi personalizzati che incapsulano la funzionalità di runtime fornita in JavaScript e sono identificati da nomi personalizzati come <web-codelab>
.
Il design si presta bene a siti in gran parte statici come web.dev: il tuo browser gestisce il ciclo di vita di un elemento quando il codice HTML di un sito viene aggiornato, informando correttamente tutti gli elementi quando vengono allegati o scollegati dalla pagina.
I browser obsoleti ignorano completamente i componenti web e visualizzano ciò che rimane nel DOM.
Ogni componente web è una classe con metodi quali connectedCallback()
, disconnectedCallback()
e attributeChangedCallback()
.
Gli elementi personalizzati di web.dev ereditano principalmente da LitElement, che fornisce una base semplice per componenti complessi.
Anche se web.dev utilizza i componenti web su molte pagine, in nessun altro luogo è più necessario che nella pagina Misura. Due elementi forniscono la maggior parte delle funzionalità che vedi in questa pagina:
<web-url-chooser-container></web-url-chooser-container>
<web-lighthouse-scores-container></web-lighthouse-scores-container>
Questi elementi creano altri elementi che forniscono più funzionalità. È importante sottolineare che questi elementi fanno parte del nostro normale codice sorgente Markdown e il nostro team di contenuti può aggiungere funzionalità estese a qualsiasi pagina, non solo al nodo Misura.
I nostri componenti web utilizzano più comunemente il modello Componente container, reso popolare da React, anche se ora questo modello è un po' superato.
Ogni elemento -container
si connette al nostro stato globale (fornito da unistore) e poi esegue il rendering di un elemento visivo, che a sua volta esegue il rendering di nodi DOM effettivi con stili o altre funzionalità integrate.
I nostri componenti web più complessi esistono per visualizzare azioni e stato globali. Ad esempio, web.dev ti consente di verificare il tuo sito preferito e poi uscire dalla pagina Misura. Se torni, vedrai che l'attività è ancora in corso.
I nostri semplici componenti migliorano semplicemente i contenuti statici o creano visualizzazioni straordinarie (ad esempio, ogni grafico a linee è il proprio <web-sparkline-chart>
), che non ha alcuna relazione con lo stato globale.
Parliamone
Il team tecnico di web.dev (Rob, Ewa, Michael e Sam) seguirà a breve approfondimenti di carattere più tecnico.
Ci auguriamo che le informazioni su come lavoriamo ti abbiano dato qualche idea per i tuoi progetti. Se hai domande o richieste sugli argomenti per questo blog, contattaci su Twitter.