Konformität im JavaScript-Framework-Ökosystem
In unserem Einführungsblogpost haben wir beschrieben, wie wir beim Entwickeln und Warten von umfangreichen Webanwendungen wie der Google Suche, Google Maps und Google Fotos viel gelernt haben. Wir haben Entwickler davor geschützt, Code zu schreiben, der sich negativ auf die Nutzerfreundlichkeit auswirken kann, und damit bewiesen, dass Frameworks eine wichtige Rolle bei der Verbesserung von Leistung und App-Qualität spielen können.
Intern bei Google haben wir diese Methodik als Konformität bezeichnet. In diesem Artikel wird beschrieben, wie wir planen, dieses Konzept für das JavaScript-Framework-Ökosystem als Open Source zu veröffentlichen.
Was ist Konformität?
Bei Google war die Konformität eine Entwicklung. Die Teams verließen sich auf eine kleine Gruppe von erfahrenen Maintainern, die umfangreiche Code-Reviews durchführten und Probleme meldeten, die sich weit über Korrektheitsfehler hinaus auf die App-Qualität und Wartungsfreundlichkeit auswirkten. Um dies auf wachsende Teams von App-Entwicklern auszuweiten, wurde ein Konformitätssystem entwickelt, um Best Practices auf automatisierte und durchsetzbare Weise zu kodifizieren. So wurde unabhängig von der Anzahl der Code-Mitwirkenden ein gleichbleibend hoher Standard für App-Qualität und Wartbarkeit der Codebasis gewährleistet.
Compliance ist ein System, das dafür sorgt, dass Entwickler auf dem richtigen Weg bleiben. Es schafft Vertrauen und sorgt für vorhersehbare Ergebnisse. Es macht Teams produktiv und wird für die Skalierung entscheidend, wenn Teams wachsen und mehr Funktionen gleichzeitig entwickelt werden. So können sich Entwickler auf die Entwicklung von Produktfunktionen konzentrieren und müssen sich nicht mit Details und der sich ständig verändernden Landschaft in verschiedenen Bereichen wie Leistung, Barrierefreiheit und Sicherheit befassen. Jeder kann die Konformität jederzeit deaktivieren. Sie sollte so anpassbar sein, dass Teams die Möglichkeit haben, alles durchzusetzen, was sie sich vornehmen.
Die Konformität basiert auf starken Standardeinstellungen und umsetzbaren Regeln, die während der Erstellung durchgesetzt werden können. Daraus ergeben sich die folgenden drei Grundsätze.
1. Starke Standardeinstellungen
Ein grundlegender Aspekt der Konformität ist, dass die von Entwicklern verwendeten Tools starke Standardeinstellungen haben. Das bedeutet, dass Lösungen nicht nur in Frameworks integriert sind, sondern auch Framework-Designmuster es einfach machen, das Richtige zu tun, und es erschweren, Anti-Muster zu befolgen. Das Framework unterstützt Entwickler beim Anwendungsdesign und bei der Codestruktur.
Zur Verbesserung der Ladeleistung sollten alle Ressourcen (Schriftarten, CSS, JavaScript, Bilder usw.) optimiert werden. Das ist eine komplexe Aufgabe, bei der es darum geht, Bytes zu entfernen, Roundtrips zu reduzieren und die Elemente zu trennen, die für das erste Rendern, die visuelle Bereitschaft und die Nutzerinteraktion benötigt werden. Dazu gehören beispielsweise das Extrahieren von kritischem CSS und das Festlegen der Priorität für wichtige Bilder.
2. Umsetzbare Regeln
Auch wenn grundlegende Optimierungen vorgenommen wurden, müssen Entwickler weiterhin Entscheidungen treffen. Es gibt ein Spektrum an Möglichkeiten für Optimierungen, je nachdem, wie viel Entwicklereingabe erforderlich ist:
- Standardeinstellungen, für die keine Entwicklereingabe erforderlich ist, z. B. das Inline-Einbinden von kritischem CSS.
- Entwickler müssen die Funktion aktivieren. Sie können beispielsweise eine vom Framework bereitgestellte Bildkomponente verwenden, um die Größe und Skalierung von Bildern festzulegen.
- Entwickler müssen die Funktion aktivieren und anpassen. Sie können beispielsweise wichtige Bilder taggen, damit sie frühzeitig geladen werden.
- Keine spezifische Funktion, sondern Dinge, die weiterhin eine Entscheidung des Entwicklers erfordern. Beispielsweise sollten Sie Schriftarten oder synchrone Skripts vermeiden, die das frühe Rendern verzögern.
Optimierungen, die eine Entscheidung von Entwicklern erfordern, bergen ein Risiko für die Leistung der Anwendung. Wenn Funktionen hinzugefügt werden und Ihr Team wächst, können selbst die erfahrensten Entwickler nicht mit den sich ständig ändernden Best Practices mithalten. Außerdem ist es nicht die beste Nutzung ihrer Zeit. Für die Konformität sind geeignete umsetzbare Regeln ebenso wichtig wie starke Standardeinstellungen, damit die Anwendung auch dann einem bestimmten Standard entspricht, wenn Entwickler weiterhin Änderungen vornehmen.
3. Erstellungszeit
Es ist wichtig, Leistungsprobleme frühzeitig im Entwicklungszyklus zu erkennen und zu vermeiden. Die Entwicklungsphase, bevor Code übernommen wird, ist ideal, um Probleme zu erkennen und zu beheben. Je später ein Problem im Entwicklungszyklus erkannt wird, desto schwieriger und teurer ist es, es zu beheben. Das gilt nicht nur für Korrektheits-, sondern auch für Leistungsprobleme, da viele dieser Probleme nicht rückwirkend behoben werden, sobald sie in die Codebasis aufgenommen wurden.
Derzeit erfolgt das meiste Leistungsfeedback außerhalb des Bandes über die Dokumentation, einmalige Audits oder es wird zu spät über Metrikregressionen nach der Bereitstellung in der Produktion angezeigt. Wir möchten diese Funktion in die Erstellungsphase integrieren.
Konformität in Frameworks
Um eine hohe Ladeleistung zu gewährleisten, müssen die folgenden Fragen beantwortet werden:
- Was ist eine optimale Belastung und welche häufigen Probleme können sich negativ darauf auswirken?
- Welche Lösungen können integriert werden, ohne dass Entwickler eingreifen müssen?
- Wie können wir sicherstellen, dass der Entwickler diese Lösungen nutzt und optimal einsetzt?
- Welche anderen Entscheidungen kann der Entwickler treffen, die sich auf die Ladeleistung auswirken?
- Welche Codemuster können uns frühzeitig bei der Erstellung über diese Entscheidungen (Nr. 3 und 4 oben) informieren?
- Welche Regeln können wir formulieren, um diese Codemuster zu bewerten? Wie können sie dem Entwickler während der Erstellung angezeigt werden, ohne dass sein Workflow unterbrochen wird?
Um das Konformitätsmodell, das wir intern bei Google verwenden, in Open-Source-Frameworks zu integrieren, hat unser Team intensiv mit Next.js experimentiert. Wir freuen uns, unsere verfeinerte Vision und unsere Pläne mit Ihnen zu teilen. Wir haben festgestellt, dass die besten Regeln zur Bewertung von Codemustern eine Kombination aus statischer Codeanalyse und dynamischen Prüfungen sein müssen. Diese Regeln können sich auf mehrere Oberflächen beziehen, darunter:
- ESLint
- TypeScript
- Dynamische Prüfungen auf dem Entwicklungsserver des Nutzers (nach der DOM-Erstellung)
- Modul-Bundler (webpack)
- CSS-Tools (noch in der Testphase)
Da wir Regeln über verschiedene Tools bereitstellen, können wir dafür sorgen, dass sie zusammenhängend sind und auch alle Probleme mit der Nutzerfreundlichkeit abdecken, die sich direkt auf die Ladeleistung auswirken. Außerdem können diese Regeln Entwicklern zu unterschiedlichen Zeiten angezeigt werden:
- Während der lokalen Entwicklung auf dem Entwicklungsserver werden im Browser und in der IDE des Nutzers Warnungen angezeigt, die Entwickler auffordern, kleine Codeänderungen vorzunehmen.
- Zur Build-Zeit werden ungelöste Probleme im Terminal des Nutzers angezeigt.
Kurz gesagt: Teams wählen Ergebnisse aus, die ihnen wichtig sind, z. B. Core Web Vitals oder die Ladeleistung, und aktivieren entsprechende Regelsätze, die alle Code-Mitwirkenden befolgen müssen.
Das funktioniert zwar sehr gut für neue Projekte, aber es ist nicht einfach, große Codebases zu aktualisieren, damit sie den vollständigen Regelsätzen entsprechen. Bei Google haben wir ein umfangreiches System für das Deaktivieren auf verschiedenen Ebenen, z. B. für einzelne Quellcodezeilen, ganze Verzeichnisse, Legacy-Codebasen oder Teile der App, die nicht aktiv entwickelt werden. Wir arbeiten aktiv an effektiven Strategien, um dies für Teams mit Open-Source-Frameworks zu ermöglichen.
Konformität in Next.js
ESLint ist bei JavaScript-Entwicklern weit verbreitet und über 50% der Next.js-Anwendungen verwenden ESLint in einem Teil ihres Build-Workflows. Mit Next.js v11 wurde die sofort einsatzbereite ESLint-Unterstützung eingeführt, die ein benutzerdefiniertes Plug-in und eine gemeinsam nutzbare Konfiguration umfasst, um häufige frameworkspezifische Probleme während der Entwicklung und Build-Zeit leichter zu erkennen. So können Entwickler wichtige Probleme bereits bei der Erstellung beheben. Ein Beispiel ist, wenn eine bestimmte Komponente so verwendet wird oder nicht verwendet wird, dass die Leistung beeinträchtigt werden könnte, wie im Fall von Kein HTML-Link für Seite. Oder wenn eine bestimmte Schriftart, ein bestimmtes Stylesheet oder ein bestimmtes Skript das Laden von Ressourcen auf einer Seite negativ beeinflussen kann. Beispiel: Kein synchrones Skript.
Zusätzlich zu ESLint wird seit Version 9 in Next.js die integrierte Typüberprüfung in der Entwicklungs- und Produktionsumgebung mit TypeScript-Unterstützung unterstützt. Mehrere vom Framework bereitgestellte Komponenten (Image, Script, Link) wurden als Erweiterung von HTML-Elementen (<img>
, <script>
, <a>
) entwickelt, um Entwicklern eine leistungsstarke Möglichkeit zu bieten, einer Webseite Inhalte hinzuzufügen. Die Typüberprüfung unterstützt die angemessene Verwendung dieser Funktionen, indem sichergestellt wird, dass zugewiesene Eigenschaften und Optionen im zulässigen Bereich der unterstützten Werte und Typen liegen. Ein Beispiel finden Sie unter erforderliche Bildbreite und ‑höhe.
Fehler mit Toasts und Overlays anzeigen
Wie bereits erwähnt, können Konformitätsregeln in mehreren Bereichen angezeigt werden. Wir prüfen derzeit, ob sich Toasts und Overlays eignen, um Fehler direkt im Browser in der lokalen Entwicklungsumgebung des Nutzers anzuzeigen.
Viele Tools zur Fehlerprüfung und ‑behebung, die Entwickler verwenden (Lighthouse, Chrome-Entwicklertools, Tab „Probleme“), sind passiv und erfordern eine Nutzerinteraktion, um Informationen abzurufen. Entwickler reagieren eher, wenn Fehler direkt in ihren vorhandenen Tools angezeigt werden und wenn konkrete und spezifische Maßnahmen zur Behebung des Problems vorgeschlagen werden.
Konformität in anderen Frameworks
Die Konformität wird zuerst in Next.js untersucht. Ziel ist es, sie auf andere Frameworks (Nuxt, Angular usw.) auszuweiten. ESLint und TypeScript werden bereits in vielen Frameworks auf unterschiedliche Weise verwendet. Das Konzept eines kohäsiven Laufzeitsystems auf Browserebene wird jedoch aktiv untersucht.
Fazit
Bei der Konformität werden Best Practices in Regelsätzen zusammengefasst, die für Entwickler als einfache Codemuster umsetzbar sind. Das Aurora-Team hat sich auf die Ladeleistung konzentriert, aber andere Best Practices wie Barrierefreiheit und Sicherheit sind genauso wichtig.
Die Einhaltung der Konformitätsregeln sollte zu vorhersehbaren Ergebnissen führen. Eine hohe Nutzerfreundlichkeit kann sich als Nebeneffekt der Entwicklung auf Ihrem Technologie-Stack ergeben. Die Einhaltung von Standards macht Teams produktiv und sorgt für eine hohe Qualität der Anwendung, auch wenn Teams und Codebases im Laufe der Zeit wachsen.