Conformità per i framework

Conformità nell'ecosistema del framework JavaScript

Shubhie Panicker
Shubhie Panicker

Nel nostro post del blog introduttivo, abbiamo visto come abbiamo imparato molto durante la creazione e l'utilizzo di framework e strumenti per sviluppare e gestire applicazioni web su larga scala come la Ricerca Google, Maps, Foto e così via. Salvando gli sviluppatori dalla scrittura di codice che può influire negativamente sull'esperienza utente, abbiamo dimostrato che i framework possono svolgere un ruolo chiave nel cambiamento dei risultati in termini di prestazioni e qualità delle applicazioni.

A livello interno di Google, abbiamo usato il termine "Conformità" per descrivere questa metodologia e questo articolo spiega come intendiamo rendere open source questo concetto nell'ecosistema del framework JavaScript.

Che cos'è la conformità?

Per Google, Conformance è stata un'evoluzione. I team si sono affidati a un ristretto gruppo di manutentori di grande esperienza, che hanno svolto ampie revisioni del codice, segnalando aspetti che influenzavano la qualità e la manutenzione delle app ben oltre i problemi di correttezza. Per adattarlo ai team di sviluppatori di app in crescita, è stato sviluppato un sistema di conformità per codificare le best practice in modo automatico e applicabile. Ciò ha garantito un livello costantemente elevato di qualità delle app e gestibilità del codebase indipendentemente dal numero di collaboratori.

La conformità è un sistema che garantisce agli sviluppatori di seguire un percorso ben illuminato; crea fiducia e garantisce risultati prevedibili. Rende i team produttivi e diventa fondamentale per la scalabilità, in quanto i team crescono e vengono sviluppate contemporaneamente più funzionalità. Consente agli sviluppatori di concentrarsi sulla creazione delle caratteristiche dei prodotti, liberandoli dalle minutie e dal mutevole panorama in diverse aree come prestazioni, accessibilità, sicurezza e così via. Chiunque può disattivare la conformità in qualsiasi momento e questa scelta dovrebbe essere personalizzabile nella misura in cui i team abbiano la possibilità di applicare qualsiasi cosa decidano di impegnarsi.

La conformità si basa su impostazioni predefinite efficaci e sull'applicazione di regole attuabili che possono essere applicate al momento della creazione. Questa si compone dei tre principi seguenti.

1. Impostazioni predefinite efficaci

Un aspetto fondamentale della conformità è garantire che gli strumenti usati dagli sviluppatori dispongano di impostazioni predefinite efficaci. Questo significa che le soluzioni non solo sono integrate nei framework, ma anche i pattern di progettazione dei framework semplificano l'esecuzione della cosa giusta e gli anti-pattern difficili da seguire. Il framework supporta gli sviluppatori nella progettazione delle applicazioni e nella struttura del codice.

Per migliorare il rendimento del caricamento, ogni risorsa (caratteri, CSS, JavaScript, immagini e così via) deve essere ottimizzata. Si tratta di una sfida complessa che comporta la riduzione dei byte, la riduzione dei round trip e la separazione di ciò che è necessario per la prima visualizzazione, l'idoneità visiva e l'interazione dell'utente. ad esempio l'estrazione di CSS critici e l'impostazione della priorità sulle immagini importanti.

2. Regole attuabili

Anche con le ottimizzazioni di base, gli sviluppatori devono comunque fare delle scelte. Quando è necessario il contributo dello sviluppatore, le possibilità di ottimizzazione sono molteplici:

  • Valori predefiniti che non richiedono l'intervento dello sviluppatore, ad esempio l'incorporamento di codice CSS fondamentale.
  • Richiede attivazione sviluppatore. Ad esempio, l'utilizzo di un componente di immagine fornito dal framework per dimensionare e scalare le immagini.
  • Richiede l'attivazione e la personalizzazione da parte degli sviluppatori. ad esempio il tagging di immagini importanti da caricare in anticipo.
  • Non si tratta di una funzionalità specifica, ma di aspetti che richiedono ancora una decisione dello sviluppatore. Ad esempio, evitare caratteri o script sincroni che ritardano il rendering iniziale.

