Die Hauptprobleme bei der Entwicklung moderner Schnittstellen

Hallo Habr! Ich präsentiere Ihnen eine Übersetzung von Dan Abramovs Beitrag „The Elements of UI Engineering“ zu aktuellen Problemen und Aufgaben, die in einer guten Oberfläche gelöst werden müssen. Der Autor untersucht die grundlegenden Probleme bei der Entwicklung von Schnittstellen, deren Interpretation und Lösung allein - ohne Verwendung vorgefertigter Bibliotheken und Frameworks - ein tiefgreifendes Verständnis der auf dem Markt vorhandenen Lösungen im Bereich der Frontend-Entwicklung vermitteln kann.



Anmerkung des Übersetzers
Der Text wird in der ersten Person geschrieben und übersetzt. Der Autor des englischen Originals ist Dan Abramov , der Entwickler der React-Bibliothek zum Erstellen komplexer Benutzeroberflächen.

In meiner letzten Veröffentlichung habe ich darüber geschrieben, wie wichtig es ist, Lücken im eigenen Wissen zu erkennen. Es könnte so ausgesehen haben, als hätte ich Ihnen Ausreden angeboten, um mittelmäßig zu sein. Überhaupt nicht! Tatsächlich ist unser Wissen jedoch ein umfangreiches Gesprächsthema.

Ich bin überzeugt, dass Sie Ihr Wissen „von Anfang an“ beginnen können und es nicht erforderlich ist, Technologie (technologischer Stapel für die Webentwicklung - ca. Übersetzer) in einer bestimmten Reihenfolge zu studieren. Ich glaube aber auch, dass die Anhäufung von Erfahrung und beruflichen Fähigkeiten in dem gewählten Bereich von großer Bedeutung ist. Persönlich war ich immer am meisten daran interessiert, Benutzeroberflächen zu erstellen.

Und ich habe mich gefragt, was ich verstehe und was ich wichtig finde? Natürlich bin ich mit Technologien wie Javascript und React gut vertraut. Die wichtigsten Dinge, die mit Erfahrung einhergehen, sind jedoch schwer fassbar und verschwinden normalerweise, wenn versucht wird, sie genau zu artikulieren. Ich habe nie versucht, sie in Worte zu fassen. Dies ist mein erster Versuch, einige von ihnen zu systematisieren und zu beschreiben.



Heutzutage gibt es viele verschiedene Möglichkeiten, Technologie zu lernen. Auf welche Bibliothek kann man 2019 wetten? Und im Jahr 2020? Soll ich Vue oder React lernen? Oder eckig? Was ist mit Redux oder Rx? Muss ich Apollo lernen? REST oder GraphQL? Hier kann man sich leicht verlaufen! Darüber hinaus kann sich der Autor auch irren.

Meine größten Erkenntniserfolge beziehen sich nicht auf eine bestimmte Technologie. Ich begann mehr zu verstehen, als ich ein bestimmtes Problem mit der Benutzeroberfläche (Benutzeroberfläche - ca. Übersetzer) löste. Gleichzeitig fand ich manchmal die Bibliotheken und Muster anderer Leute, die mir bei der Lösung des Problems halfen. Und manchmal schrieb er seine eigenen Entscheidungen (sowohl gut als auch schrecklich).
Diese Kombination - bestehend aus dem Verstehen des Problems , dem Experimentieren mit Werkzeugen und dem Anwenden verschiedener Lösungen - gab mir die wertvollsten Erfahrungen und Fähigkeiten. Dieser Beitrag konzentriert sich nur auf Themen, mit denen ich mich bei der Entwicklung von Benutzeroberflächen befasst habe.



Wenn Sie Benutzeroberflächen entwickelt haben, sind Sie höchstwahrscheinlich auf einige dieser Probleme gestoßen - direkt oder bei der Verwendung von Bibliotheken. In beiden Fällen empfehle ich, dass Sie an einer einfachen Anwendung ohne Bibliotheken arbeiten und versuchen, diese Probleme zu reproduzieren und zu lösen. Für keinen von ihnen gibt es eine echte Lösung. Erfahrung besteht darin, diese Probleme kennenzulernen und mögliche Lösungen zu finden, wenn man die Stärken und Schwächen der einzelnen Probleme berücksichtigt.

