Blog

So beschleunigen Sie Ihre Mendix-App: xas

Autor
CLEVR
Letzte Aktualisierung
June 26, 2025
veröffentlicht
October 1, 2019

Dieser Beitrag ist Teil einer Reihe zur Anwendungsleistung. Um es kurz zusammenzufassen, das vorherige Post stellte ein übergeordnetes Verfahren zur Behandlung von Leistungsproblemen in einer Mendix-Anwendung vor. Außerdem wurde beschrieben, wie und welche Metriken zur bestmöglichen Diagnose von Leistungsproblemen erfasst werden müssen.

Der Schwerpunkt dieses Blogbeitrags wird sein xas. Nun, einige von Ihnen fragen sich wahrscheinlich,

Was um alles in der Welt ist xas?

Wie Sie wahrscheinlich wissen, werden Mendix-Apps so genannt Single-Page-Anwendungen (SPA). Das bedeutet, dass beim Navigieren zwischen verschiedenen Bildschirmen in der App nicht die gesamte Seite neu geladen wird, was ein Gefühl der Reaktionsfähigkeit vermittelt. Natürlich müssen das Layout des Bildschirms und die Daten immer noch irgendwie geladen werden. Das erfolgt mit xas, eine Mendix-Technologie zur Ausführung dynamischer Abfragen (die Teil der Mendix Client API ist).

Mendix verwendet xas, um Seiten, Layouts, Snippets sowie Daten (sowohl per Assoziation als auch aus der Datenbank) abzurufen. Darüber hinaus wird xas auch zum Festschreiben und Löschen persistenter Objekte sowie zum Aufrufen von Mikroflows vom Client verwendet. Angesichts der Tatsache, wie allgegenwärtig XAS-Abfragen sind, ist es kein Wunder, dass sie für die Leistung Ihrer Anwendung sehr wichtig sind.

Wie wirkt sich xas auf die Leistung meiner Mendix-Anwendung aus?

HTTP wird verwendet, um XAS-Anfragen vom Client an den Server weiterzuleiten. Dies bedeutet, dass jede Anfrage mindestens zum Server gesendet, verarbeitet und dann zum Client zurückgesendet werden muss.

Schauen wir uns zunächst die Reisezeit an. Je nach Standort des Servers und des Clients kann allein die Round-Trip-Zeit erheblich sein (50 bis 400 Millisekunden). Sehr oft führt eine XAS-Anfrage zur nächsten, zum Beispiel müssen nach dem Laden einer Seite mit einem Datenraster die nächsten Daten für das Grid geladen werden. Leider können die Daten für das Grid erst geladen werden, nachdem die Seite geladen wurde. Das Ergebnis? Wenn eine Anfrage an den Server ungefähr 100 ms dauert, dauert das Laden der Seite mindestens 200 ms, da die Anfragen sequentiell, also nacheinander, erfolgen müssen.

Lassen Sie uns als Nächstes unsere Aufmerksamkeit auf den zweiten großen Leistungsfaktor in xas-Anfragen richten: die Zeit, die der Server benötigt, um die Anfrage zu bearbeiten. Eines der wichtigsten Dinge, die es hier zu beachten gilt, ist, dass es nur eine Datenbank und eine begrenzte Anzahl von Servern gibt (meiner Erfahrung nach normalerweise einen). Wenn der Server/die Datenbank bereits mit anderen XAS-Anfragen ausgelastet ist, dauert die Bearbeitung neuer Anfragen länger. Deshalb ist es sinnvoll, die Anzahl der XAS-Anfragen zu minimieren.

Genug Theorie, sehen wir uns ein Beispiel an

Wie versprochen werden wir uns eine reale Anwendung ansehen, bei der ich zusammen mit einem Kollegen als Performance-Berater gearbeitet habe. Aus offensichtlichen Gründen darf ich die Analyse und das Modell der realen Anwendung nicht verwenden, also habe ich stattdessen eine neu erstellt minimales Arbeitsbeispiel (MWA). Diese MWA hat alle wesentlichen Funktionen der realen Anwendung, auf die ich mich in diesem Beitrag konzentrieren möchte.

Anlage A

