Formulare für Leistung in modellgesteuerten Apps erstellen

Der Aufbau von Erfahrungen, bei denen Aufgaben schnell und effizient erledigt werden können, ist entscheidend für die Benutzerzufriedenheit. Modellgesteuerte Apps können stark angepasst werden, um Erlebnisse zu schaffen, die den Anforderungen Ihrer Benutzer entsprechen. Es ist jedoch wichtig zu wissen, wie Sie modellgesteuerte Apps effektiv codieren, erstellen und ausführen, die schnell geladen werden, wenn ein Benutzer Ihre App öffnet und navigiert. während Sie an täglichen Aufgaben arbeiten. Es hat sich gezeigt, dass die Leistung ein Hauptgrund für die Unzufriedenheit einer App ist, wenn sie nicht für die Leistung optimiert ist.

Intelligente Anpassungen und performante Formulare sind wichtige Aspekte beim Erstellen hocheffizienter und produktiver Formulare. Es ist auch wichtig, sicherzustellen, dass Sie hochproduktive Formulare mit den Best Practices für Benutzeroberflächendesign und -Layout erstellen. Informationen zum Entwerfen von Formularen für Effizienz und Produktivität finden Sie unter Produktive Hauptformulare in modellgesteuerten Apps entwerfen.

Es ist auch wichtig, sicherzustellen, dass Benutzer empfohlene und unterstützte Geräte und die erforderlichen Mindestspezifikationen verwenden. Weitere Informationen: Unterstützte Webbrowser und Mobilgeräte.

Verwenden von Daten und Registerkarten

In diesem Abschnitt wird erläutert, wie sich Steuerelemente zum Anzeigen von Daten und Registerkarten auf die Formularleistung auswirken.

Bedeutung des Standard-Registerkarten

Die Standardregisterkarte ist die erste erweiterte Registerkarte in einem Formular. Es spielt eine besondere Rolle beim Laden einer Formularseite. Die Steuerelemente der Standardregisterkarte werden standardmäßig beim Öffnen eines Datensatzes gerendert. Insbesondere wird die Initialisierungslogik des Steuerelements, wie z. B. der Datenabruf, für jedes Steuerelement auf der Registerkarte aufgerufen.

Im Gegensatz dazu führt eine sekundäre Registerkarte diese Initialisierung für ihre Steuerelemente nicht durch, wenn das Formular zum ersten Mal geladen wird. Stattdessen erfolgt die Initialisierung des Steuerelements zu dem Zeitpunkt, zu dem die sekundäre Registerkarte entweder durch Benutzerinteraktion oder durch Aufrufen der setFocus Client-API-Methode geöffnet wird. Dies bietet die Möglichkeit, die anfängliche Formularlast vor übermäßiger Steuerelementverarbeitung zu schützen, indem bestimmte Steuerelemente in sekundären Registerkarten anstelle der Standardregisterkarten platziert werden. Somit kann die Steuerungsplatzierungsstrategie einen signifikanten Einfluss auf die Reaktionsfähigkeit des anfänglichen Formularladens haben. Eine reaktionsschnellere Standardregisterkarte bietet insgesamt eine bessere Erfahrung beim Ändern wichtiger Felder, der Interaktion mit der Befehlsleiste und der Erkundung anderer Registerkarten und Abschnitte.

Platzieren Sie die am häufigsten verwendeten Steuerelemente immer oben auf Ihrem Standard-Registerkarte. Layout und Informationsarchitektur sind nicht nur für die Leistung wichtig, sondern auch für die Verbesserung der Produktivität, wenn Benutzer mit Daten im Formular interagieren. Weitere Informationen: Produktive Hauptformulare in modellgesteuerten Apps gestalten

Datengesteuerte Steuerelemente

Steuerelemente, die über den primären Datensatz hinaus zusätzliche Daten erfordern, belasten die Reaktionsfähigkeit des Formulars und die Ladegeschwindigkeit am meisten. Diese Steuerelemente rufen Daten über das Netzwerk ab und beinhalten oft eine Wartezeit (als Fortschrittsanzeige angesehen), da die Übertragung der Daten einige Zeit in Anspruch nehmen kann.

