Aurelia vs. Angular 2 – Ein Code-Vergleich

Veröffentlicht: 2022-03-11

Angular und Aurelia, Nachkommen des guten alten JavaScript Angular 1, sind erbitterte Konkurrenten, die ungefähr zur gleichen Zeit und mit einer ähnlichen Philosophie entwickelt und veröffentlicht wurden, sich aber in einigen wichtigen Punkten unterscheiden. In diesem Artikel werden wir diese Unterschiede in Funktionen und Code nebeneinander vergleichen.

Um es kurz zu machen, Aurelia wurde von Rob Eisenberg erschaffen, bekannt als der Schöpfer von Durandal und Caliburn. Er arbeitete im Angular 2-Team bei Google, verließ es jedoch 2014, als seine Ansichten darüber, wie ein modernes Framework aussehen sollte, von ihren abwichen.

Die Ähnlichkeiten bleiben auch auf technischer Ebene bestehen: Vorlagen und die damit verbundenen Komponenten (oder benutzerdefinierten Elemente) sind der Kern von Angular- und Aurelia-Apps, und beide erfordern, dass Sie eine Root-Komponente (dh die App) haben. Darüber hinaus verwenden sowohl Angular als auch Aurelia stark Dekoratoren für die Komponentenkonfiguration. Jede Komponente hat einen festen Lebenszyklus, in den wir uns einklinken können.

Was ist also der Unterschied zwischen Aurelia und Angular 2?

Der Hauptunterschied liegt laut Rob Eisenberg im Code: Aurelia ist unauffällig. Wenn Sie eine Aurelia-App entwickeln (nach der Konfiguration), schreiben Sie in ES6 oder TypeScript, und die Vorlagen sehen wie absolut vernünftiges HTML aus, insbesondere im Vergleich zu Angular. Aurelia ist Konvention über Konfiguration, und in 95 % der Fälle werden Sie mit Standardkonventionen (z. B. Vorlagenbenennung, Elementbenennung usw.) gut zurechtkommen, während Angular von Ihnen verlangt, dass Sie für praktisch alles eine Konfiguration bereitstellen.

Aurelia gilt auch als standardkonformer, schon allein deshalb, weil es bei HTML-Tags nicht zwischen Groß- und Kleinschreibung unterscheidet, während Angular 2 dies tut. Das bedeutet, dass Angular 2 sich nicht auf den HTML-Parser des Browsers verlassen kann, also haben sie einen eigenen erstellt.

Ein weiterer Faktor, der bei der Wahl zwischen SPA-Frameworks zu berücksichtigen ist, ist die Gemeinschaft – das Ökosystem – um sie herum. Sowohl Angular als auch Aurelia verfügen über alle Grundlagen (Router, Template-Engine, Validierung usw.), und es ist einfach, ein natives Modal zu erhalten oder eine Bibliothek eines Drittanbieters zu verwenden, aber es ist keine Überraschung, dass Angular eine größere Community und eine größere Entwicklung hat Mannschaft.

Während beide Frameworks Open Source sind, wird Angular außerdem hauptsächlich von Google entwickelt und soll nicht kommerzialisiert werden, während Durandal, Inc., das das Kernteam beschäftigt, dem Monetarisierungsmodell von Ember.js durch Beratung und Schulung folgt.

Aurelia vs. Angular: Ein Code-Vergleich

Schauen wir uns einige der bemerkenswertesten Merkmale an, die die Philosophien hinter jedem Framework unterstreichen.

Nach dem Klonen von Seed-Projekten für Angular und Aurelia haben wir eine ES6-Aurelia-App (Sie können Jspm/System.js, Webpack und RequireJS in Kombination mit ES6 oder TypeScript verwenden) bzw. eine TypeScript-Angular-App (WebPack).

Auf geht's.

Datenbindung