Das Leistungsproblem in dieser Anwendung, das wir beheben sollten, war einfach: Das Laden der am häufigsten verwendeten Seite in der App dauerte inakzeptabel lange. Um Ihnen eine Vorstellung zu geben, die Seite wurde in 5 Sekunden geladen, als nur ein einziger Benutzer angemeldet war. An einem normalen Tag mit einer Handvoll Benutzern stieg dies auf 8 Sekunden. Stellen Sie sich vor, Sie müssen so lange warten, bis eine Seite geladen ist. Das machte die Mitarbeiter verrückt, und so bat uns das Unternehmen um Hilfe. Auf der fraglichen Seite befand sich ein Planungszeitplan. Verschiedene Ressourcen wurden nach Zeitfenstern gebucht, wie unten gezeigt (die echte App sah viel besser aus)

resources

Also machten ich und mein Kollege uns auf den Weg. Unser Endziel war es, die Zeit auf 1 Sekunde zu reduzieren.

Wir haben damit begonnen, die Leistung mit APM zu messen. APM verfügt über eine hervorragende Funktion zur Analyse von XAS-Abfragen, mit der die tatsächliche Ladezeit gemessen wird, wie sie der Benutzer erlebt hat. Es stellte sich heraus, dass die meiste Zeit (ungefähr 3 Sekunden) damit verbracht wurde, die Zeitfensterdaten zu laden! Die Daten wurden in vielen kleinen XAS-Anfragen geladen, die jeweils nur etwa ein paar hundert Millisekunden dauerten. Zusammengenommen waren das jedoch mehrere Sekunden. Das war ein starker Hinweis. Bei einer kurzen Inspektion des Modells wurde der folgende Entwurf für den Stundenplan aufgedeckt

mendix

Kannst du sehen, was das Leistungsproblem verursacht hat? Kannst du dir einen Weg vorstellen, das zu beheben?

Nehmen Sie sich eine Minute Zeit, um darüber nachzudenken, und lesen Sie weiter, um zu sehen, was wir getan haben.

Das Problem ist, dass die Aufgaben pro Ressource geladen werden. Dies war aus gestalterischer Sicht sehr sinnvoll und die einfachste mögliche Lösung. Dies war jedoch eine erhebliche Leistungsbelastung, da es zu vielen einzelnen XAS-Anfragen führte, die Aufgabe für jede Ressource separat zu laden. Sie müssen mir nicht glauben, überzeugen Sie sich selbst in dieser schönen Visualisierung von APM.

apm2

Eine APM-Analyse der Seitenladezeit, die die einzelnen gestellten XAS-Anfragen und deren Dauer aus der Erfahrung des Benutzers zeigt.

Die Lösung bestand darin, die Seite so neu zu organisieren, dass die Zeitfenster in einer einzigen großen Anfrage geladen werden. Um das Layout beizubehalten, haben wir einfaches CSS¹ verwendet. Das resultierende Seitenmodell war

mendix-page-model

Zu diesem Zeitpunkt waren wir sehr zuversichtlich, dass das Update eine viel bessere Leistung bringen wird. Aber wir sind nicht nach Bauchgefühl gegangen. Stattdessen haben wir den Fix bereitgestellt und ihn erneut über APM ausgeführt, um zu überprüfen, ob er wirklich funktioniert. Die Ergebnisse sprechen für sich:

apm-result

Die Ladezeit der Seite stieg von 1,7 auf 0,7 Sekunden. Die Ergebnisse für die reale Anwendung waren noch dramatischer. Die Ladezeit der Zeitfenster stieg von 3 Sekunden auf 200 Millisekunden. Dadurch sank die Gesamtladezeit der Seite von 5 Sekunden auf etwas mehr als 2 Sekunden.

Bevor ich mit der nächsten Ausstellung fortfahre, möchte ich darauf hinweisen, dass dies ein klassisches Beispiel für Einfachheit im Vergleich zu Leistung ist. Um die Leistung der Seite zu verbessern, mussten wir zusätzliche Komplexität einführen. Daher ist es sehr wichtig, dass dies durch exakte Messungen von APM bestätigt wurde.

Ausstellung B

Ermutigt durch unseren Erfolg machten wir uns auf einen Mini-Kreuzzug, um alle unnötigen XAS-Anfragen zu eliminieren. Was folgt, ist etwas, mit dem ich mir sicher bin, dass sich jeder Mendix-Entwickler identifizieren kann.

Die Seite hatte eine nette Nachricht, die den vollständigen Namen des angemeldeten Benutzers zeigte. Wie in der Mendix-Community allgemein bekannt ist, ist der vollständige Name keine Eigenschaft der System.User-Entität, sondern eine Eigenschaft der Administration.Account-Entität. Um also den vollständigen Namen anzuzeigen, benötigt man einen Verweis auf das Account-Objekt. In der Anwendung wurde dies mit dem folgenden Microflow durchgeführt

mendix-microflow

