Die Zahlen zeigen, dass sich das
Wachstum von JavaScript-Code negativ auf die Leistung von Webprojekten auswirkt. Wenn dies weitergeht, werden sehr bald beim Laden der mittleren Seite mindestens 400 KB JS-Code übertragen. Und das ist nur die Menge der übertragenen Daten. Wie andere Textressourcen wird JavaScript-Code fast immer in komprimierter Form übertragen. Die Komprimierung ist wahrscheinlich das einzige, was normalerweise korrekt ausgeführt wird, wenn Code vom Server auf den Client übertragen wird.

Obwohl die Reduzierung der Übertragungszeit bestimmter Ressourcen einen ernsthaften Beitrag zur sogenannten Leistung leistet, hat die Komprimierung leider keinen Einfluss darauf, wie viel Zeit der Browser benötigt, um das Skript nach dem vollständigen Laden zu analysieren und zu verarbeiten .
Wenn der Server 400 KB komprimierten JS-Code an den Client sendet, liegt die tatsächliche Menge an Code, die der Browser nach dem Dekomprimieren der empfangenen Daten verarbeiten muss, im Megabyte-Bereich. Wie gut verschiedene Geräte diese Art von Arbeit erledigen, hängt von den Geräten selbst ab.
Es wurde viel darüber geschrieben, aber wir können nur mit Sicherheit sagen, dass die Zeit, die benötigt wird, um die für seine Zeit übliche Codemenge zu analysieren, zwischen verschiedenen Geräten sehr unterschiedlich ist.
Schauen Sie sich zum Beispiel
dieses einfache Projekt von mir an. Während des Ladens der Seite werden ca. 23 KB unkomprimierter JS-Code an den Client übertragen. Chrome, das auf dem MacBook Pro ausgeführt wird, das Mitte 2017 veröffentlicht wurde, verarbeitet diese relativ kleine Menge an Code in etwa 25 ms. Auf dem
Nokia 2 Android-Smartphone wird eine ähnliche Zahl jedoch auf 190 ms erweitert. Dies bedeutet nicht, dass es sehr klein ist, aber auf jeden Fall wird die Seite schnell genug interaktiv.
Nun eine wichtige Frage. Was denken Sie, wie verwaltet ein einfaches Nokia 2 Smartphone durchschnittlich moderne Seiten? In der Tat - einfach schrecklich. Das Durchsuchen von Webseiten, selbst bei einer schnellen Internetverbindung, zwingt den Benutzer zur Geduld, da das Arbeiten mit Seiten, die mit JavaScript-Code geladen sind, erst nach einer langen Wartezeit möglich wird.
Leistungsübersicht von Nokia 2 beim Anzeigen einer Seite mit einer großen Menge an JS-Code, dessen Verarbeitung den Hauptthread blockiertObwohl sich die Geräte, mit denen sie Webseiten durchsuchen, und die Netzwerke, über die Daten übertragen werden, in den letzten Jahren erheblich verbessert haben, zeigen Studien, dass all diese Verbesserungen durch große Mengen an JS-Code auf den Seiten „aufgefressen“ werden. Wir müssen verantwortungsbewusst mit JavaScript umgehen. Verantwortung beginnt mit einem Verständnis dafür, was wir schaffen und wie wir es tun.
Vergleich der Ideologie von "Sites" und "Anwendungen"
Seltsame Dinge passieren mit ungenauen Begriffen, mit denen wir etwas benennen, obwohl ihre Bedeutung auf einer intuitiven Ebene für alle klar ist. Manchmal überladen wir die Bedeutung des Wortes „Biene“ und nennen es „Bienen“ und Wespen, obwohl der Unterschied zwischen Bienen und Wespen sehr bedeutend ist. Die Berücksichtigung solcher Unterschiede kann dazu führen, dass sich die „Bienen“ und „Wespen“ unterschiedlich verhalten. Zum Beispiel werden wir ein Hornissennest zerstören, aber wenn wir über Bienen sprechen, sind Insekten viel nützlicher und verletzlicher. Ihr Nest am falschen Ort wird wahrscheinlich nicht zerstört, sondern irgendwohin verlegt.
Ähnliche Freiheiten lassen sich bei der Verwendung der Begriffe „Website“ und „Webanwendung“ beobachten. Die Unterschiede zwischen diesen Konzepten sind viel weniger offensichtlich als die Unterschiede zwischen echten Wespen und Honigbienen. Wenn diese Konzepte jedoch kombiniert werden, kann dies zu sehr unangenehmen Konsequenzen führen. Probleme beginnen, wenn wir uns etwas erlauben, je nachdem, ob ein Projekt „nur eine Website“ oder „eine vollständige Webanwendung“ ist. Wenn Sie eine Informationssite für ein Unternehmen erstellen, verlassen Sie sich höchstwahrscheinlich nicht auf ein leistungsstarkes Framework zum Verwalten von DOM-Änderungen oder zum Implementieren des Routings auf dem Client. Zumindest hoffe ich es. Die Verwendung von Tools, die zur Lösung bestimmter Probleme schlecht geeignet sind, schadet nicht nur denjenigen, die die Website nutzen, sondern wirkt sich wahrscheinlich auch stark auf den Entwicklungsprozess aus.
Bei der Entwicklung einer Webanwendung sieht alles anders aus. Wir installieren Pakete, die mit dem Hinzufügen von Hunderten, wenn nicht Tausenden von Abhängigkeiten zum Projekt einhergehen. Darüber hinaus sind wir uns der
Sicherheit einiger von ihnen nicht einmal sicher. Wir schreiben komplexe Konfigurationen für Bundler. Wenn Sie in einer so allgegenwärtigen verrückten Entwicklungsumgebung arbeiten, benötigen Sie Wissen und Aufmerksamkeit, um sicherzustellen, dass das Gesammelte schnell ist und das Projekt dort funktioniert, wo es funktionieren sollte. Führen Sie im Zweifelsfall den
Befehl npm ls --prod im Stammverzeichnis Ihres Projekts aus und
prüfen Sie, ob Sie den Zweck der Verwendung
aller in diesem Befehl angezeigten
Elemente angeben können. Selbst wenn Sie dies tun können, gilt dies nicht für Skripte von Drittanbietern. Ich bin sicher, dass mehrere solcher Skripte auch in Ihrem Projekt verwendet werden.
Wir vergessen, dass sowohl Websites als auch Webanwendungen dieselbe „ökologische Nische“ besetzen. Beide stehen unter dem gleichen Einfluss der Umgebung, die aus einer Vielzahl von Netzwerken und Geräten besteht. Solche Einschränkungen werden nicht verschwinden, wenn wir uns entscheiden, das, was wir entwickeln, als "Anwendung" zu bezeichnen, und die Geräte unserer Benutzer werden nicht auf magische Weise viel schneller, wenn wir die "Website" als "Anwendung" bezeichnen.
Es liegt in unserer Verantwortung herauszufinden, wer das verwendet, was wir erstellen. Wir müssen berücksichtigen, dass die Bedingungen, unter denen verschiedene Benutzer eine Verbindung zum Internet herstellen, von denen abweichen können, auf die wir uns verlassen. Wenn wir etwas erschaffen, müssen wir das Ziel kennen, für das wir es erschaffen, und danach sollten wir entwickeln, was zur Erreichung dieses Ziels beiträgt - auch wenn sich herausstellt, dass die Entwicklung
kein so aufregendes Unterfangen ist .
Dies bedeutet, dass wir unsere Abhängigkeit von JavaScript neu bewerten müssen und dass seine Verwendung, insbesondere zum Nachteil von HTML und CSS, dazu führen kann, dass irrationale Muster verwendet werden, die die Leistung und Zugänglichkeit von Webprojekten beeinträchtigen.
Lassen Sie sich von Frameworks keine irrationalen Muster auferlegen
Ich habe die Entdeckung seltsamer Dinge in Codebasen miterlebt, als ich mit Teams zusammengearbeitet habe, die von Frameworks abhängig waren, um ihnen zu mehr Produktivität zu verhelfen. Viele dieser Funde haben eines gemeinsam: Die Art und Weise, wie sie geschrieben werden, führt häufig zu Problemen mit der Verfügbarkeit und Leistung von Websites. Betrachten Sie beispielsweise die folgende Reaktionskomponente:
import React, { Component } from "react"; import { validateEmail } from "helpers/validation"; class SignupForm extends Component { constructor (props) { this.handleSubmit = this.handleSubmit.bind(this); this.updateEmail = this.updateEmail.bind(this); this.state.email = ""; } updateEmail (event) { this.setState({ email: event.target.value }); } handleSubmit () {
Hier finden Sie einige bemerkenswerte Probleme hinsichtlich der Projektzugänglichkeit:
- Ein Formular, das das
<form>
-Element nicht verwendet, ist kein Formular mehr. Sie können dies beheben, indem Sie einfach die Rolle = "form" des übergeordneten <div>
-Elements <div>
Wenn Sie jedoch ein Formular erstellen und das, was wir sehen, definitiv wie ein Formular aussieht, verwenden Sie das <form>
-Element und legen Sie es entsprechend fest Attribute action
und method
. Das action
spielt hier eine entscheidende Rolle, da es dem Formular ermöglicht, zumindest etwas zu tun, auch wenn JavaScript nicht verfügbar ist (natürlich, wenn die Komponente auf dem Server gerendert wurde). - Das
<span>
kein Ersatz für das <label>
, das einige Funktionen hinsichtlich der Verfügbarkeit von Projekten bietet, über die <span>
nicht verfügt. - Das
<button>
-Element ohne das Attribut type="submit"
ist nur eine Schaltfläche, auf die der daran gebundene Ereignishandler aufruft. Wenn wir vor dem Senden des Formulars etwas mit den Daten tun möchten, müssen wir der Schaltfläche das Attribut type="submit"
onClick
type="submit"
zuweisen und den Code vom onClick
Ereignishandler in den onSubmit
Formularereignishandler verschieben. - Warum sollten Sie übrigens JavaScript verwenden, um E-Mail-Adressen zu überprüfen, während HTML5 uns Steuerelemente zur Verfügung stellt, die das Überprüfen von Eingabedaten in fast allen Browsern unterstützen - bis zu IE10? Hier sehen wir eine verpasste Gelegenheit, die bereits im Browser vorhandene Funktionalität zu nutzen und den entsprechenden Elementtyp sowie das erforderliche Attribut anzuwenden. Beachten Sie jedoch bei der Verwendung solcher Konstruktionen, dass das Einrichten der normalen Interaktion mit Bildschirmleseprogrammen einige Anstrengungen erfordert.
In Anbetracht des oben Gesagten überarbeiten wir den Komponentencode:
import React, { Component } from "react"; class SignupForm extends Component { constructor (props) { this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit (event) {
Die Tatsache, dass diese Komponente nicht nur leichter zugänglich ist, sondern auch weniger JS-Code verwendet wird, um dieselbe Funktionalität wie zuvor zu implementieren. In einer Welt, die buchstäblich in JavaScript ertrunken ist, sollte das Entfernen einiger Codezeilen als etwas Positives angesehen werden. Der Browser bietet uns
viele Möglichkeiten , und wir müssen uns bemühen, diese Möglichkeiten so oft wie möglich zu nutzen.
Ich möchte hier nicht sagen, dass Probleme mit der Zugänglichkeit von Seiten ausschließlich bei Verwendung bestimmter Frameworks auftreten. Ich meine, wenn der Entwickler sich zu sehr auf JavaScript verlässt, wird er einfach viele wichtige HTML- und CSS-Funktionen verpassen. Diese Wissenslücken führen oft zu Fehlern, außerdem vermuten wir diese Fehler nicht einmal. Frameworks können nützliche Tools sein, die die Entwicklerproduktivität steigern. Die ständige Untersuchung der Funktionen grundlegender Webtechnologien ist jedoch äußerst wichtig für die Erstellung praktischer, verwendbarer Produkte, unabhängig von den bei ihrer Entwicklung verwendeten Hilfstools.
Verlassen Sie sich auf die Leistungsfähigkeit der Webplattform und geben Sie Ihren Projekten eine glänzende Zukunft
Da es sich um Frameworks handelt, sollte beachtet werden, dass die Webplattform an sich auch ein riesiges Framework ist. Wie im vorherigen Abschnitt gezeigt, befinden wir uns in einer besseren Position, wenn wir uns bei der Arbeit mit Markup- und Browserfunktionen auf etablierte Muster verlassen können. Eine Alternative zu diesen Standardfunktionen besteht darin, sie erneut zu erfinden. Es ist unnötig zu erwähnen, dass eine solche „Erfindung“ mit erheblichen Schwierigkeiten behaftet ist. Was aber, wenn solche Probleme auf ihre Weise von den Autoren aller von uns installierten JavaScript-Pakete gelöst würden?
▍Einzelseitenanwendungen
Eine der Schwächen von Entwicklern, die sie sich leicht leisten können, ist die Verwendung des Single Page Application (SPA) -Modells, selbst in Projekten, für die dieses Modell nicht geeignet ist. Natürlich profitieren solche Projekte von der Tatsache, dass sie von Benutzern aufgrund des vom Kunden durchgeführten Routings als produktiver wahrgenommen werden. Aber was sind die Nachteile der Verwendung des SPA-Modells? Die integrierten Seitennavigationsfunktionen des Browsers, die auf einem synchronen Modell basieren, bieten dem Projekt eine Menge Vorteile. Eine davon ist, dass die Verwaltung der Besuchsgeschichte durch die Implementierung
komplexer Spezifikationen erfolgt . Benutzer ohne JavaScript,
unabhängig davon ,
ob sie es selbst deaktiviert haben oder nicht , verlieren nicht die Fähigkeit, mit dem Projekt zu arbeiten. Damit eine einseitige Anwendung in Browsern mit deaktiviertem JavaScript verfügbar ist, stellt sich plötzlich heraus, dass dem Server-Rendering erhebliche Aufmerksamkeit geschenkt werden muss.
Vergleich verschiedener Optionen zum Laden einer experimentellen Anwendung auf einen langsamen Kommunikationskanal. Das Rendern der Anwendung auf der linken Seite ist vollständig von JavaScript abhängig. Die Anwendung auf der rechten Seite wird auf dem Server gerendert, verwendet dann jedoch auf dem Client die hydrate () -Methode, um die Komponenten mit dem bereits auf dem Server erstellten Markup zu verbindenHier sehen Sie, dass die Anwendung, die auf dem Client für einige Sekunden gerendert wird, dem Benutzer einen leeren Bildschirm anzeigt und dann die fertige Oberfläche anzeigt.
Eine Anwendung, die auf dem Server gerendert und auf dem Client betriebsbereit gemacht wird, zeigt schnell die Hauptelemente der Schnittstelle an. Sie können sie jedoch ungefähr nach der gleichen Zeit wie die Anwendung verwenden, die vollständig auf dem Client gerendert wird.
Die Verfügbarkeit der Anwendung leidet auch, wenn der auf dem Client befindliche Router den Benutzer nicht darüber informieren kann, was sich auf der angezeigten Seite geändert hat. Dies kann den Benutzer dazu zwingen, sich auf unterstützende Technologien zu verlassen, um herauszufinden, was sich genau auf der Seite geändert hat. Infolgedessen ist die Arbeit des Benutzers mit der Website viel komplizierter.
Außerdem können Sie unseren alten Feind sofort treffen - eine übermäßige Belastung des Systems. Einige Client-Router sind sehr klein. Wenn Sie jedoch ein Projekt in
React erstellen , einen kompatiblen
Router und möglicherweise eine
Bibliothek zum Verwalten des Status der Anwendung verwenden, müssen Sie akzeptieren, dass diese eine bestimmte Menge an Service-Code enthält, von dem Sie nirgendwo etwas bekommen können. In diesem Fall sind es nämlich ungefähr 135 KB eines solchen Codes. Analysieren Sie sorgfältig die Projekte, die Sie erstellen, und prüfen Sie, ob das Client-Routing die zusätzliche Belastung des Systems wert ist. In der Regel ist es besser, das Client-Routing-System abzulehnen.
Wenn Sie sich Sorgen über die Gefühle des Benutzers machen und möchten, dass die Website für ihn schnell erscheint, können Sie sich auf das Attribut
rel = prefetch link verlassen, mit dem Sie das Vorladen von Dokumenten aus derselben Quelle organisieren können. Die Verwendung dieses Attributs hat einen großen Einfluss auf die Verbesserung der Leistung des Projekts, die von den Benutzern wahrgenommen wird, da die mit der Verwendung dieses Attributs verknüpften Seiten beim Klicken auf diese Links sofort aus dem Cache geladen werden. Da das Vorladen von Daten eine niedrige Priorität hat, ist es außerdem unwahrscheinlich, dass es mit wichtigen Ressourcen um die Bandbreite konkurriert.
Der HTML-Code, auf den durch Schreiben / verwiesen wird, wird vorinstalliert, wenn Sie die Hauptseite der Site besuchen. Wenn ein Benutzer auf den entsprechenden Link klickt, wird der HTML-Code sofort aus dem Browser-Cache geladenDas Hauptproblem, das beim Vorladen von Seiten auftreten kann und das Sie beachten müssen, besteht darin, dass sich das Laden möglicherweise als Zeit- und Ressourcenverschwendung herausstellt. Um dies zu lösen, können Sie beispielsweise das kleine
Quicklink- Skript von Google verwenden, um dieses Problem zu beheben. Es wird überprüft, ob der aktuelle Client eine langsame Verbindung verwendet, ob der
Datenspeichermodus aktiviert ist , und standardmäßig können Sie das Vorladen von Materialien aus anderen Quellen als der Seitenquelle vermeiden.
Damit die Website in den Augen der Benutzer, die sie häufig besuchen, schnell angezeigt wird, können Sie
Servicemitarbeiter einsetzen . Sie können unabhängig davon verwendet werden, ob das Projekt ein Client-Routing-System verwendet oder nicht, da Sie mit
einigen Funktionen von Servicemitarbeitern vertraut sind.
Wenn wir das
Routen-Caching mithilfe von Servicemitarbeitern durchführen, erhalten wir viele der gleichen Vorteile, die für das Vorladen von Materialien einiger Links typisch sind, aber wir verfügen über viel umfangreichere Funktionen für die Arbeit mit Anfragen und Antworten. Unabhängig davon, ob Sie Ihre Website als „Anwendung“ wahrnehmen oder nicht, ist die Ausstattung mit einem Servicemitarbeiter wahrscheinlich ein Beispiel für einen der kritischsten JavaScript-Anwendungsfälle unserer Zeit.
▍JavaScript ist nicht für das Layout ausgelegt
Wenn wir ein JS-Paket installieren, mit dem Probleme im Zusammenhang mit Seitenlayouts gelöst werden sollen, müssen wir sehr vorsichtig sein und uns fragen, was wir mit diesem Paket erreichen möchten. CSS wurde
speziell für das Erstellen von Seitenlayouts erstellt. Um es effektiv nutzen zu können, benötigen Sie keine Abstraktionen. Die meisten Aufgaben beim
Erstellen von Layouts, die mit JavaScript gelöst werden sollen, z. B. das
Platzieren von Elementen, das Ausrichten von Elementen, das Anpassen ihrer Größe, z. B. das
Bearbeiten von Text oder sogar das vollständige
Erstellen von Layouts mit JavaScript, können jetzt mithilfe von CSS ausgeführt werden. Moderne Tools zum Erstellen von Layouts wie Flexbox und Grid werden von Browsern gut unterstützt, sodass wir keine Projekte entwickeln müssen, die auf Frameworks für die Arbeit mit Layouts basieren. CSS ist übrigens auch ein Framework. Wenn uns eine Möglichkeit wie
Immobilienanfragen zur Verfügung steht, ist die schrittweise Verbesserung der Grundrisse zur Unterstützung neuer Mittel ihrer Bildung, wie sich herausstellt,
nicht so schwierig .
/* , , , CSS Grid. */ /* @supports , CSS Grid, . */ @supports (display: grid) { /* */ @media (min-width: 40em) { /* CSS Grid */ } }
Die Verwendung von JavaScript zur Lösung der Probleme beim Erstellen von Seitenlayouts und beim Anpassen des Erscheinungsbilds ist keine Neuigkeit. Dies haben wir 2009 getan, als wir in einer Atmosphäre der Selbsttäuschung lebten und sagten, dass jede Site sowohl in IE6 als auch in fortgeschritteneren Browsern dieser Zeit aussehen sollte. Wenn wir heute, im Jahr 2019, Websites weiterentwickeln, damit sie in allen Browsern gleich aussehen, bedeutet dies, dass wir unsere Ziele überdenken müssen. Es wird immer einige Browser geben, die unterstützt werden müssen und die nicht die gleichen Funktionen wie die modernsten Browser haben. Die vollständige externe Ähnlichkeit von Projekten auf allen Plattformen ist nicht nur eine Energieverschwendung, sondern auch ein grundlegender Feind der Idee
fortschreitender Verbesserungen .
Fazit: Ich werde kein JavaScript-Killer
Versteh mich nicht falsch, ich gehöre nicht zu den Feinden von JavaScript. Dank dieser Sprache habe ich eine Karriere aufgebaut, und um ehrlich zu sein, macht mir JavaScript seit mehr als zehn Jahren viel Freude. Wie bei jeder langfristigen Beziehung lerne ich sie umso besser kennen, je mehr Zeit ich mit JavaScript arbeite. Es ist eine ausgereifte Sprache mit vielen Funktionen, die von Jahr zu Jahr besser wird.
Manchmal scheint es mir jedoch, dass bei unserer JavaScript-Beziehung etwas schief gelaufen ist. Ich kritisiere ihn. Genauer gesagt kritisiere ich die derzeitige Tendenz, JavaScript als das Hauptwerkzeug für die Erstellung von Websites zu betrachten, auf das in erster Linie zurückgegriffen wird, ohne auf etwas anderes zu achten. Als ich ein anderes Bundle analysierte, das wie eine verwirrende Weihnachtsgirlande aussah, wurde mir klar, dass das Web mit JavaScript berauscht war. Wir greifen aus fast jedem Grund auf diese Sprache zurück, auch wenn die Umstände dies nicht erfordern. Manchmal denke ich darüber nach, wie schwerwiegend die Konsequenzen dieser Haltung gegenüber JS sein können.
Ich plane, weiterhin über JavaScript und Webentwicklung zu schreiben und weiterhin nach Möglichkeiten zu suchen, Webtechnologien rational einzusetzen. Hoffentlich verbessern wir gemeinsam das moderne Web.
Liebe Leser! Denken Sie, dass das moderne Web wirklich mit JavaScript-Code überladen ist?