Bevor wir Arbeitsbeispiele nebeneinander vergleichen, müssen wir uns einige syntaktische Unterschiede zwischen Aurelia und Angular 2 ansehen, nämlich in der Schlüsselfunktionalität, Werte vom Controller an die Ansicht zu binden. Angular 1 nutzte für alles „Dirty Checking“, eine Methode, die den Umfang nach Änderungen durchsuchte. Dies führte verständlicherweise zu einer Reihe von Leistungsproblemen. Weder Angular 2 noch Aurelia folgten diesem Weg. Stattdessen verwenden sie die Ereignisbindung.

Datenbindung in Angular 2

In Angular binden Sie Daten mit eckigen Klammern und verwenden Klammern, um Ereignisse zu binden, wie folgt:

 <element [property]="value"></a> <element (someEvent)="eventHandler($event)"></a>

Die bidirektionale Bindung – wenn Sie möchten, dass Änderungen in den Anwendungsdaten in der Ansicht widergespiegelt werden und umgekehrt – ist eine Kombination aus eckigen und runden Klammern. Für eine bidirektionale gebundene Eingabe würde dies also gut funktionieren:

 <input type="text" [(ngModel)]="text"> {{text}}

Mit anderen Worten, Klammern stellen ein Ereignis dar, während eckige Klammern einen Wert darstellen, der an die Eingabe geschoben wird.

Das Angular-Team hat großartige Arbeit geleistet, indem es die Bindungsrichtungen getrennt hat: zum DOM, vom DOM und bidirektional. Es gibt auch eine Menge Syntaxzucker im Zusammenhang mit Bindungsklassen und -stilen. Betrachten Sie zum Beispiel das folgende Snippet als Beispiel für eine unidirektionale Bindung:

 <div [class.red-container]="isRed"></div> <div [style.width.px]="elementWidth"></div>

Aber was ist, wenn wir bidirektionale Daten in eine Komponente binden wollen? Betrachten Sie die folgende grundlegende Eingabekonfiguration:

 <!-- parent component --> <input type="text" [(ngModel)]="text"> {{ text }} <my-component [(text)]="text"></my-component> import {Component, Input} from '@angular/core'; @Component(/* ... */) export class MyComponent { @Input() text : string; } <!-- child component --> <input [(ngModel)]="text"> Text in child: {{ text }}

Beachten Sie, dass Ihr Modul zur Verwendung von ngModel FormsModule aus @angular/forms importieren muss. Jetzt haben wir etwas Interessantes. Das Aktualisieren des Werts in der übergeordneten Eingabe ändert die Werte überall, aber das Ändern der Eingabe des untergeordneten Elements wirkt sich nur auf dieses untergeordnete Element aus. Wenn wir möchten, dass der übergeordnete Wert aktualisiert wird, benötigen wir ein Ereignis, das den übergeordneten Wert informiert. Die Namenskonvention für dieses Ereignis ist property name + 'Change' , etwa so:

 import {Component, Input, Output, EventEmitter} from '@angular/core'; @Component(/* ... */) export class MyComponent { @Input() text : string; @Output() textChange = new EventEmitter(); triggerUpdate() { this.textChange.emit(this.text); } }

Die bidirektionale Bindung beginnt direkt nach der Bindung an das ngModelChange Ereignis ordnungsgemäß zu funktionieren:

 <!-- child component --> <input [(ngModel)]="text" (ngModelChange)="triggerUpdate($event)">

Was ist mit der einmaligen Bindung, wenn Sie das Framework effektiv anweisen, die gebundenen Werte zu ignorieren, selbst wenn sie sich ändern?

In Angular 1 haben wir {{::value}} verwendet, um einmal zu binden. In Angular 2 wird die einmalige Bindung kompliziert: Die Dokumentation besagt, dass Sie das Attribut changeDetection: ChangeDetectionStrategy.OnPush in der Konfiguration der Komponente verwenden können, aber dadurch werden alle Ihre Bindungen einmalig.

Datenbindung: Der Aurelia-Weg

Im Gegensatz zu Angular 2 ist das Binden von Daten und Ereignissen in Aurelia wirklich einfach. Sie können entweder die Interpolation verwenden, genau wie Angulars property="${value}" , oder einen der folgenden Bindungstypen verwenden:

 property.one-time="value" property.one-way="value" property.two-way="value"