Das Abrufen der Datenbank ist eine sehr einfache Lösung, führt jedoch zu einer unnötigen Anfrage an die Datenbank. Da Administration.Account eine Spezialisierung von System.User ist, kann die Variable $currentUser direkt in ein Konto umgewandelt werden. Das ist ein alter Trick, den ich bei Mansystems gelernt habe und ich denke, es lohnt sich, ihn zu teilen

mendix-microflow-2

Dadurch wird der Datenbankabruf entfernt, aber es bleibt immer noch der Microflow-Aufruf übrig. Sicherlich gibt es keine Möglichkeit, es loszuwerden. Oder gibt es?

Es stellt sich heraus, dass dies seit der Veröffentlichung von Mendix 8 der Fall ist. Der Trick besteht darin, einen Nanoflow anstelle eines Microflows als Datenquelle zu verwenden und eine Javascript-Aktion zu verwenden, um den aktuellen Benutzer abzurufen und zu casten. Das fragliche Javascript ist nur wenige Zeilen lang und im App Store erhältlich.

/**
* Ruft das aktuelle Konto aus der Sitzung ab.
*
* Wenn der CurrentUser nicht existiert oder nicht vom Typ ist, wird das Konto leer zurückgegeben
* @returns {MxObject}
*/
Funktion currentAccount () {
//BENUTZERCODE BEGINNEN
neues Versprechen zurückgeben ((auflösen, ablehnen) => {
versuche {
wenn (! mx.session ||
mx.session.getUserClass ()! == „Administration.Konto“) {
resolve ();//leer zurückgeben
zurückkehren;
}
mx.data.get ({
GUID: mx.session.getUserId (),
Rückruf: function (currentUser) {
auflösen (CurrentUser);
},
Fehler: Funktion (Fehler) {
ablehnen (e);
}
});
} fangen (e) {
ablehnen (e);
}
});
//ENDBENUTZERCODE
}

Dadurch ist es möglich, die von APM bestätigte XAS-Anfrage vollständig zu eliminieren.

apm3
apm4

Unglaublich, nicht wahr? Das Endergebnis ist eine nette Beschleunigung der Seitenladezeit von 168 (mit Datenbank) auf 42 Millisekunden (mit Nanoflow):

apm5

Um es klar zu sagen: Die Idee besteht nicht darin, zu demonstrieren, wie die Leistungsbilanz abgerufen werden kann, sondern allgemeiner, wie die Leistung verbessert werden kann, indem Mikroflüsse durch Nanoflows ersetzt werden. Ehrlich gesagt gibt es mit der Einführung von JavaScript-Aktionen fast keine Logik, die nicht auf einen Nanoflow portiert werden kann. In der realen Anwendung haben wir es geschafft, 400 Millisekunden einzusparen, indem wir einige Microflow-Aufrufe durch Nanoflows ersetzt haben. Zu diesem Zeitpunkt wurde die Seite in 1,8 Sekunden geladen.

Damit sind die Beispiele abgeschlossen. Sie können ein Projekt mit beiden Beispielen aus dem App Store herunterladen.

Zusammenfassung

In diesem Blogbeitrag haben wir gesehen, wie die Minimierung der Anzahl von Abrufen das Laden von Seiten erheblich beschleunigen kann. Dies kann beispielsweise geschehen, indem ein Microflow-Aufruf durch einen Nanoflow ersetzt oder mehrere Abrufe in einer einzigen Anfrage gruppiert werden.

Seien Sie gespannt auf den nächsten Blogbeitrag der Serie. Wird fortgesetzt...

¹ In unserem Fall stützte sich das CSS auf die feste Reihenfolge der Ressourcen. Untersuchen Sie die App oder überprüfen Sie den Quellcode auf alle Details. Ein alternativer Ansatz wäre, das letzte Objekt in der Zeile zu kennzeichnen oder Dummy-Objekte hinzuzufügen, um den Beginn einer neuen Zeile zu signalisieren (z. B. eine Aufgabe, die immer um 6 Uhr morgens beginnt).

Finden Sie heraus, wie CLEVR die Wirkung Ihres Unternehmens steigern kann

Kontaktiere uns

FAQ

Can't find the answer to your question? Just get in touch

No items found.
melde dich für den Newsletter an

Erhalte persönliche Neuigkeiten und Updates in deinem Posteingang

Danke! Deine Einreichung ist eingegangen!
Hoppla! Beim Absenden des Formulars ist etwas schief gelaufen.
CLEVR Company picture Alicia - Ech
No items found.
No items found.