Share via


Dissenyar formularis de rendiment en aplicacions basades en models

Crear experiències on es puguin completar tasques d'una manera ràpida i eficaç és un procés crucial per a la satisfacció de l'usuari. Les aplicacions basades en models es poden personalitzar molt per crear experiències que cobreixin les necessitats dels usuaris, però és important saber com es codifiquen, creen i executen aplicacions basades en models que es carreguin ràpidament quan un usuari obre i navega a l'aplicació mentre treballa en tasques diàries. El rendiment s'ha demostrat que és clau a l'hora de decidir si una aplicació satisfà els clients quan no està optimitzada per al rendiment.

Les personalitzacions intel·ligents i els formularis de rendiment són aspectes importants per crear formularis molt eficients i productius. També és important assegurar-vos que esteu creant formularis molt productius amb les pràctiques recomanades de disseny i disposició de la interfície d'usuari. Per obtenir informació quant al disseny de formularis que ofereixin eficiència i productivitat, vegeu Dissenyar formularis principals productius a les aplicacions basades en models.

També és important garantir que els usuaris estiguin en els dispositius recomanats i admesos i les especificacions mínimes necessàries. Més informació: Navegadors web i dispositius mòbils admesos

Treballar amb dades i pestanyes

Aquesta secció tracta sobre com els controls que visualitzen dades i pestanyes tenen un impacte en el rendiment dels formularis.

Importància de la pestanya per defecte

La pestanya per defecte és la primera pestanya ampliada d'un formulari. Té un paper especial en la càrrega d'una pàgina de formulari. Per disseny, els controls de la pestanya per defecte sempre es representen en obrir un registre. En concret, la lògica d'inicialització del control, com ara la recuperació de dades, s'invoca per a cada control de la pestanya.

En canvi, una pestanya secundària no realitza aquesta inicialització als seus controls quan el formulari es carrega inicialment. En lloc d'això, la inicialització del control es produeix en el moment en què s'obre la pestanya secundària mitjançant la interacció de l'usuari o cridant el mètode setFocus de l'API de client. Això proporciona una oportunitat per allotjar el processament excessiu del control de la càrrega del formulari inicial col·locant determinats controls a les pestanyes secundàries en comptes de la pestanya per defecte. Per tant, l'estratègia de col·locació del control pot tenir un impacte important en la capacitat de resposta de la càrrega inicial del formulari. Una pestanya per defecte més sensible proporciona una millor experiència global modificant camps importants, interactuant amb la barra d'ordres i explorant altres pestanyes i seccions.

Col·loqueu sempre els controls que s'utilitzen més a la part superior de la pestanya per defecte. La disposició i l'arquitectura de la informació no només són importants per al rendiment, sinó també per millorar la productivitat quan els usuaris interactuen amb les dades del formulari. Més informació: Dissenyar formularis principals productius a les aplicacions basades en models

Controls controlats per dades

Els controls que requereixen dades addicionals més enllà del registre principal produeixen la càrrega més gran en la capacitat de resposta i la càrrega dels formularis. Aquests controls obtenen dades sobre la xarxa i sovint impliquen un període d'espera (que es veu com a indicadors de progrés) perquè es pot trigar temps a transmetre les dades.

Alguns dels controls controlats per dades són:

Mantingueu només els controls que s'utilitzen més sovint a la pestanya per defecte. La resta de controls controlats per dades s'han de distribuir en pestanyes secundàries per permetre que la pestanya per defecte es carregui ràpidament. A més, aquesta estratègia de disposició redueix les possibilitats de recuperar dades que acabin sense ús.

Hi ha altres controls que tenen menys impacte que els controls controlats per dades, però que encara poden participar en l'estratègia de disposició anterior per tal d'aconseguir el millor rendiment. Aquests controls inclouen:

Navegador web

Aquesta secció tracta de les pràctiques recomanades amb navegadors web.

No obrir finestres noves

El mètode API de client openForm permet que una opció de paràmetre visualitzi un formulari en una finestra nova. No utilitzeu aquest paràmetre ni el definiu com a fals. Si el definiu com a fals, es garantirà que el mètode openForm dugui a terme el comportament per defecte de visualitzar el formulari mitjançant la finestra existent. També és possible cridar directament la funció JavaScript window.open des d'un script personalitzat o una altra aplicació; tanmateix, això també s'hauria d'evitar. Obrir una finestra nova vol dir que tots els recursos de la pàgina s'han d'obtenir i carregar de zero ja que la pàgina no pot utilitzar les capacitats de memòria cau de dades en memòria entre un formulari carregat prèviament i el formulari d'una finestra nova. Com a alternativa a l'obertura de finestres noves, considereu la possibilitat d'utilitzar l'experiència multisessió que permet obrir els registres en diverses pestanyes mentre alhora que es maximitzen els beneficis de rendiment de l'emmagatzematge en la memòria cau del client.