Die Namen sind selbsterklärend. Darüber hinaus gibt es property.bind="value" , ​​einen Syntaxzucker, der selbst erkennt, ob die Bindung in eine Richtung oder in beide Richtungen erfolgen soll. Erwägen:

 <!-- parent--> <template bindable="text"> <input type="text" value.bind="text"/> <child text.two-way="text"></child> </template> <!-- child custom element --> <template bindable="text"> <input type="text" value.bind="text"/> </template>

Im obigen Snippet sind sowohl @bindable als @Input konfigurierbar, sodass Sie Dinge wie den Namen der zu bindenden Eigenschaft usw. einfach ändern können.

Was ist mit Veranstaltungen? Um sich an Ereignisse in Aurelia zu binden, verwenden Sie .trigger und .delegate . Um beispielsweise eine untergeordnete Komponente ein Ereignis auslösen zu lassen, können Sie Folgendes tun:

 // child.js this.element.dispatchEvent(new CustomEvent('change', { detail: someDetails }));

Dann, um im Elternteil darauf zu hören:

 <child change.trigger="myChangeHandler($event)"></child> <!-- or --> <child change.delegate="myChangeHandler($event)"></child>

Der Unterschied zwischen diesen beiden besteht darin, dass .trigger einen Ereignishandler für dieses bestimmte Element erstellt, während .delegate einen Listener für document hinzufügt. Dies spart Ressourcen, funktioniert aber offensichtlich nicht für nicht sprudelnde Ereignisse.

Ein grundlegendes Beispiel für Aurelia vs. Angular

Nachdem wir nun die Bindung behandelt haben, erstellen wir eine grundlegende Komponente, die eine skalierbare Vektorgrafik (SVG) rendert. Es wird fantastisch, deshalb nennen wir es awesome-svg . Diese Übung veranschaulicht sowohl die grundlegende Funktionalität als auch die Philosophie für Aurelia und Angular 2. Die Aurelia-Codebeispiele dieses Artikels sind auf GitHub verfügbar.

Beispiel für SVG-Rechtecke in Aurelia

Lassen Sie uns zuerst die JavaScript-Datei erstellen:

 // awesome-svg.js import {bindable} from 'aurelia-framework'; export class AwesomeSvgCustomElement { @bindable title; @bindable colors = []; }

Nun zum HTML.

In Aurelia können Sie die Vorlage (oder die Inline-Vorlage) mit den Anmerkungen @template , @inlineView oder sogar @noView , aber standardmäßig sucht es nach der .html -Datei mit demselben Namen wie die .js Datei. Dasselbe gilt für den Namen des benutzerdefinierten Elements – Sie können ihn mit @customElement('awesome-svg') , aber wenn Sie dies nicht tun, konvertiert Aurelia den Titel in dash-case und sucht nach einer Übereinstimmung.

Da wir nichts anderes angegeben haben, heißt das Element awesome-svg und Aurelia sucht nach der Vorlage mit demselben Namen wie die js -Datei (dh awesome-svg.html ) im selben Verzeichnis:

 <!-- awesome-svg.html --> <template> <h1>${title}</h1> <svg> <rect repeat.for="color of colors" fill.bind="color" x.bind="$index * 100" y="0" width="50" height="50"></rect> </svg> </template>

Beachten Sie das <template> -Tag? Alle Vorlagen müssen in ein <template> -Tag eingeschlossen werden. Bemerkenswert ist auch, dass Sie ` for … of and the string interpolation ${title}` verwenden, genau wie Sie es in ES6 tun.

Um die Komponente jetzt zu verwenden, sollten wir sie entweder in eine Vorlage mit <require from="path/to/awesome-svg"></require> importieren oder, wenn sie in der gesamten App verwendet wird, die Ressource in der Konfigurationsfunktion des Frameworks globalisieren mit aurelia.use.globalResources('path/to/awesome-svg'); , wodurch die awesome-svg Komponente ein für alle Mal importiert wird.