Konsistenz


Sie mochten den Beitrag und die Inschrift erschien: "Sie und 3 weitere Ihrer Freunde haben es geschätzt." Sie haben erneut auf die Schaltfläche "Gefällt mir" geklickt und die Inschrift ist verschwunden. Es klingt einfach! Es ist jedoch möglich, dass eine solche Inschrift an mehreren Stellen auf dem Bildschirm vorhanden ist. Es ist möglich, dass es auch eine zusätzliche visuelle Anzeige für dergleichen gibt (zum Beispiel die Hintergrundfarbe der Schaltfläche), die sich ebenfalls ändern sollte. Die Liste der "Likes", die zuvor vom Server empfangen wurde und angezeigt wird, wenn Sie mit der Maus über die Maus fahren, sollte jetzt Ihren Namen enthalten. Und wenn Sie zu einem anderen Abschnitt gegangen sind oder auf die Schaltfläche Zurück geklickt haben, sollte der Beitrag nicht „vergessen“, dass er Ihnen gefällt. Wie Sie sehen können, führt selbst die lokale Integrität eines einzelnen Benutzers zu einer Reihe schwieriger Aufgaben. Gleichzeitig können andere Benutzer auch mit den Daten interagieren, die bei Ihnen angezeigt werden (z. B. dem Beitrag, den Sie gerade anzeigen). Wie halten wir Daten in verschiedenen Teilen des Bildschirms synchron? Wie und wann sollten wir lokale Daten mit dem Server überprüfen und Änderungen empfangen / senden?

Reaktionsfähigkeit


Menschen lassen das Fehlen von visuellem Feedback für ihre Handlungen nur für eine sehr begrenzte Zeit zu. Bei kontinuierlichen Benutzeraktionen wie dem Scrollen ist die fehlende Reaktion der Anwendung nur für den kürzesten Zeitraum möglich. Selbst das Überspringen eines Frames in 16 Millisekunden sieht bereits fehlerhaft und unvollendet aus. Bei diskreten (einmaligen) Aktionen, wie z. B. einem Klick, nehmen Benutzer laut einigen Studien normalerweise Verzögerungen bei der Reaktion von weniger als 100 Millisekunden wahr. Wenn die Aktion länger dauert, muss eine visuelle Anzeige angezeigt werden. Es gibt jedoch mehrere kontraintuitive Aufgaben. Indikatoren, die eine Verschiebung in der Seitenvorlage verursachen oder mehrere abwechselnde Phasen durchlaufen, können dazu führen, dass das „Fühlen“ der Aktion länger dauert als sie tatsächlich war. In ähnlicher Weise kann sich die Antwort einer Anwendung innerhalb von 20 Millisekunden durch Überspringen eines Frames der Animation langsamer anfühlen als eine vollständige Animation innerhalb von 30 Millisekunden. Unser Bewusstsein funktioniert nicht wie Benchmarks. Wie halten wir Apps ansprechbar?

Reaktionszeit (Latenz)


Computercomputer und das Übertragen von Daten über ein Netzwerk benötigen Zeit. Manchmal können wir die Berechnungszeit ignorieren, wenn sie die Reaktionsfähigkeit auf den Geräten der Benutzer nicht beeinträchtigt (stellen Sie jedoch sicher, dass Sie Ihren Code auf alten und preisgünstigen Geräten getestet haben). Die Verarbeitung der Zeit der Datenübertragung über das Netzwerk kann jedoch nicht vermieden werden - sie kann in Sekunden berechnet werden! Eine Anwendung kann nicht einfach „hängen bleiben“, während wir auf das Laden von Daten oder Code warten. Dies bedeutet, dass jede Aktion, die neue Daten, Code oder Assets erfordert, möglicherweise asynchron ist und den Ladezustand verarbeiten muss. Dies gilt für die überwiegende Mehrheit der Bildschirme und Elemente. Wie kann man die Verzögerung bei der Datenübertragung richtig handhaben, ohne eine Kaskade sich drehender Spinner oder leere "Löcher" in der Schnittstelle anzuzeigen? Wie vermeide ich Seitenlayoutverschiebungen? Und wie kann man asynchrone Abhängigkeiten ändern, ohne dass ständig Code neu geschrieben werden muss?