Utilitzar navegadors moderns

Utilitzar el navegador web més actualitzat és clau per garantir que l'aplicació basada en models s'executi al més ràpidament possible. La raó d'això és que moltes de les millores de rendiment només es poden utilitzar en els navegadors més nous i moderns.

Per exemple, si l'organització té versions antigues del Firefox, navegadors no basats en Chromium, etc. i, per tant, molts dels guanys de rendiment integrats en una aplicació basada en models no estaran disponibles a les versions anteriors del navegador perquè no admeten característiques en què confia l'aplicació per executar-se de manera ràpida i sense problemes.

En la majoria dels casos, es possible obtenir millores en la càrrega de la pàgina simplement canviant a Microsoft Edge, actualitzant a l'última versió del navegador des d'una versió anterior o canviant a un navegador modern basat en Chromium.

Personalització de JavaScript

Aquesta secció explica com fer personalitzacions intel·ligents quan utilitzeu JavaScript per ajudar-vos a crear formularis i pàgines de rendiment en una aplicació basada en models.

Utilitzar JavaScript amb formularis

La capacitat de personalitzar els formularis amb JavaScript proporciona als desenvolupadors professionals una flexibilitat excel·lent sobre l'aparença i el comportament d'un formulari. L'ús inadequat d'aquesta flexibilitat pot afectar negativament el rendiment dels formularis. Els desenvolupadors han d'utilitzar les estratègies següents per maximitzar el rendiment del formulari quan implementin personalitzacions de JavaScript.

Utilitzar sol·licituds de xarxa asíncrones en sol·licitar dades

Sol·liciteu les dades de manera asíncrona en comptes de síncrona quan calguin dades addicionals per a les personalitzacions. Per a les incidències que admeten l'espera de codi asíncron, com ara les incidències de formulari OnLoad i OnSave, els controladors d'incidències haurien de retornar un Promise per tal que la plataforma esperi fins que es resolgui el Promise. La plataforma mostrarà una IU adequada mentre l'usuari espera que la incidència es completi.

Per a les incidències que no admeten l'espera de codi asíncron, com ara la incidència de formulari OnChange, podeu utilitzar una solució alternativa per aturar la interacció amb un formulari mentre el codi està fent una sol·licitud asíncrona mitjançant showProgressIndicator. Això és millor que utilitzar sol·licituds síncrones perquè els usuaris encara podran interactuar amb altres parts de l'aplicació mentre es visualitza l'indicador de progrés.

Aquest és un exemple del codi asíncron en punts d'extensió síncrons.

//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);

Hauríeu d'anar en compte quan utilitzeu codi asíncron en un controlador d'incidències que no admet l'espera de codi asíncron. Això és particularment cert per al codi que necessita fer o gestionar una acció en la resolució del codi asíncron. El codi asíncron pot provocar problemes si el controlador de resolució espera que el context de l'aplicació es mantingui igual que quan es va iniciar el codi asíncron. El codi hauria de comprovar que l'usuari es troba en el mateix context després de cada punt de continuació asíncron.

Per exemple, pot haver-hi codi en un controlador d'incidències per fer una sol·licitud de xarxa i canviar un control perquè es desactivi segons les dades de la resposta. Abans de rebre la resposta de la sol·licitud, l'usuari pot haver interactuat amb el control o navegar a una altra pàgina. Com que l'usuari està en una pàgina diferent, pot ser que el context del formulari no estigui disponible, la qual cosa pot provocar errors, o pot ser que hi hagi un altre comportament no desitjat.

Compatibilitat asíncrona en incidències OnLoad i OnSave de formulari

Les incidències OnLoad i OnSave de formulari admeten controladors que retornen promeses. Les incidències esperaran totes les promeses retornades per un controlador per resoldre's, amb un temps d'espera. Aquest suport es pot habilitar a través de la configuració de l'aplicació.

Més informació:

Limitar la quantitat de dades sol·licitades durant la càrrega del formulari

Sol·liciteu només la quantitat mínima de dades que calen per fer la lògica empresarial en un formulari. Deseu a la memòria cau les dades que se sol·liciten al màxim possible, especialment per a les dades que no canvien sovint o que no han d'estar actualitzades. Per exemple, imagineu que hi ha un formulari que sol·licita dades d'una taula de configuració. A partir de les dades de la taula de configuració, pot ser que el formulari amagui una secció del formulari. En aquest cas, el JavaScript pot emmagatzemar a la memòria cau les dades de sessionStorage perquè les dades només se sol·licitin un cop per sessió (onLoad1). Una estratègia d'obsolet fins que es revalidi també es pot utilitzar quan JavaScript utilitza les dades de sessionStorage mentre sol·licita dades per a la següent navegació al formulari (onLoad2). Finalment, una estratègia de desduplicació es podria utilitzar en cas que un controlador es cridi diverses vegades seguides (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   
    }
}