[Beachten Sie, wenn Sie nichts davon tun, wird <awesome-svg></awesome-svg> wie jedes andere HTML-Tag ohne Fehler behandelt.]

Sie können die Komponente anzeigen mit:

 <awesome-svg colors.bind="['#ff0000', '#00ff00', '#0000ff']"></awesome-svg>

Dies rendert einen Satz von 3 Rechtecken:

Beispiel für SVG-Rechtecke in Aurelia

Beispiel für SVG-Rechtecke in Angular 2

Lassen Sie uns nun dasselbe Beispiel in Angular 2 ausführen, das auch auf GitHub verfügbar ist. Angular 2 erfordert, dass wir sowohl die Vorlage als auch den Elementnamen angeben:

 // awesome-svg.component.ts import {Component, Input} from '@angular/core'; @Component({ selector: 'awesome-svg', templateUrl: './awesome-svg.component.html' }) export class AwesomeSvgComponent { @Input() title : string; @Input() colors : string[] = [] }

Bei der Ansicht wird es etwas kompliziert. Zunächst einmal behandelt Angular unbekannte HTML-Tags stillschweigend wie ein Browser: Es gibt einen Fehler aus, der besagt, dass etwas in der Art von my-own-tag ein unbekanntes Element ist. Das Gleiche gilt für alle Eigenschaften, die Sie binden. Wenn Sie also irgendwo im Code einen Tippfehler hätten, würde dies große Aufmerksamkeit erregen, da die App abstürzen würde. Klingt gut, oder? Ja, weil Sie es sofort bemerken würden, wenn Sie die App kaputt machen würden, und nein, weil dies nur ein schlechter Stil ist.

Betrachten Sie dieses Snippet, das in Bezug auf die Bindungssyntax vollkommen in Ordnung ist:

 <svg> <rect [fill]="color"></rect> </svg>

Obwohl es gut liest, erhalten Sie eine Fehlermeldung wie „Kann nicht an ‚fill‘ binden, da es keine bekannte Eigenschaft von ‚:svg:rect‘ ist.“ Um dies zu beheben, müssen Sie stattdessen die Syntax [attr.fill]="color" verwenden. Beachten Sie auch, dass es erforderlich ist, den Namespace in untergeordneten Elementen innerhalb von <svg/>: <svg:rect> anzugeben, damit Angular weiß, dass dies nicht als HTML behandelt werden sollte. Erweitern wir unser Snippet:

 <!-- awesome-svg.component.html--> <h1>{{ title }}</h1> <svg> <rect *ngFor="let color of colors; let i = index" [attr.fill]="color" [attr.x]="i * 100" y="0" width="50" height="50" ></rect> </svg>

