Deseñar formularios para o rendemento en aplicacións baseadas en modelos

Construír experiencias onde as tarefas se poidan completar de xeito rápido e eficiente é crucial para a satisfacción do usuario. As aplicacións baseadas en modelos pódense personalizar moito para crear experiencias que satisfagan as necesidades dos seus usuarios, pero é importante saber codificar, construír e executar de forma eficaz aplicacións baseadas en modelos que se carguen rapidamente cando un usuario abre e navega na súa aplicación mentres se traballa nas tarefas diarias. O rendemento demostrou ser un dos principais motores da insatisfacción dunha aplicación cando non está optimizada para o seu rendemento.

As personalizacións intelixentes e os formularios de rendemento son aspectos importantes para construír formularios altamente eficientes e produtivos. Tamén é importante asegurarse de que está a crear formularios altamente produtivos coas prácticas recomendadas no deseño da interface de usuario. Para obter información sobre o deseño de formularios de eficiencia e produtividade, consulte Deseñar formularios principais produtivos en aplicacións baseadas en modelos.

Tamén é importante asegurarse de que os usuarios estean en dispositivos recomendados e compatibles e as especificacións mínimas requiridas. Máis información: Exploradores web e dispositivos móbiles compatibles

Traballar con datos e pestanas

Esta sección describe como os controis que mostran datos e pestanas afectan ao rendemento do formulario.

Importancia da pestana predeterminada

A pestana predeterminada é a primeira pestana expandida dun formulario. Desempeña un papel especial na carga dunha páxina de formulario. Por deseño, os controis da pestana predeterminada sempre se representan ao abrir un rexistro. En concreto, invócase a lóxica de inicialización do control, como a recuperación de datos, para cada control da pestana.

Pola contra, unha pestana secundaria non realiza esta inicialización nos seus controis cando se carga inicialmente o formulario. Pola contra, a inicialización do control prodúcese no momento en que se abre a pestana secundaria mediante a interacción do usuario ou chamando ao método da API de cliente setFocus. Isto ofrece a oportunidade de protexer a carga inicial do formulario dun procesamento excesivo de control colocando certos controis en pestanas secundarias no canto da pestana predeterminada. Así, a estratexia de colocación do control pode ter un efecto significativo na capacidade de resposta da carga inicial do formulario. Unha pestana predeterminada máis sensible ofrece unha mellor experiencia xeral para modificar campos importantes, interactuar coa barra de comandos e explorar outras pestanas e seccións.

Poña sempre os controis que máis se usan na parte superior da pestana predeterminada. O deseño e a arquitectura da información non só son importantes para o rendemento, senón tamén para mellorar a produtividade cando os usuarios interactúan cos datos do formulario. Máis información: Deseñe formularios principais produtivos en aplicacións baseadas en modelos

Controis baseados en datos

Os controis que requiren datos adicionais máis alá do rexistro primario producen a maioría da tensión na capacidade de resposta do formulario e na velocidade de carga. Estes controis obteñen datos pola rede e adoitan implicar un período de espera (visto mediante indicadores de progreso) porque pode levar tempo transmitir os datos.

Algúns dos controis baseados en datos inclúen:

Manteña só os controis usados con máis frecuencia na pestana predeterminada. Os restantes controis baseados en datos deberían distribuírse en pestanas secundarias para permitir que a ficha predeterminada se cargue rapidamente. Ademais, esta estratexia de deseño reduce a posibilidade de obter datos que acaban por non utilizarse.

Hai outros controis que son menos impactantes que os controis baseados en datos pero que aínda poden participar na estratexia de deseño anterior para conseguir o mellor rendemento. Estes controis inclúen:

Explorador web

Esta sección inclúe boas prácticas para usar con navegadores web.

Non abrir ventás novas

O método de API de cliente openForm permite que unha opción de parámetro mostre un formulario nunha nova xanela. Non use este parámetro nin o configure en falso. Se o define como falso garantirase que o método openForm realice o comportamento predeterminado de amosar o formulario usando a xanela existente. Tamén é posible chamar directamente á función de JavaScript window.open desde un script personalizado ou outra aplicación; con todo, isto tamén debe evitarse. Abrir unha nova xanela significa que todos os recursos da páxina deben ser recuperados e cargados desde cero xa que a páxina non pode aproveitar as capacidades de almacenamento na caché de datos na memoria entre un formulario cargado previamente e o formulario nunha nova xanela. Como alternativa á apertura de novas fiestras, considere a posibilidade de utilizar a experiencia multisesión que permita abrir rexistros en varias pestanas mentres se maximizan os beneficios do almacenamento na caché do cliente.