Navigation


Wir erwarten, dass die Schnittstelle bei der Interaktion mit ihr „stabil“ ist. Elemente sollten nicht plötzlich verschwinden. Die Navigation sowohl innerhalb der Anwendung (z. B. Links) als auch extern (z. B. die Schaltfläche Zurück im Browser) sollte ebenfalls diesem Prinzip entsprechen. Wenn Sie beispielsweise in einem Benutzerabschnitt zwischen den Registerkarten /profile/likes und /profile/follows follow wechseln, sollte der Inhalt des Suchfelds außerhalb dieses Abschnitts nicht ungültig werden. Selbst das Wechseln zu einem anderen Bildschirm sollte wie ein Spaziergang in einen anderen Raum aussehen. Die Leute erwarten, dass sie bei ihrer Rückkehr alle Dinge dort finden, wo sie sie verlassen haben (und vielleicht mit einigen neuen Dingen zufrieden sind). Wenn Sie sich in der Mitte Ihres Bandes befanden, auf die Registerkarte "Profil" geklickt und dann zum Band zurückgekehrt sind, möchten Sie das Band definitiv nicht von Anfang an erneut scrollen oder warten, bis der vergangene Status des Bandes geladen ist. Wie entwerfe ich eine Anwendung für die willkürliche Benutzernavigation, ohne wichtigen Kontext zu verlieren?

Staleness


Wir können die Implementierung der Schaltfläche Zurück sofort durchführen, indem wir der Anwendung einen lokalen Cache hinzufügen. Dazu speichern wir die notwendigen Daten im Cache (Daten aus dem vorherigen Zustand - ca. Übersetzer). Wir können den Cache sogar theoretisch aktualisieren, um die Daten auf dem neuesten Stand zu halten. Die Implementierung von Caching bringt jedoch neue Herausforderungen mit sich. Der Cache ist möglicherweise veraltet. Wenn ich den Avatar geändert habe, sollte er auch im Cache aktualisiert werden. Wenn ich einen neuen Beitrag veröffentlicht habe, sollte er sofort im Cache angezeigt werden, da sonst der Cache ungültig wird. Ein solcher Code kann möglicherweise zu komplex und schwierig zu warten sein. Was ist, wenn der Veröffentlichungsprozess fehlschlägt? Wie lang ist der Cache im Speicher? Wenn wir den Datensatz erneut abrufen, führen wir die neuen Daten früher mit den zwischengespeicherten Daten zusammen oder entfernen wir den alten Cache und zwischenspeichern den gesamten Satz erneut? Wie sollen Paginierung und Sortierung im Cache dargestellt werden?

Entropie


Der zweite Hauptsatz der Thermodynamik lautet ungefähr wie folgt: „Im Laufe der Zeit wird alles zu einem völligen Durcheinander“ (natürlich nicht wörtlich). Dies gilt auch für Benutzeroberflächen. Wir können die Aktionen eines bestimmten Benutzers und deren Reihenfolge nicht vorhersagen. Unsere Anwendung kann sich jederzeit in einem von einer riesigen (gigantischen!) Anzahl verschiedener Zustände befinden. Wir versuchen unser Bestes, um das Ergebnis gemäß unserem Design vorhersehbar und begrenzt zu machen. Wir wollen uns den Screenshot mit dem Fehler nicht ansehen und uns denken: "Wie ist das überhaupt passiert?" Für N mögliche Zustände gibt es N × (N - 1) mögliche Übergänge zwischen ihnen. Wenn beispielsweise fünf verschiedene Zustände für eine Schaltfläche möglich sind (normal, aktiv, schweben, hervorgehoben und deaktiviert), muss der Code, der für das Ändern der Schaltfläche verantwortlich ist, für 5 × 4 = 20 mögliche Übergänge korrekt sein - oder einige davon explizit verbieten. Wie gehen wir mit der kombinatorischen Zunahme möglicher Zustände um und erzeugen vorhersehbare visuelle Ergebnisse?