Zu den datengesteuerten Steuerelementen gehören:

Behalten Sie nur die am häufigsten verwendeten dieser Steuerelemente auf der Standardregisterkarte bei. Die verbleibenden datengesteuerten Steuerelemente sollten auf sekundäre Registerkarten verteilt werden, damit die Standardregisterkarte schnell geladen werden kann. Darüber hinaus verringert diese Layoutstrategie die Wahrscheinlichkeit, dass Daten abgerufen werden, die am Ende ungenutzt bleiben.

Es gibt andere Steuerelemente, die weniger wirkungsvoll sind als die datengesteuerten Steuerelemente, die aber dennoch an der obigen Layoutstrategie teilnehmen können, um die beste Leistung zu erzielen. Zu den Steuerelementen gehören:

Webbrowser

In diesem Abschnitt werden bewährte Verfahren für die Verwendung mit Webbrowsern behandelt.

Keine neuen Fenster öffnen

Die openForm Client-API-Methode ermöglicht es einer Parameteroption, ein Formular in einem neuen Fenster anzuzeigen. Verwenden Sie diesen Parameter nicht und setzen Sie ihn nicht auf „false“. Wenn Sie es auf false setzen, wird sichergestellt, dass die openForm-Methode das Standardverhalten der Anzeige des Formulars mithilfe des vorhandenen Fensters ausführt. Es ist auch möglich, direkt die window.open JavaScript-Funktion aus einem benutzerdefinierten Skript oder einer anderen Anwendung aufzurufen; dies sollte jedoch ebenfalls vermieden werden. Das Öffnen eines neuen Fensters bedeutet, dass alle Seitenressourcen abgerufen und von Grund auf neu geladen werden müssen, da die Seite nicht in der Lage ist, die speicherinternen Daten-Caching-Funktionen zwischen einem zuvor geladenen Formular und dem Formular in einem neuen Fenster zu nutzen. Als Alternative zum Öffnen neuer Fenster sollten Sie die Multisession-Erfahrung in Betracht ziehen, die das Öffnen von Datensätzen in mehreren Registerkarten ermöglicht und gleichzeitig die Leistungsvorteile des Client-Caching maximiert.

Verwenden Sie moderne Browser

Die Verwendung des aktuellsten Webbrowsers ist entscheidend, um sicherzustellen, dass Ihre modellgesteuerte App so schnell wie möglich ausgeführt wird. Der Grund dafür ist, dass viele der Leistungsverbesserungen nur in den neueren modernen Browsern verwendet werden können.

Wenn Ihre Organisation beispielsweise über ältere Versionen von Firefox verfügt, nicht auf Chrom basierende Browser usw., viele der Leistungssteigerungen, die in eine modellgesteuerte App integriert sind, sind in den älteren Browserversionen nicht verfügbar, da sie keine Funktionen unterstützen, von denen die App für eine schnelle Ausführung abhängt. und reibungslos.

In den meisten Fällen können Sie Verbesserungen beim Seitenladen erwarten, indem Sie einfach zu Microsoft Edge wechseln, von einer älteren Version auf die neueste aktuelle Browserversion aktualisieren oder zu einem modernen Chromium-basierten Browser wechseln.

JavaScript-Anpassung

In diesem Abschnitt wird erläutert, wie Sie bei Verwendung von JavaScript intelligente Anpassungen vornehmen, die Ihnen beim Erstellen leistungsfähiger Formulare und Seiten in einer modellgesteuerten App helfen.

Verwenden von JavaScript mit Formularen

Die Möglichkeit, Formulare durch JavaScript anzupassen, bietet professionellen Entwicklern große Flexibilität beim Aussehen und Verhalten eines Formulars. Die unsachgemäße Verwendung dieser Flexibilität kann sich negativ auf die Formularleistung auswirken. Entwickler sollten die folgenden Strategien verwenden, um die Formularleistung bei der Implementierung von JavaScript-Anpassungen zu maximieren.