Na, bitte. Als nächstes importieren Sie es in die Modulkonfiguration:

 @NgModule({ declarations: [ AwesomeSvgComponent ] //... })

Jetzt kann die Komponente in diesem Modul wie folgt verwendet werden:

 <awesome-svg [colors]="['#ff0000', '#00ff00', '#0000ff']" title="Rectangles"></awesome-svg> 

Beispiel für SVG-Rechtecke in AngularJS 2

Benutzerdefinierte Elemente

Angenommen, wir möchten, dass unser Rectangle-Code eine benutzerdefinierte Komponente mit eigener Logik ist.

Benutzerdefinierte Elemente: Der eckige 2-Wege

Da Angular 2 Komponenten nach dem rendert, was mit seinem definierten Selektor übereinstimmt, ist es extrem einfach, eine benutzerdefinierte Komponente zu definieren, wie folgt:

 @Component({ selector: 'g[custom-rect]', ... })

Das obige Snippet würde das benutzerdefinierte Element in beliebige <g custom-rect></div> -Tags rendern, was äußerst praktisch ist.

Benutzerdefinierte Elemente: Der Aurelia-Weg

Mit Aurelia können wir benutzerdefinierte Elemente erstellen, die nur aus Vorlagen bestehen:

 <template bindable="colors, title"> <h1>${title}</h1> <svg> <rect repeat.for="color of colors" fill.bind="color" x.bind="$index * 100" y="0" width="50" height="50"></rect> </svg> </template>

Das benutzerdefinierte Element wird in Bezug auf den Dateinamen benannt. Der einzige Unterschied zur Benennung anderer Komponenten besteht darin, dass Sie beim Importieren entweder in configure oder über das <require> -Tag .html an das Ende setzen sollten. Also zum Beispiel: <require from="awesome-svg.html"></require> .

Aurelia hat auch benutzerdefinierte Attribute, aber sie dienen nicht demselben Zweck wie in Angular 2. In Aurelia können Sie beispielsweise die Annotation @containerless für das benutzerdefinierte rect -Element verwenden. @containerless kann auch mit benutzerdefinierten Vorlagen ohne den Controller und <compose> verwendet werden, was im Grunde Dinge in das DOM rendert.

Betrachten Sie den folgenden Code, der die Annotation @containerless enthält:

 <svg> <custom-rect containerless></custom-rect> </svg>

Die Ausgabe würde das benutzerdefinierte Element-Tag ( custom-rect ) nicht enthalten, stattdessen erhalten wir:

 <svg> <rect ...></rect> </svg>

Dienstleistungen

In Bezug auf die Dienste sind sich Aurelia und Angular sehr ähnlich, wie Sie in den folgenden Beispielen sehen werden. Angenommen, wir brauchen NumberOperator , der von NumberGenerator abhängt.

Dienstleistungen in Aurelia

So definieren Sie unsere beiden Dienste in Aurelia:

 import {inject} from 'aurelia-framework'; import {NumberGenerator} from './number-generator' export class NumberGenerator { getNumber(){ return 42; } } @inject(NumberGenerator) export class NumberOperator { constructor(numberGenerator){ this.numberGenerator = numberGenerator; this.counter = 0; } getNumber(){ return this.numberGenerator.getNumber() + this.counter++; } }

Jetzt spritzen wir für eine Komponente auf die gleiche Weise ein:

 import {inject} from 'aurelia-framework'; import {NumberOperator} from './_services/number-operator'; @inject(NumberOperator) export class SomeCustomElement { constructor(numberOperator){ this.numberOperator = numberOperator; //this.numberOperator.getNumber(); } }

Wie Sie sehen können, kann jede Klasse mit Dependency Injection ein vollständig erweiterbarer Dienst sein, sodass Sie sogar Ihre eigenen Resolver schreiben können.

Fabriken in Aurelia

Wenn Sie eine Factory oder eine neue Instanz benötigen ( Factory und NewInstance sind nur ein paar beliebte Resolver, die standardmäßig bereitgestellt werden), können Sie Folgendes tun:

 import { Factory, NewInstance } from 'aurelia-framework'; @inject(SomeService) export class Stuff { constructor(someService, config){ this.someService = someService; } } @inject(Factory.of(Stuff), NewInstance.of(AnotherService)) export class SomethingUsingStuff { constructor(stuffFactory, anotherService){ this.stuff = stuffFactory(config); this.anotherServiceNewInstance = anotherService; } }

Eckige Dienste

Hier ist der gleiche Satz von Diensten in Angular 2:

 import { Injectable } from '@angular/core'; import { NumberGenerator } from './number-generator'; @Injectable() export class NumberGenerator { getNumber(){ return 42; } } @Injectable() export class NumberOperator { counter : number = 0; constructor(@Inject(NumberGenerator) private numberGenerator) { } getNumber(){ return this.numberGenerator.getNumber() + this.counter++; } }

Die Annotation @Injectable ist erforderlich, und um einen Dienst tatsächlich einzufügen, müssen Sie den Dienst in der Liste der Anbieter in der Komponentenkonfiguration oder der gesamten Modulkonfiguration wie folgt angeben:

 @Component({ //... providers: [NumberOperator, NumberGenerator] })

Oder, nicht empfohlen, Sie können es auch im bootstrap(AppComponent, [NumberGenerator, NumberOperator]) Aufruf angeben.

Beachten Sie, dass Sie sowohl NumberOperator als auch NumberGenerator angeben müssen, unabhängig davon, wie Sie es einfügen.

Die resultierende Komponente sieht in etwa so aus:

 @Component({ //... providers: [NumberOperator, NumberGenerator], }) export class SomeComponent { constructor(@Inject(NumberOperator) public service){ //service.getNumber(); } }
Fabriken in Angular 2

In Angular 2 können Sie Factorys mit der provide -Annotation erstellen, die auch für Aliasing-Dienste verwendet wird, um Namenskollisionen zu vermeiden. Das Erstellen einer Factory könnte wie folgt aussehen:

 let stuffFactory = (someService: SomeService) => { return new Stuff(someService); } @Component({ //... providers: [provide(Stuff, {useFactory: stuffFactory, deps: [SomeService]})] })

Transklusion

Angular 1 hatte die Möglichkeit, Inhalte, einen „Slot“, von einer Vorlage in eine andere einzufügen, indem Transklusion verwendet wurde. Mal sehen, was seine Nachkommen zu bieten haben.

Inhaltsprojektion mit Angular 2

In Angular 2 wird die Transklusion „Inhaltsprojektion“ genannt und funktioniert genauso wie ng-transclude ; Das heißt, in Angular 1-Begriffen gesprochen, verwendet der transkludierte Inhalt den übergeordneten Gültigkeitsbereich. Es stimmt mit dem transkludierten Inhaltstag basierend auf dem Konfigurationsselektor überein. Erwägen:

 @Component({ selector: 'child', template: `Transcluded: <ng-content></ng-content>` }) export class MyComponent {}

Sie können die Komponente dann mit <child-component>Hello from Translusion Component</child-component> , und wir erhalten genau das transkludierte Yes -HTML, das in der untergeordneten Komponente gerendert wird.

Für Multi-Slot-Transklusion verfügt Angular 2 über Selektoren, die Sie auf die gleiche Weise verwenden können wie für die @Component Konfiguration:

 <!-- child.component.html --> <h4>Slot 1:</h4> <ng-content select=".class-selector"></ng-content> <h4>Slot 2:</h4> <ng-content select="[attr-selector]"></ng-content>
 <!-- parent.component.html --> <child> <span class="class-selector">Hello from Translusion Component</span> <p class="class-selector">Hello from Translusion Component again</p> <span attr-selector>Hello from Translusion Component one more time</span> </child> 

Steckplätze in Angular2

Sie können select für Ihre benutzerdefinierten Tags verwenden, aber denken Sie daran, dass das Tag Angular 2 bekannt sein muss.

Spielautomaten mit Aurelia

Erinnern Sie sich, als ich sagte, dass Aurelia Webstandards einhält, wann immer dies möglich ist? In Aurelia wird Transklusion Slots genannt und ist nur ein Polyfill für Web Components Shadow DOM. Shadow DOM wurde noch nicht für Slots erstellt, folgt aber den W3C-Spezifikationen.

 <!-- child --> <template> Slot: <slot></slot> </template> <!-- parent --> <template> <child>${textValue}</child> </template>

Aurelia wurde entwickelt, um standardkonform zu sein, und Angular 2 war es nicht. Infolgedessen können wir mit Aurelias Slots weitere großartige Dinge tun, z. B. Fallback-Inhalte verwenden (der Versuch, Fallback-Inhalte in Angular 2 zu verwenden, schlägt mit <ng-content> element cannot have content fehl). Erwägen:

 <!-- child --> <template> Slot A: <slot name="slot-a"></slot> <br /> Slot B: <slot name="slot-b"></slot> Slot C: <slot name="slot-c">Fallback Content</slot> </template> <!-- parent --> <template> <child> <div slot="slot-a">A value</div> <div slot="slot-b">B value</div> </child> </template>

Auf die gleiche Weise wie Angular 2 rendert Aurelia alle Vorkommen des Slots basierend auf einer Namensübereinstimmung.

Spielautomaten in Aurelia

Es ist auch erwähnenswert, dass Sie sowohl in Aurelia als auch in Angular Vorlagenteile kompilieren und Komponenten dynamisch rendern können (unter Verwendung von <compose> mit view-model in Aurelia oder ComponentResolver in Angular 2).

Schatten-DOM

Sowohl Aurelia als auch Angular unterstützen Shadow DOM.

Verwenden Sie in Aurelia einfach den @useShadowDOM Dekorator und schon kann es losgehen:

 import {useShadowDOM} from 'aurelia-framework'; @useShadowDOM() export class YetAnotherCustomElement {}

In Angular kann dasselbe mit ViewEncapsulation.Native gemacht werden:

 import { Component, ViewEncapsulation } from '@angular/core'; @Component({ //... encapsulation: ViewEncapsulation.Native, }) export class YetAnotherComponent {}

Denken Sie daran zu überprüfen, ob Ihr Browser Shadow DOM unterstützt.

Serverseitiges Rendern

Wir schreiben das Jahr 2017 und serverseitiges Rendern liegt voll im Trend. Sie können Angular 2 bereits im Backend mit Angular Universal rendern, und Aurelia wird dies 2017 haben, wie es in den Neujahrsvorsätzen seines Teams heißt. Tatsächlich gibt es in Aurelias Repo eine lauffähige Demo.

Darüber hinaus verfügt Aurelia seit über einem Jahr über progressive Erweiterungsfunktionen, was Angular 2 aufgrund seiner nicht standardmäßigen HTML-Syntax nicht bietet.

Größe, Leistung und was als nächstes kommt

Obwohl es uns nicht das ganze Bild zeigt, zeichnen DBMonster-Benchmarks mit Standardkonfigurationen und optimierter Implementierung ein gutes Vergleichsbild: Aurelia und Angular zeigen ähnliche Ergebnisse von ungefähr 100 Neu-Renderings pro Sekunde (wie auf einem MacBook Pro getestet). während Angular 1 etwa die Hälfte dieses Ergebnisses zeigte. Sowohl Aurelia als auch Angular übertreffen Angular 1 um etwa das Fünffache und beide liegen 40 % vor React. Weder Aurelia noch Angular 2 haben eine Virtual DOM-Implementierung.

In Bezug auf die Größe ist Angular ungefähr doppelt so fett wie Aurelia, aber die Jungs von Google arbeiten daran: Die Roadmap von Angular beinhaltet die Veröffentlichung von Angular 4 mit Plänen, es kleiner und leichter zu machen und gleichzeitig das Entwicklererlebnis zu verbessern. Es gibt kein Angular 3, und eigentlich sollte die Versionsnummer weggelassen werden, wenn man über Angular spricht, da große Releases alle 6 Monate geplant sind. Wenn Sie sich den Weg ansehen, den Angular von der Alpha-Version zur aktuellen Version genommen hat, werden Sie feststellen, dass er nicht immer mit Dingen wie der Umbenennung von Attributen von Build zu Build usw. kohärent war. Das Angular-Team verspricht, dass Breaking Changes einfach sein werden migrieren.

Ab 2017 plant das Aurelia-Team die Veröffentlichung von Aurelia UX, die Bereitstellung weiterer Integrationen und Tools sowie die Implementierung von serverseitigem Rendering (das seit sehr langer Zeit auf der Roadmap steht).

Angular 2 vs. Aurelia: Geschmackssache

Sowohl Angular als auch Aurelia sind gut, und die Wahl eines gegenüber dem anderen ist eine Frage des persönlichen Geschmacks und der Prioritäten. Wenn Sie eine schlankere Lösung benötigen, ist Aurelia Ihre beste Option, aber wenn Sie Community-Unterstützung benötigen, ist Angular Ihr Gewinner. Es geht nicht um die Frage „Erlaubt mir dieser Rahmen, …?“ weil die Antwort einfach „Ja“ lautet. Sie bieten ungefähr die gleiche Funktionalität, folgen aber unterschiedlichen Philosophien und Stilen sowie einer völlig anderen Herangehensweise an Webstandards.