Diagramma che mostra uno spettro tra le ottimizzazioni automatiche e manuali per gli sviluppatori

Le ottimizzazioni che richiedono una decisione da parte degli sviluppatori rappresentano un rischio per le prestazioni dell'applicazione. Con l'aggiunta di funzionalità e la scalabilità del tuo team, anche gli sviluppatori più esperti non sono in grado di stare al passo con le best practice in continua evoluzione e non si tratta di sfruttare al meglio il proprio tempo. Per la conformità, le regole attuabili e appropriati sono importanti quanto le impostazioni predefinite efficaci per garantire che l'applicazione continui a soddisfare un determinato standard anche quando gli sviluppatori continuano ad apportare modifiche.

3. Data creazione

È importante individuare e precludere i problemi di prestazioni nelle prime fasi del ciclo di sviluppo. Il tempo di creazione, prima del commit del codice, è ideale per rilevare e risolvere i problemi. Più avanti un problema viene coinvolto nel ciclo di vita dello sviluppo, più difficile e costoso è affrontarlo. Anche se questo vale per i problemi di correttezza, ma è anche vero per i problemi di prestazioni, poiché molti di questi problemi non verranno risolti in modo retroattivo una volta eseguito il commit nel codebase.

Oggi la maggior parte dei feedback sulle prestazioni è fuori banda tramite documentazione, audit una tantum o viene rivelata troppo tardi tramite la regressione delle metriche dopo il deployment in produzione. Vogliamo riportarlo al momento della creazione.

Conformità nei framework

Per mantenere un livello elevato di esperienza utente per le prestazioni di caricamento, è necessario rispondere alle seguenti domande:

  1. Cosa costituisce un caricamento ottimale e quali sono i problemi comuni che potrebbero influenzarlo negativamente?
  2. Quali soluzioni possono essere integrate che non richiedono alcun intervento da parte degli sviluppatori?
  3. Come possiamo assicurarci che lo sviluppatore utilizzi queste soluzioni e le sfrutti in modo ottimale?
  4. Quali altre scelte potrebbe fare lo sviluppatore che influiscono sulle prestazioni del caricamento?
  5. Quali sono i pattern di codice che possono indicarci queste scelte (n. 3 e n. 4 sopra) fin dalle prime fasi della creazione?
  6. Quali regole possiamo formulare per valutare questi pattern di codice? Come possono essere mostrate allo sviluppatore al momento della creazione e perfettamente integrate nel flusso di lavoro?

Per portare nei framework open source il modello di conformità di cui abbiamo internamente Google, il nostro team ha fatto grandi esperimenti su Next.js e siamo entusiasti di condividere la nostra visione e i nostri piani perfezionati. Ci siamo resi conto che l'insieme migliore di regole in grado di valutare i pattern di codice dovrà essere una combinazione di analisi del codice statico e controlli dinamici. Queste regole possono riguardare più piattaforme, tra cui:

  • ESLint
  • TypeScript
  • Controlli dinamici nel server di sviluppo dell'utente (dopo la creazione del DOM)
  • Bundler di moduli (webpack)
  • Strumenti CSS (ancora di esplorazione)

Se applichiamo regole tramite diversi strumenti, possiamo garantire che siano coerenti, ma che influiscano anche su eventuali problemi relativi all'esperienza utente che incidono direttamente sulle prestazioni di caricamento. Inoltre, queste regole possono essere mostrate anche agli sviluppatori in momenti diversi:

  • Durante lo sviluppo locale nel server di sviluppo, il browser e l'IDE dell'utente mostreranno avvisi, invitando gli sviluppatori ad apportare piccole modifiche al codice.
  • Al momento della creazione, i problemi non risolti verranno nuovamente visualizzati nel terminale dell'utente