Utilitzeu la informació disponible a l'API de client en comptes de fer sol·licituds. Per exemple, en comptes de sol·licitar les funcions de seguretat d'un usuari en carregar el formulari, podeu utilitzar getGlobalContext.userSettings.roles.

Carregar el codi només quan sigui necessari

Carregueu tant codi com calgui per a les incidències d'un formulari concret. Si teniu codi que només és per al formulari A i el formulari B, no s'hauria d'incloure en una biblioteca que es carregui per al formulari C. Hauria de ser a la seva pròpia biblioteca.

Eviteu carregar biblioteques en la incidència OnLoad si només s'utilitzen per a les incidències OnChange o OnSave. En comptes d'això, carregueu-les en aquestes incidències. D'aquesta manera, la plataforma pot ajornar la càrrega fins que es carregui el formulari. Més informació: Optimitzar el rendiment del formulari

Supressió de l'ús de les API de consola al codi de producció

No utilitzeu els mètodes de l'API de consola, com ara console.log en codi de producció. El registre de dades a la consola pot augmentar significativament la demanda de memòria i impedir que es netegin dades en memòria. Això pot fer que l'aplicació sigui més lenta amb el temps i, finalment, es bloquegi.

Evitar salts de memòria

Els salts de memòria del codi poden donar lloc a un rendiment més lent al llarg del temps i, finalment, provocar que l'aplicació es bloquegi. Els salts de memòria es produeixen quan l'aplicació no pot alliberar memòria quan ja no es necessita. Amb totes les personalitzacions i els components de codi del formulari, heu de:

  • Considereu i proveu a fons els escenaris per a qualsevol cosa responsable de la neteja de memòria, com ara les classes responsables de l'administració del cicle de vida dels objectes.
  • Netegeu tots els oients d'incidències i subscripcions, especialment si està a sobre de l'objecte window.
  • Netegeu tots els temporitzadors com setInterval.
  • Evitar, limitar i netejar referències a objectes globals o estàtics.

Per als components de control personalitzats, la neteja es pot fer amb el mètode de destrucció.

Per obtenir més informació sobre la solució de problemes de memòria, aneu a aquesta documentació per a desenvolupadors de l'Edge.

Eines que podeu utilitzar per ajudar a fer que les aplicacions tinguin millor rendiment

Aquesta secció descriu les eines que us poden ajudar a entendre els problemes de rendiment i ofereix recomanacions sobre com optimitzar les personalitzacions a les aplicacions basades en models.

Conclusions del rendiment

El Performance Insights és una eina d'autoservei per als responsables de l'aplicació empresarial que analitza dades de telemetria en temps d'execució i proporciona una llista prioritzada de recomanacions per ajudar a millorar el rendiment de les aplicacions basades en models. Aquesta característica proporciona un conjunt diari d'informació analítica relacionada amb el rendiment d'una aplicació basada en el model del Power Apps o del Customer Engagement, com ara el Dynamics 365 Sales o el Dynamics 365 Service, amb recomanacions i elements que es poden dur a terme. Els responsables de l'aplicació empresarial poden veure informació detallada del rendiment en un nivell d'aplicació al Power Apps. Més informació: Què són les conclusions de rendiment? (versió preliminar)

Comprovador de solucions

El comprovador de solucions és una eina potent que pot analitzar les personalitzacions de client i de servidor per a problemes de rendiment o fiabilitat. Pot analitzar JavaScript de client, XML de formulari i complements del servidor .NET i oferir conclusions sobre què pot alentir els usuaris finals. Es recomana executar el comprovador de solucions cada vegada que es publiquin canvis en un entorn de desenvolupament perquè sorgeixi qualsevol problema de rendiment abans que arribi als usuaris finals. Més informació: Utilitzar el verificador de solucions per validar aplicacions basades en models al Power Apps

Alguns exemples de problemes relacionats amb el rendiment que es troben amb el comprovador de solucions:

Comprovador d'objectes

El comprovador d'objectes executa diagnòstics en temps real sobre objectes de components dins de la vostra solució. Si es detecten problemes, es retorna una recomanació que descriu com solucionar el problema. Més informació: Utilitzar el comprovador d'objectes per diagnosticar un component de la solució (versió preliminar)

Passos següents

Disseny de formularis productius principals a les aplicacions basades en model