Myapp verlängert Urlaub


Ich bin sicher, dass es unter den respektierten Zuschauern diejenigen geben wird, die mich verstehen werden. Tatsache ist, dass mir bei der Fülle an populären Bibliotheken und Frameworks für das Web-Frontend persönlich fast alle Alternativen nicht gefallen . In jeder der Optionen sehe ich erhebliche Nachteile, die mich daran hindern, sie ruhig zu nutzen. Alles fängt immer rosig an: ein interessantes Konzept, Sound auf den ersten Blick, Argumentation in Punkten "für" ... Aber dann stößt alles immer wieder auf redundante Abhängigkeiten, überflüssige Entitäten und Versuche, von den Entwicklern selbst geschaffene Probleme zu lösen. Es wird uns angeboten, eine neue Syntax zu erlernen, neue Ideen zu akzeptieren, eine Reihe von Modewörtern zu lernen und viele "notwendige" Pakete zu installieren. Ok, ich liebe alles Neue und ich liebe kluge Worte. Aber ich bin sehr entmutigt, wenn das, was einfach getan werden kann, anfängt, die Leute fraktal zu komplizieren. Sie haben wahrscheinlich schon die Geständnisse derer gelesen, die wie ich verzweifelt nach gesundem Menschenverstand suchten und beschlossen, ins andere Extrem zu gehen - alles „in Vanille“ zu schreiben. Dies geschah mir, als ich vom Polymer- Projekt enttäuscht war, das unter aktiver Beteiligung von Entwicklern von Google erstellt wurde. Anfangs hat mir alles sehr gut gefallen, das Motto dieser Bewegung lautete „Nutze die Plattform!“, Was für mich bedeutete: „Du solltest im Code nicht tun, was der Browser selbst effizienter macht“. Das Polymer-Team hat viel unternommen, um neue Standards und Funktionen auf Plattformebene einzuführen, und vielen Dank dafür. Als diese Ziele erreicht wurden , begannen sie selbst, ihre eigenen Prinzipien zu verletzen. Und jetzt weigert sich ihre neue Bibliothek ( LitElement ) bereits, direkt im Browser zu arbeiten, ohne eine spezielle Umgebung zu installieren, weil die Jungs sich nicht an die Standards halten ... Ich verfolge weiterhin die Entwicklung von LitElement und sehe sogar offensichtliche Anzeichen dafür, dass diese Streuner auf den wahren Weg zurückkehren, aber ich selbst schon Ich werde es nicht verwenden, weil ich jetzt etwas Besseres habe.

Was denn


Holiday.js ist eine Bibliothek für diejenigen, die alles brauchen, was sie brauchen und nichts extra brauchen. Urlaub - denn für mich ist die Arbeit mit ihr ein Urlaub. Und auch, weil ich es geschrieben habe, hauptsächlich in den Ferien oder im Urlaub. Dennoch ist dies ein sehr ernstes Projekt, mit dessen Hilfe eine ganze Reihe komplexer Anwendungen für das sehr „blutige Unternehmen“ entwickelt werden, das Anfängern des Fahrradbaus Angst einjagt. Ich schreibe auch alle meine persönlichen Projekte auf Holiday.js.

Alles basiert auf der Standardgruppe " Benutzerdefinierte Elemente" und " Schatten-DOM ", wie Sie vielleicht erraten haben, und wenn Sie mit diesen bereits vertraut sind, können Sie es ganz einfach herausfinden.

Ein bisschen über dich
Ich bin 40 Jahre alt. Derzeit bin ich ein führender Webentwickler und F & E-Ingenieur in einem niederländischen Unternehmen, das sich auf Integrationslösungen von IBM spezialisiert hat. Unsere Kunden sind große Unternehmen: Öl, Gas, Tanker, Eisenbahnen - das ist alles. Das Wesentliche meiner Arbeit besteht darin, die Standardfunktionen für große und langsame Unternehmenssysteme zu erweitern und die Benutzererfahrung bei der Arbeit mit ihnen zu verbessern. Einerseits habe ich Onkel in Krawatten, andererseits - ein frischer Wind der Freiheit der modernen Webentwicklung. Dies ist eine interessante Kombination, mit der Sie viele Dinge aus einem neuen Blickwinkel betrachten können. Und ich mag es. Früher habe ich die Rolle eines Startups, eines UX-Ingenieurs, eines Art Direktors eines kleinen Designstudios und vieler anderer ausprobiert. Meine gesamte „Erfahrung“ ist also wie ein Patchwork-Quilt. Das heißt aber nicht, dass ich mich oberflächlich auf alles beziehe, ich finde nur bei vielen Arten von Tätigkeiten ähnliche ingenieurtechnische Prinzipien, die mich vor allem interessieren.