Verwenden Sie asynchrone Netzwerkanforderungen, wenn Sie Daten anfordern

Fordern Sie Daten asynchron statt synchron an, wenn zusätzliche Daten für Anpassungen erforderlich sind. Für Ereignisse, die das Warten auf asynchronen Code wie das Formular OnLoad und Formular OnSave-Ereignisse unterstützen, sollten Ereignishandler ein Promise zurückgeben, damit die Plattform bis zum Promise erledigt ist. Die Plattform zeigt eine entsprechende Benutzeroberfläche an, während der Benutzer auf den Abschluss des Ereignisses wartet.

Für Ereignisse, die das Warten auf asynchronen Code nicht unterstützen, wie das Formular OnChange-Ereignis können Sie eine Problemumgehung verwenden, um die Interaktion mit einem Formular zu beenden, während der Code eine asynchrone Anforderung mithilfe von showProgressIndicator durchführt. Dies ist besser als die Verwendung synchroner Anforderungen, da Benutzer weiterhin mit anderen Teilen der Anwendung interagieren können, während eine Fortschrittsanzeige angezeigt wird.

Hier ist ein Beispiel mit asynchronem Code in synchronen Erweiterungspunkten.

//Only do this if an extension point does not yet support asynchronous code
try {
    await Xrm.WebApi.retrieveRecord("settings_entity", "7333e80e-9b0f-49b5-92c8-9b48d621c37c");
    //do other logic with data here
} catch (error) {
    //do other logic with error here
} finally {
    Xrm.Utility.closeProgressIndicator();
}

// Or using .then/.finally
Xrm.Utility.showProgressIndicator("Checking settings...");
Xrm.WebApi.retrieveRecord("settings_entity", "7333e80e-9b0f-49b5-92c8-9b48d621c37c")
    .then(
        (data) => {
            //do other logic with data here
        },
        (error) => {
            //do other logic with error here
        }
    )
    .finally(Xrm.Utility.closeProgressIndicator);

Seien Sie vorsichtig, wenn Sie asynchronen Code in einem Ereignishandler verwenden, der das Warten auf asynchronen Code nicht unterstützt. Dies gilt insbesondere für Code, der bei der Auflösung des asynchronen Codes eine Aktion ausführen oder verarbeiten muss. Asynchroner Code kann Probleme verursachen, wenn der Auflösungshandler erwartet, dass der Anwendungskontext derselbe bleibt wie beim Starten des asynchronen Codes. Ihr Code sollte überprüfen, ob sich der Benutzer nach jedem asynchronen Fortsetzungspunkt im selben Kontext befindet.

Ein -Ereignishandler kann beispielsweise Code enthalten, um eine Netzwerkanforderung zu erstellen und ein Steuerelement zu deaktivieren, das basierend auf den Antwortdaten geändert werden soll. Bevor die Antwort auf die Anfrage empfangen wird, hat der Benutzer möglicherweise mit dem Steuerelement interagiert oder zu einer anderen Seite navigiert. Da sich der Benutzer auf einer anderen Seite befindet, ist der Formularkontext möglicherweise nicht verfügbar, was zu Fehlern oder anderen unerwünschten Verhaltensweisen führen kann.

Async-Unterstützung in Formular-OnLoad- und Formular-OnSave-Ereignissen

Die Formular-OnLoad und OnSave-Ereignisse unterstützen Handler, die Versprechen zurückgeben. Die Ereignisse warten bis zu einer Zeitüberschreitung, bis alle von einem Handler zurückgegebenen Zusagen aufgelöst werden. Diese Unterstützung kann über die App-Einstellungen aktiviert werden.

Weitere Informationen:

Begrenzen Sie die beim Laden des Formulars angeforderte Datenmenge