Usar navegadores modernos

Utilizar o navegador web máis actualizado é fundamental para garantir que a aplicación baseada en modelos funcione o máis rápido posible. A razón disto é que moitas das melloras de rendemento só se poden empregar nos navegadores modernos máis recentes.

Por exemplo, se a súa organización ten versións máis antigas de Firefox, navegadores non baseados en Chromium, etc., moitas das ganancias de rendemento integradas nunha aplicación baseada en modelos non estarán dispoñibles nas versións antigas do navegador porque non Non admite funcións das que depende a aplicación para funcionar de forma rápida e sen problemas.

Na maioría dos casos, pode esperar ver melloras na carga da páxina cambiando a Microsoft Edge, actualizando á última versión actual do navegador desde unha versión anterior ou cambiando a un navegador moderno baseado en Chromium.

Personalización de JavaScript

Esta sección describe como facer personalizacións intelixentes cando usa JavaScript que lle axudan a crear formularios e páxinas con alto rendemento nunha aplicación baseada en modelos.

Uso de JavaScript con formularios

A posibilidade de personalizar formularios con JavaScript proporciona aos desenvolvedores profesionais unha gran flexibilidade sobre o aspecto e o comportamento dun formulario. O uso inadecuado desta flexibilidade pode repercutir negativamente no rendemento do formulario. Os desenvolvedores deben empregar as seguintes estratexias para maximizar o rendemento do formulario ao implementar personalizacións de JavaScript.

Usar solicitudes de rede asíncronas cando solicite datos

Solicite datos de xeito asíncrono en vez que de xeito sincronizado cando sexan necesarios datos adicionais para as personalizacións. Para eventos que admiten a espera de código asíncrono como eventos do formulario OnLoad e do formulario OnSave, os xestores de eventos deben devolver unha Promise para que a plataforma agarde ata a resolución de Promise. A plataforma mostrará unha interface de usuario adecuada mentres o usuario espera a que se complete o evento.

Para eventos que non admiten a espera de código asíncrono, como o evento do formulario OnChange, pode usar unha solución alternativa para deter a interacción cun formulario mentres o código realiza unha solicitude asíncrona usando showProgressIndicator. Isto é mellor que usar solicitudes síncronas porque os usuarios aínda poderán interactuar con outras partes da aplicación a medida que se amosa un indicador de progreso.

Aquí ten un exemplo de uso de código asíncrono en puntos de extensión síncronos.

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

Debe ter coidado ao usar código asíncrono nun controlador de eventos que non admite a espera de código asíncrono. Isto é particularmente certo para o código que precisa realizar ou xestionar unha acción na resolución do código asíncrono. O código asíncrono pode causar problemas se o controlador de resolución espera que o contexto da aplicación siga sendo o mesmo que cando se iniciou o código asíncrono. O seu código debería comprobar que o usuario está no mesmo contexto despois de cada punto de continuación asíncrono.

Por exemplo, pode haber código nun controlador de eventos para facer unha solicitude de rede e cambiar un control para desactivar en función dos datos de resposta. Antes de que se reciba a resposta da solicitude, o usuario pode ter interactuado co control ou navegado a unha páxina diferente. Debido a que o usuario está nunha páxina diferente, o contexto do formulario pode non estar dispoñible, o que pode provocar erros ou pode haber outro comportamento non desexado.

Asistencia asíncrona en formularios OnLoad e eventos OnSave de formulario

Os eventos OnLoad e OnSave do formulario soportan xestores que devolven promesas. Os eventos esperarán a que se resolvan as promesas devoltas por un controlador, ata un período de tempo de espera. Este soporte pódese activar mediante a configuración da aplicación.

Máis información:

Limitar a cantidade de datos solicitados durante a carga do formulario

Solicite só a cantidade mínima de datos necesaria para realizar a lóxica empresarial nun formulario. Almacene na caché os datos que se soliciten na medida do posible, especialmente para os datos que non cambian a miúdo ou que non precisan actualizarse. Por exemplo, imaxine que hai un formulario que solicita datos dunha táboa de configuración. Baseado nos datos da táboa de configuración, o formulario pode optar por ocultar unha sección do formulario. Neste caso, o JavaScript pode almacenar na caché datos en sessionStorage de xeito que os datos só se soliciten unha vez por sesión (onLoad1). Tamén se pode empregar unha estratexia obsoleta cando se revalida onde JavaScript utiliza os datos de sessionStorage mentres solicita datos para a seguinte navegación ao formulario (onLoad2). Finalmente, podería empregarse unha estratexia de cancelación da duplicación no caso de que se chame a un controlador varias veces seguidas (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   
    }
}