Worum geht es?


Wenn ich selbst einen ähnlichen Artikel lese, um das Interesse nicht zu verlieren, würde ich gerne ein Beispiel für Komponentencode sehen. Da ist er:

import {HdElement} from '../../holiday/core/hd-element.js'; class MyComponent extends HdElement { constructor() { super(); this.state = { imageURL: 'images/photo.jpg', firstName: 'John', secondName: 'Snow', }; } } MyComponent.template = /*html*/ ` <style> :host { display: block; padding: 10px; background - color: #fff; color: #000; } </style> <img bind="src: imageURL" /> <div bind="textContent: firstName"></div> <div bind="textContent: secondName"></div> `; MyComponent.is = 'my-component'; 

Hier sehen wir, dass die Komponente einen bestimmten Status und eine Vorlage mit seltsamen Attributen der " Bind " -Elemente hat. Diese Attribute sind die Hauptmagie: Sie ermöglichen es Ihnen, die Vorlage zu analysieren und eine Kopie des Ergebnisses zur weiteren Verwendung (Klonen) im Speicher zu speichern, OHNE zusätzliche Verarbeitung der Vorlagenzeichenfolge in der JS-Laufzeit, was eine hohe Leistung beim anfänglichen Rendern ergibt, wenn jede Komponente instanziiert wird. Im Gegensatz zu vielen modernen Bibliotheken, in denen der DOM-Teil, für den die Komponente verantwortlich ist, durch die Funktion des Zustands bestimmt wird, ist in Holiday.js eine Vorlage ein Halbzeug, das die anfängliche Struktur definiert und das spätere Binden von Daten mithilfe der üblichen DOM-API und ermöglicht es funktioniert sehr schnell. Wir werden auf das Thema Geschwindigkeit zurückkommen.

Ich werde andere Vorteile auflisten:

  • Maximale Nähe zu nativen APIs, minimale zusätzliche Abstraktionen
  • Syntax für native Vorlagen: Sie müssen kein neues HTML und CSS lernen
  • Um zu beginnen, müssen Sie nichts Zusätzliches installieren, Ihr Projekt verfügt möglicherweise überhaupt nicht über einen node_modules-Ordner
  • Leichtigkeit: Sie werden die Benutzer nicht zwingen, lange auf Downloads zu warten
  • Das Kit enthält globale Statusverwaltung, Routing und eine UI-Bibliothek: Sie werden sich nicht in der Wüste fühlen

Die Hauptprojektdokumentation: https://holiday-js.web.app/

Lebenszyklus