Fordern Sie nur die minimale Datenmenge an, die zum Ausführen der Geschäftslogik in einem Formular erforderlich ist. Zwischenspeichern Sie die angeforderten Daten so weit wie möglich, insbesondere bei Daten, die sich nicht oft ändern oder nicht neu sein müssen. Stellen Sie sich zum Beispiel vor, es gibt ein Formular, das Daten von einer Tabelle Einstellung anfordert. Basierend auf den Daten in der Einstellungstabelle kann das Formular einen Abschnitt des Formulars ausblenden. In diesem Fall kann das JavaScript Daten in sessionStorage zwischenspeichern, damit Daten nur einmal pro Sitzung abgefragt werden (onLoad1). Es kann auch eine Stale-While-Revalidate-Strategie verwendet werden, wenn das JavaScript die Daten von sessionStorage beim Anfordern von Daten für die nächste Navigation zum Formular (onLoad2) verwendet. Schließlich könnte eine Deduplizierungsstrategie verwendet werden, falls ein Handler mehrmals hintereinander aufgerufen wird (onLoad3).

const SETTING_ENTITY_NAME = "settings_entity";
const SETTING_FIELD_NAME = "settingField1";
const SETTING_VALUE_SESSION_STORAGE_KEY = `${SETTING_ENTITY_NAME}_${SETTING_FIELD_NAME}`;

// Retrieve setting value once per session
async function onLoad1(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Ensure there is a stored setting value to use
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestSettingValue();
    }

    // Do logic with setting value here
}

// Retrieve setting value with stale-while-revalidate strategy
async function onLoad2(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Revalidate, but only await if session storage value is not present
    const requestPromise = requestSettingValue();

    // Ensure there is a stored setting value to use the first time in a session
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestPromise;
    }
    
    // Do logic with setting value here
}

// Retrieve setting value with stale-while-revalidate and deduplication strategy
let requestPromise;
async function onLoad3(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Request setting value again but don't wait on it
    // In case this handler fires twice, don’t make the same request again if it is already in flight
    // Additional logic can be added so that this is done less than once per page
    if (!requestPromise) {
        requestPromise = requestSettingValue().finally(() => {
            requestPromise = undefined;
        });
    }

    // Ensure there is a stored setting value to use the first time in a session
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestPromise;
    }
    
    // Do logic with setting value here
}

async function requestSettingValue() {
    try {
        const data = await Xrm.WebApi.retrieveRecord(
            SETTING_ENTITY_NAME,
            "7333e80e-9b0f-49b5-92c8-9b48d621c37c",
            `?$select=${SETTING_FIELD_NAME}`);
        try {
            sessionStorage.setItem(SETTING_VALUE_SESSION_STORAGE_KEY, data[SETTING_FIELD_NAME]);
        } catch (error) {
            // Handle sessionStorage error
        } finally {
            return data[SETTING_FIELD_NAME];
        }
    } catch (error) {
        // Handle retrieveRecord error   
    }
}

Verwenden Sie Informationen, die in der Client-API verfügbar sind, anstatt Anfragen zu stellen. Anstatt beispielsweise die Sicherheitsrollen eines Benutzers beim Laden eines Formulars anzufordern, können Sie getGlobalContext.userSettings.roles verwenden.

Code nur laden, wenn er benötigt wird

Laden Sie so viel Code, wie für Ereignisse für ein bestimmtes Formular benötigt wird. Wenn Sie Code haben, der nur für Formular A und Formular B gilt, es sollte nicht in einer Bibliothek enthalten sein, die für Formular C geladen wird. Es sollte in einer eigenen Bibliothek sein.

Vermeiden Sie das Laden von Bibliotheken im OnLoad-Ereignis, wenn sie nur für die OnChange oder OnSave-Ereignisse verwendet werden. Laden Sie sie stattdessen in diese Ereignisse. Auf diese Weise kann die Plattform das Laden der Variablen aufschieben, bis das Formular geladen ist. Weitere Informationen: Optimieren Sie die Leistung von Formularen

Entfernen Sie die Verwendung von Konsolen-APIs im Produktionscode