Use a información dispoñible na API do cliente en lugar de facer solicitudes. Por exemplo, en lugar de solicitar as funcións de seguridade dun usuario na carga do formulario, pode usar getGlobalContext.userSettings.roles.

Cargar o código só cando sexa necesario

Cargue tanto código como sexa necesario para eventos dun formulario concreto. Se ten código só para o formulario A e o formulario B, non debería incluírse nunha biblioteca que está cargada para o formulario C . Debe estar na súa propia biblioteca.

Evite cargar bibliotecas no evento OnLoad se só se usan para os eventos OnChange ou OnSave. En vez diso, cárgueos neses eventos. Deste xeito, a plataforma pode aprazar a súa carga ata despois de cargar o formulario. Máis información: Optimizar o rendemento do formulario

Eliminar o uso das API da consola no código de produción

Non use os métodos da API da consola como console.log no código de produción. O rexistro de datos na consola pode aumentar significativamente a demanda de memoria e pode evitar que os datos se limpen na memoria. Isto pode levar a que a aplicación se faga máis lenta co paso do tempo e, finalmente, falle.

Evitar fugas de memoria

As fugas de memoria no seu código poden provocar un rendemento máis lento co paso do tempo e, finalmente, facer que a súa aplicación se bloquee. As fugas de memoria prodúcense cando a aplicación non libera memoria cando xa non é necesaria. Con todas as personalizacións e compoñentes de código do seu formulario, debe:

  • Considere e probe a fondo os escenarios para calquera cousa responsable da limpeza da memoria, como as clases responsables da xestión do ciclo de vida dos obxectos.
  • Limpar todos os oíntes de eventos e subscricións, especialmente se está no obxecto de window.
  • Limpar todos os temporizadores como setInterval.
  • Evite, limite e limpe referencias a obxectos globais ou estáticos.

Para compoñentes de control personalizados, a limpeza pódese facer no método destruír.

Para obter máis información sobre como solucionar problemas de memoria, vaia a esta documentación para desenvolvedores de Edge.

Ferramentas que pode empregar para que as aplicacións sexan máis eficaces

Esta sección describe as ferramentas que poden axudalo a comprender os problemas de rendemento e ofrecer recomendacións sobre como optimizar as súas personalizacións en aplicacións baseadas en modelos.

Información de desempeño

A información do rendemento é unha ferramenta de autoservizo para os fabricantes de aplicacións empresariais que analiza os datos de telemetría en tempo de execución e ofrece unha lista prioritaria de recomendacións para axudar a mellorar o rendemento das aplicacións baseadas en modelos. Esta función ofrece un conxunto diario de información analítica relacionada co rendemento dunha aplicación Power Apps baseada en modelos ou de participación do cliente, como Dynamics 365 Sales ou Dynamics 365 Service, con recomendacións e elementos accionables. Os creadores de aplicacións empresariais poden ver información detallada sobre o rendemento a nivel de aplicación en Power Apps. Máis información: Que é a información de rendemento? (vista previa)

Verificador de solucións

O comprobador de solucións é unha poderosa ferramenta que pode analizar as personalizacións de clientes e servidores por problemas de rendemento ou fiabilidade. Pode analizar JavaScript do lado do cliente, formar XML e complementos do servidor .NET e dar información específica sobre o que pode provocar que os usuarios finais sufran retardos. Recomendámoslle que execute o comprobador de solucións cada vez que publique cambios nun contorno de desenvolvemento, para que xurdan os problemas de rendemento antes de chegar aos usuarios finais. Máis información: Utiliza o comprobador de solucións para validar as túas aplicacións baseadas en modelos en Power Apps

Algúns exemplos de problemas relacionados co rendemento atopados co comprobador de solucións:

Verificador de obxectos

O comprobador de obxectos executa diagnósticos en tempo real en obxectos compoñentes da súa solución. Se se detectan problemas, devólvese unha recomendación que describe como solucionalo. Máis información: Use o verificador de obxectos para diagnosticar un compoñente da solución (vista previa)

Pasos seguintes

Deseñar formularios principais produtivos en aplicacións baseadas en modelos