In breve, i team sceglieranno i risultati a cui sono interessati, come i Segnali web essenziali o le prestazioni di caricamento, e attiveranno set di regole pertinenti per tutti i collaboratori del codice da seguire.

Anche se questo approccio funziona molto bene per i nuovi progetti, non è facile eseguire l'upgrade di codebase di grandi dimensioni per rispettare un set di regole completo. Google offre un ampio sistema per la disattivazione a diversi livelli, ad esempio singole righe di codice sorgente, intere directory, codebase legacy o parti dell'app non in fase di sviluppo attivo. Stiamo esplorando attivamente strategie efficaci per applicare questo approccio ai team utilizzando framework open source.

Conformità in Next.js

ESLint è ampiamente utilizzato tra gli sviluppatori JavaScript e oltre il 50% delle applicazioni Next.js utilizza ESLint in una parte del flusso di lavoro di compilazione. Next.js v11 ha introdotto un supporto ESLint pronto all'uso che include un plug-in personalizzato e una configurazione condivisibile per semplificare l'individuazione di problemi comuni specifici del framework durante lo sviluppo e la fase di creazione. Questo può aiutare gli sviluppatori a risolvere problemi significativi al momento della creazione. Ad esempio, quando un determinato componente viene utilizzato, o non utilizzato, in un modo che potrebbe influire negativamente sulle prestazioni, come indicato in Nessun link HTML per la pagina. Oppure, un determinato carattere, foglio di stile o script può influire negativamente sul caricamento delle risorse in una pagina. Ad esempio, Nessuno script sincrono.

Oltre a ESLint, il controllo dei tipi integrato sia in fase di sviluppo che in produzione è supportato in Next.js sin dalla versione 9, con supporto TypeScript. Più componenti forniti dal framework (Image, Script, Link) sono stati creati come estensione degli elementi HTML (<img>, <script>, <a>) per fornire agli sviluppatori un approccio efficace per aggiungere contenuti a una pagina web. Il controllo dei tipi supporta un utilizzo appropriato di queste funzionalità garantendo che le proprietà e le opzioni assegnate rientrino nell'ambito accettabile di valori e tipi supportati. Per un esempio, consulta Altezza e larghezza dell'immagine obbligatorie.

Rilevare errori con toast e sovrapposizioni

Come accennato in precedenza, le regole di conformità possono essere presenti in più aree. Toast e overlay sono attualmente in fase di analisi per mostrare gli errori direttamente nel browser all'interno dell'ambiente di sviluppo locale dell'utente.

Errori emersi tramite
toast

Molti strumenti di controllo e controllo degli errori su cui gli sviluppatori si affidano (Lighthouse, scheda Problemi di Chrome DevTools) sono passivi e richiedono un qualche tipo di interazione dell'utente per recuperare le informazioni. Gli sviluppatori sono più propensi ad agire quando gli errori vengono emersi direttamente all'interno dei loro strumenti esistenti e quando forniscono azioni concrete e specifiche da intraprendere per risolvere il problema.

Conformità in altri framework

La conformità è attualmente in fase di analisi in Next.js con l'obiettivo di estenderla ad altri framework (Nuxt, Angular e così via). ESLint e TypeScript sono già utilizzati in molti framework in molti modi diversi, ma il concetto di sistema di runtime coeso a livello di browser è attualmente in fase di esplorazione.

Conclusione

La conformità codifica le best practice in set di regole utilizzabili dagli sviluppatori come semplici pattern di codice. Il team di Aurora si è concentrato sulle prestazioni di caricamento, ma altre best practice, come accessibilità e sicurezza, sono altrettanto applicabili.

Il rispetto delle regole di conformità dovrebbe comportare risultati prevedibili, mentre raggiungere un livello elevato di esperienza utente può diventare un effetto collaterale della creazione sul tuo stack tecnico. La conformità rende i team produttivi e garantisce un livello qualitativo di alta qualità per l'applicazione, anche con la crescita di team e codebase nel tempo.