Priorität


Einige Dinge sind wichtiger als andere. Möglicherweise sollte Ihre Dialogoberfläche streng über der Schaltfläche angezeigt werden, mit der sie aufgerufen wurde, und über den übergeordneten Container hinausgehen. Oder eine gerade geplante Aufgabe (d. H. Das Ergebnis eines Klicks) kann wichtiger sein als eine bereits begonnene Aufgabe mit langer Laufzeit. Wenn die Anwendung vergrößert wird, konkurrieren ihre verschiedenen Teile, die von verschiedenen Personen oder sogar Teams geschrieben wurden, um begrenzte Ressourcen wie Prozessor-Rechenleistung, Netzwerkverkehr, Bildschirmplatz oder Bundle-Größe. Manchmal können Sie Elemente auf einer einzigen Wichtigkeitsskala verteilen, ähnlich wie bei der z-index CSS-Regel. Aber normalerweise endet es nicht mit etwas Gutem . Jeder Entwickler hält seinen Code aufrichtig für wichtig. Aber wenn alles gleich wichtig ist, heißt das - nichts ist wichtig. Wie können wir die unabhängigen Teile der Anwendung interagieren lassen, anstatt um begrenzte Ressourcen zu kämpfen?

Zugänglichkeit


Websites, die nicht für Menschen mit Behinderungen geeignet sind, sind kein hochspezialisiertes Problem. In England ist beispielsweise jeder fünfte Benutzer mit diesem Problem konfrontiert ( hier eine visuelle Infografik). Ich fühlte es an mir. Trotz der Tatsache, dass ich erst 26 Jahre alt bin, verwende ich kaum Websites mit dünnen Schriftarten und einem undurchsichtigen Farbschema. Ich versuche, das Trackpad seltener zu verwenden, habe aber Angst vor dem Tag, an dem ich eine ungeeignete Site für die Tastatur verwenden muss. Wir dürfen unsere Bewerbungen nicht zu einem Albtraum für Menschen mit Behinderungen machen - und die gute Nachricht ist, dass es nicht so schwierig ist. Sie müssen zunächst Lösungen und Tools untersuchen. Darüber hinaus müssen wir es Designern und Entwicklern einfach und verständlich machen, die richtigen Entscheidungen zu treffen. Was können wir tun, um sicherzustellen, dass die Verfügbarkeit unserer Anwendungen standardmäßig aktiviert ist und keine späte Überarbeitung erfolgt?

Internationalisierung


Unsere Anwendungen sollten weltweit funktionieren. Ja, die Leute sprechen verschiedene Sprachen, aber zusätzlich ist die Unterstützung für das Schreiben von rechts nach links und mit minimalem Aufwand der Entwickler erforderlich. Wie können wir verschiedene Sprachen und Skripte unterstützen, ohne die Reaktionsfähigkeit und Reaktionszeit der Anwendung zu verlieren?

Lieferung


Wir müssen den Anwendungscode an den Endbenutzercomputer senden. Welche Übertragungsmethode und welches Format werden wir verwenden? In dieser Frage ist jede Antwort ein Kompromiss mit eigenen Stärken und Schwächen. Zum Beispiel müssen native Anwendungen aufgrund ihrer großen Größe ihren gesamten Code im Voraus herunterladen. Zwar haben Webanwendungen in der Regel viel kürzere Startzeiten, müssen jedoch während der Verwendung viel Latenz und Downloads bewältigen. Wie entscheiden wir, welche Art von Verzögerung aus diesen beiden Optionen ausgewählt werden soll? Wie optimieren wir die Antwortzeiten basierend auf Nutzernutzungsstatistiken? Welche Daten benötigen wir, um die beste Entscheidung zu treffen?

Flexibilität (Belastbarkeit)