Verwenden Sie die Konsolen-API-Methoden wie console.log nicht im Produktionscode. Die Protokollierung von Daten in die Konsole kann den Bedarf an Speicher erheblich erhöhen und verhindern, dass die Daten im Speicher bereinigt werden. Dies kann dazu führen, dass die App mit der Zeit langsamer wird und schließlich abstürzt.

Vermeiden Sie Speicherlecks

Speicherlecks in Ihrem Code können mit der Zeit zu einer geringeren Leistung führen und schließlich zum Absturz Ihrer App führen. Speicherlecks treten auf, wenn die Anwendung Speicher nicht mehr freigibt, wenn er nicht mehr benötigt wird. Bei allen Anpassungen und Codekomponenten in Ihrem Formular sollten Sie:

  • Überlegen und testen Sie Szenarien für alles, was für die Speicherbereinigung verantwortlich ist, wie z. B. Klassen, die für die Verwaltung des Lebenszyklus von Objekten verantwortlich sind.
  • Bereinigen Sie alle Ereignis-Listener und Abonnements, insbesondere wenn es sich um das window-Objekt handelt.
  • Bereinigen Sie alle Timer wie setInterval.
  • Vermeiden, begrenzen und bereinigen Sie Verweise auf globale oder statische Objekte.

Für benutzerdefinierte Steuerungskomponenten kann die Bereinigung in der destroy-Methode durchgeführt werden.

Weitere Informationen zum Beheben von Speicherproblemen finden Sie unter dieser Edge-Entwicklerdokumentation.

Tools, die Sie verwenden können, um Apps leistungsfähiger zu machen

In diesem Abschnitt werden die Tools beschrieben, die Ihnen helfen können, Leistungsprobleme zu verstehen und Empfehlungen zur Optimierung Ihrer Anpassungen in modellbasierten Apps zu geben.

Leistungserkenntnisse

Performance Insights ist ein Self-Service-Tool für Entwickler von Unternehmens-Apps, das Laufzeit-Telemetriedaten analysiert und eine priorisierte Liste von Empfehlungen bereitstellt, um die Leistung modellgesteuerter Apps zu verbessern. Diese Funktion bietet einen täglichen Satz analytischer Einblicke in Bezug auf die Leistung von einer Power Apps Modellgesteuerten oder Kundenbindungs-App, wie Dynamics 365 Sales oder Dynamics 365 Service, mit Empfehlungen und umsetzbaren Elementen. Hersteller von Unternehmens-Apps können detaillierte Leistungseinblicke auf App-Ebene in Power Apps einsehen. Weitere Informationen: Was sind Leistungseinblicke? (Vorschau)

Lösungsüberprüfung

Solution Checker ist ein leistungsstarkes Tool, das Client- und Serveranpassungen auf Leistungs- oder Zuverlässigkeitsprobleme analysieren kann. Es kann clientseitiges JavaScript parsen, XML bilden und serverseitige .NET-Plug-Ins und gibt gezielte Einblicke in mögliche Verlangsamungen der Endbenutzer. Wir empfehlen, dass Sie die Lösungsprüfung jedes Mal ausführen, wenn Sie Änderungen in einer Entwicklungsumgebung veröffentlichen, damit alle Leistungsprobleme aufgedeckt werden, bevor sie Endbenutzer erreichen. Mehr Informationen: Verwenden Sie den Solution Checker, um Ihre modellgetriebenen Anwendungen in Power Apps zu validieren.

Einige Beispiele für Leistungsbezogene Probleme, die beim Lösungschecker gefunden wurden:

Objektüberprüfung

Die Objektprüfung führt eine Echtzeitdiagnose für Komponentenobjekte in Ihrer Lösung aus. Wenn Probleme erkannt werden, wird eine Empfehlung zurückgegeben, die beschreibt, wie das Problem behoben werden kann. Weitere Informationen: Verwenden des Objektprüfers zum Diagnostizieren einer Lösungskomponente (Vorschau)

Nächste Schritte

Produktive Hauptformulare in modellgesteuerten Apps entwerfen