Sehen wir uns die Phasen des Komponentenlebenszyklus an:

 import {HdElement} from '../../holiday/core/hd-element.js'; class LifecycleExample extends HdElement { constructor() { super(); //   : this.state = { name: '', bigName: '', }; /*   ,      DOM  "   ",       .    ,      "defineAccessor": */ this.defineAccessor('name', (name) => { // Some accessor code: this.setStateProperty('name', name); }); /*    ,      DOM               . */ } connectedCallback() { super.connectedCallback(); /*  .    DOM.               . */ } stateUpdated(path) { /*        : */ if (path === 'name') { this.setStateProperty('bigName', this.state.name.toUpperCase()); } } attributeChangedCallback(attributeName, oldValue, newValue) { /*  .      . */ super.attributeChangedCallback(attributeName, oldValue, newValue); } disconnectedCallback() { /*  .    DOM.              */ } } LifecycleExample.template = /*html*/ ` <div bind="textContent: name"></div> <div bind="textContent: bigName"></div> `; /*  HTML-,     : */ LifecycleExample.logicAttributes = [ //   ,         'name', ]; /*     CustomElements: */ LifecycleExample.is = 'lifecycle-example'; 

Muster


Da Vorlagen in Holiday.js nur Standardvorlagenliterale sind, haben Sie die vollständige Freiheit, sie im Projekt zu platzieren und deren Inhalt zu gestalten. Sie können sie in separaten Modulen ablegen, zusammen mit dem Komponentencode definieren oder sie im Handumdrehen aus Daten generieren. Sie können Ausdrücke und Funktionsergebnisse in Vorlagen verwenden. All dies bietet große Möglichkeiten und Meinungsfreiheit. Sie können beispielsweise gängige Stile in eine Vorlage importieren, Variablen verwenden und Werte in CSS berechnen, ohne Präprozessoren zu verwenden, und Vorlagen aus vorgefertigten Teilen zusammenstellen.

Ein wichtiger Teil der Vorlagen für Webkomponenten sind Slots . Mithilfe von Slots können Sie spezielle Stellen im "Schatten" -DOM Ihrer Komponente festlegen, an denen deren direkte Nachkommen im allgemeinen DOM-Baum angezeigt werden. Ein Beispiel:

 <header> <slot name="header"></slot> </header> <div class="toolbar"> <slot name="toolbar"></slot> </div> <div class="content"> <slot></slot> </div> <footer> <slot name="footer"></slot> </footer> 

Platzierung in Slots:

 <my-component> <div slot="header">Header content</div> <toolbar-component slot="toolbar"></toolbar-component> <div>Content of the default slot...</div> <div slot="footer">Footer content...</div> </my-component> 

Wie Sie vielleicht erraten haben, können Sie so Komponentenlayouts erstellen, in denen die gewünschten Module einfach in Zellen sortiert werden können.

Wie oben erwähnt, wird zum dynamischen Binden von Daten und Handlern das Attribut "bind" verwendet:

 <div bind="textContent: content; onclick: on.clicked"></div> 

Verwenden Sie zum Binden von Attributwerten das Symbol "@" am Anfang des Eigenschaftsnamens:

 <div bind="@style: style">Content...</div> 

Weitere Informationen finden Sie im entsprechenden Abschnitt der Dokumentation: https://holiday-js.web.app/?templates

Staatsverwaltung


Innerhalb der Komponente:

 class MyComponent extends HdElement { constructor() { super(); //        : this.state = { content: 'Initial Content', style: 'color: #f00', on: { clicked: () => { console.log('Clicked!'); }, }, }; //       "setStateProperty": window.setTimeout(() => { //   : this.setStateProperty('content', 'Updated Content'); //   : this.setStateProperty({ 'content': 'Updated Content', 'style': 'color: #00f', }); }, 1000); } } 

Um den Status auf der Ebene der gesamten Anwendung zu steuern, wird das HdState-Modul verwendet.
Anwendungsbeispiel:

 import {HdState} from '../../holiday/core/hd-state.js'; //   : HdState.subscribe('ui.loading', (val) => { console.log(val); }); //   : HdState.publish('ui.loading', true); // : HdState.publish({ 'ui.loading': true, 'ui.sidePanelActive': true, }); 

Um mit dem globalen Staat arbeiten zu können, müssen Sie zunächst sein allgemeines Schema festlegen:

 HdState.applyScheme({ ui: { loading: { /*      ,       : */ type: Boolean, //    : value: false, }, sidePanelActive: { type: Boolean, value: false, }, }, user: { authorized: { type: Boolean, value: false, }, name: { type: String, value: null, //          : cache: true, }, }, }); 

Die Schaltung kann auch bequem in separate logische Blöcke unterteilt werden.

Um Speicherverluste zu vermeiden, sollten irrelevante Abonnements wie folgt entsorgt werden:

 let subscription = HdState.subscribe('ui.loading', (val) => { console.log(val); }); window.setTimeout(() => { // Unsubscribe: subscription.remove(); }, 10000); 

Statusdokumentation: https://holiday-js.web.app/?state

Entwicklungswerkzeuge


Der kleinste Einstiegssatz ist ein Texteditor und ein Browser. Ja, das reicht aus, um es zu versuchen. Es sollte beachtet werden, dass in dieser Konfiguration der Browser genau Firefox sein sollte. Es kann ES-Module laden, ohne einen lokalen Server zu verwenden.

Für eine vollständigere Arbeit benötigen Sie git und einen beliebigen Webserver (für die Arbeit mit ES-Modulen in anderen Browsern).

Um die HTML-Syntax und die automatische Vervollständigung in Vorlagenliteralen hervorzuheben, verwende ich die Erweiterung für VS Code, die ursprünglich für die Verwendung mit lit-html entwickelt wurde: https://github.com/pushqrdx/vscode-inline-html

Um den Code vor dem Veröffentlichen zu erstellen, können Sie jeden gängigen Compiler verwenden , z. B. Webpack oder Rollup .

Leistung


Benchmarks für Frameworks sind nicht einfach zu schreiben. Für einen repräsentativen Vergleich müssen Sie sicherstellen, dass Sie vergleichbare Dinge vergleichen und die Auswirkungen von Nebenwirkungen so gering wie möglich halten. Sie sollten also eine klare Vorstellung davon haben, was jeweils „unter der Haube“ passiert. Zunächst müssen Sie entscheiden, welche Parameter gemessen werden sollen. Für uns ist es wichtig:

  1. Startzeit für die Ausführung des Hauptprogramms (Download)
  2. Anfangsrenderingzeit der Komponente
  3. Zeit zum Aktualisieren und Neuzeichnen dieser Komponenten

Leider können wir nicht zuverlässig feststellen, wann der Browser das Programm ausgeführt und das Rendern vollständig abgeschlossen hat. Auf Browserebene gibt es viele eigene Optimierungen, die für uns so etwas wie eine „Black Box“ sind und sich in verschiedenen Engines unterscheiden können. Was wir verwenden können: Leistungs-API , requestAnimationFrame und nicht standardmäßige requestIdleCallback- Methode, die nur in Chrome und Firefox funktioniert. Zum ersten Mal genug.

Womit werden wir Holiday.js vergleichen? Ich habe mit zwei Bibliotheken begonnen: React (wo ohne) und LitElement (ähnliche Technologien im Kern). Sie finden Benchmark-Code in diesen Repositories:

https://github.com/foxeyes/holiday-benchmark
https://github.com/foxeyes/lit-benchmark
https://github.com/foxeyes/react-benchmark

Leider habe ich das Testen der Automatisierung noch nicht abgeschlossen, und das ist auch nicht einfach, da die Automatisierung selbst keine Nebenwirkungen hervorrufen sollte. Im Moment arbeite ich weiter an diesem Problem und bereite mit Puppeteer ein geeignetes Tool vor (eine sehr nützliche Sache, die ich empfehle). In der Zwischenzeit können Sie die Tests im manuellen Modus (Chrome / Firefox) ausprobieren und die Ergebnisse in der Browserkonsole überprüfen. Sie werden sehen, dass Holiday.js in allen Fällen ein selbstbewusster Marktführer ist .

Möglicherweise stellen Sie fest, dass im Fall von React beim Anzeigen von Komponenten ein zusätzlicher div-Container erstellt wird, mit dem die Anzahl der erstellten DOM-Elemente angepasst werden kann. Ich entschied, dass dies zutrifft, da eine Webkomponente immer ein DOM-Element und ein Container ist und die Übereinstimmung der DOM-Baumstrukturen in verschiedenen Tests sehr wichtig ist. Außerdem ist es möglich, unnötige Verschachtelungen in Holiday.js zu vermeiden und die Daten auf die gleiche Weise wie in React anzuzeigen. Wenn Ihnen dieses Problem jedoch umstritten erscheint, achten Sie zunächst auf die Aktualisierungsgeschwindigkeit.

Browser-Unterstützung


Nein, Internet Explorer wird nicht unterstützt. Dies hätte mit gewissen Anstrengungen erreicht werden können (für die 11. Version), aber die Ablehnung der Unterstützung ist eine prinzipielle Position. Erstens glaube ich, dass IE für eine lange Zeit sterben sollte und in unserer Macht steht, dazu beizutragen. Zweitens machen die Befürworter der IE-Unterstützung häufig einen schwerwiegenden logischen Fehler: Der Anteil des IE am gesamten Datenverkehr beträgt nach den aktuellen Caniuse-Daten ~ 1,6% für alle gefundenen Versionen. Und der beliebteste Browser, der den Rest bei weitem übertrifft, ist Mobile Chrome (~ 35%). Wenn Sie IE unterstützen, lehnen Sie es daher bewusst ab, eine große Anzahl von Technologien zu verwenden, die einfach erforderlich sind, um vollständige Anpassungsfähigkeit und Mobilität in Ihren Anwendungen zu implementieren, was einer kleinen Minderheit zuliebe das Leben einer großen Mehrheit der Benutzer erschwert. Oder erhöhen Sie die Kosten für die Entwicklung und Wartung Ihrer Produkte erheblich . Drittens hat Microsoft in letzter Zeit Benutzer aktiv dazu gezwungen, Windows 7 zu verlassen, damit der Anteil des IE-Datenverkehrs in naher Zukunft schneller abnimmt. Ich gebe zu, dass es Fälle gibt, in denen die IE-Unterstützung nicht umgangen werden kann, aber solche Fälle sind viel seltener als bisher angenommen.

Am 15. Januar dieses Jahres hat Microsoft eine Release-Version des neuen Edge auf der Chromium-Engine veröffentlicht. Ab diesem Moment können wir davon ausgehen, dass Holiday.js von Haus aus in allen aktuellen Versionen beliebter Browser unterstützt wird. Für ältere Edge ist eine Polyfüllung erforderlich. Die Möglichkeit, mit Polyfills zu arbeiten, ist in Holiday.js implementiert, das Skript selbst muss jedoch separat verbunden werden.

Minimalismus


Das Konzept von Holiday.js basiert auf Einfachheit und Minimalismus. Eine der wichtigen Phasen bei der Arbeit an diesem Projekt war für mich die Entfernung der Funktionalität , die ich schnell implementieren musste, aber später erkannte, dass ich ohne sie auskommen konnte. Wenn es Ihnen also so vorkommt, als ob etwas wirklich fehlt, fragen Sie sich, ob dies wirklich so ist. Ich habe es für mich selbst folgendermaßen beantwortet: Wenn etwas anderes dringend benötigt wird, ist es besser, eine erweiterte Klasse separat mit der Vererbung von der Hauptklasse zu erstellen. Bisher ist mir dieser Ansatz nicht entgangen. Holiday.js wurde in seinem aktuellen Zustand im Kampf getestet und hat sich bei der Arbeit als sehr positiv erwiesen.

Pläne


Wenn Sie zu diesem Ort lesen, dann wurden meine Bemühungen bereits nicht umsonst ausgegeben. Auch wenn Sie Holiday.js nicht verwenden möchten, können Sie sich zumindest etwas Interessantes an der Arbeit mit Webkomponenten als solchen holen. Ich würde mich sehr freuen, wenn dieses Material den Beginn des Gemeinschaftsaufbaus markiert. Ich freue mich sehr über eine konstruktive Diskussion, Kritik, Fehlerberichte, Pullrequests und natürlich Stars auf GitHub. Natürlich konnte ich nicht alle Aspekte ansprechen und werde gerne Ihre Fragen beantworten. Bitte beachten Sie, dass ich bis jetzt nur an dieser Bibliothek gearbeitet habe und es schwierig ist, alles alleine zu machen, einschließlich Dokumentation, Tests und zugehöriger Tools, parallel zu den Haupt- und Haustierprojekten.

In naher Zukunft jedoch:

  • Mehr Vergleiche mit anderen populären Bibliotheken und Frameworks.
  • Minimalistisches und flexibles PingPong-Testwerkzeug basierend auf Puppeteer
  • Basisprojektgenerator mit Beispielen (Starter Kit)
  • Weiterentwicklung der Dokumentation

Ich drücke die Daumen, drücke "Veröffentlichen" ...

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


All Articles