Niemand mag es, Fehler in seinen eigenen Programmen zu treffen. Einige Fehler werden jedoch unweigerlich in Produktion gehen. Und es ist sehr wichtig - was wird dann passieren. Einige Fehler verursachen falsches, aber genau definiertes und vordefiniertes Verhalten. Beispielsweise zeigt Ihr Code einen unangemessenen Status für eine bestimmte Bedingung an. Was aber, wenn die Anwendung aufgrund eines Fehlers das Rendern vollständig beendet hat? In diesem Fall können wir die sinnvolle Ausführung des Programms nicht fortsetzen, da die visuelle Ausgabe nicht bestimmt wird. Ein Fehler beim Rendern eines Beitrags aus dem Feed sollte das Rendern des gesamten Feeds nicht „unterbrechen“ oder die Anwendung in einen instabilen Zustand versetzen, was zu weiteren Fehlern führt. Wie können wir Code schreiben, der Fehler beim Rendern oder Empfangen von Daten in einem der Teile isoliert und den korrekten Betrieb des Restes der Anwendung fortsetzt? Was bedeutet Fehlertoleranz beim Erstellen von Benutzeroberflächen?

Abstraktion


In einer kleinen Anwendung können wir alle oben genannten Probleme in der Stirn fest codieren und lösen. Anwendungen wachsen jedoch tendenziell. Wir möchten in der Lage sein , verschiedene Teile der Anwendung wiederzuverwenden, zu teilen und zu kombinieren und dies gemeinsam mit anderen Personen zu tun. Wir wollen verständliche Grenzen zwischen Teilen eines Ganzen definieren, die von verschiedenen Menschen akzeptiert werden, und gleichzeitig zu starre Logik vermeiden, da sie sich im Laufe der Arbeit häufig ändert und weiterentwickelt. Wie erstellen wir Abstraktionen, die die Details der UI-Implementierung verbergen? Wie können wir das Wiederauftreten dieser Probleme mit dem Wachstum der Anwendung vermeiden?



Natürlich gibt es noch viele weitere Probleme, die ich nicht erwähnt habe. Diese Liste ist keineswegs vollständig oder vollständig. Zum Beispiel habe ich das Thema der Zusammenarbeit zwischen Design und Entwicklung, das Thema Debuggen oder Testen nicht angesprochen. Vielleicht werden wir ein anderes Mal darauf zurückkommen.

Es ist verlockend, über diese Probleme zu lesen, wobei als Lösung ein spezifischer Rahmen für die Anzeige von Daten oder eine Bibliothek für den Empfang von Daten in Betracht gezogen wird. Ich empfehle Ihnen jedoch, sich vorzustellen, dass diese Lösungen nicht existieren, und erneut zu lesen. Wie würden Sie versuchen, diese Probleme zu lösen? Versuchen Sie, Ihre Ideen in einer einfachen Anwendung umzusetzen. Ich werde mich freuen, die Ergebnisse Ihrer Experimente mit Github zu sehen. (Markieren Sie einfach Dan Abramov auf Twitter und fügen Sie Links zu Repositories hinzu - ca. Übersetzer).

Was an diesen Problemen besonders interessant ist, ist, dass sich die meisten von ihnen in jeder Größenordnung manifestieren. Sie können ihnen begegnen, wenn Sie an einem kleinen Widget wie einem Tooltip und in großen Anwendungen wie Twitter oder Facebook arbeiten.

Denken Sie an die nicht trivialen Elemente der Benutzeroberfläche der Anwendung, die Sie verwenden möchten, und führen Sie die Liste der oben genannten Probleme erneut durch. Können Sie die Kompromisse beschreiben, die die Entwickler eingegangen sind? Versuchen Sie, ein ähnliches Verhalten von Grund auf neu zu reproduzieren!

Ich habe viel über die Entwicklung guter Benutzeroberflächen gelernt und mit diesen Problemen in kleinen Anwendungen experimentiert, ohne Bibliotheken und Frameworks von Drittanbietern zu verwenden. Ich empfehle dies jedem, der ein tiefes Verständnis für Lösungen und Kompromisse bei der Entwicklung komplexer Schnittstellen erlangen möchte.

Source: https://habr.com/ru/post/de435912/


All Articles