Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Criar experiências onde as tarefas podem ser concluídas de forma rápida e eficiente é crucial para a satisfação do utilizador. As aplicações condicionadas por modelo podem ser altamente personalizadas para criar experiências que atendam às necessidades dos seus utilizadores, mas é importante saber como programar, criar e executar aplicações condicionadas por modelo que são carregadas rapidamente quando um utilizador abre e navega na sua aplicação enquanto trabalha nas tarefas diárias. O desempenho tem mostrado ser um dos principais fatores de insatisfação de uma aplicação quando não está otimizada para o desempenho.
As personalizações inteligentes e os formulários com bom desempenho são aspetos importantes para criar formulários produtivos e altamente eficientes. Também é importante assegurar que está a criar formulários altamente produtivos com as melhores práticas no design e no esquema da interface de utilizador. Para obter informações sobre como criar formulários a pensar na eficiência e na produtividade, consulte Conceber formulários principais produtivos em aplicações condicionadas por modelo.
Também é importante assegurar que os utilizadores estão em dispositivos recomendados e suportados, e com as especificações mínimas exigidas. Mais informações: Browsers e dispositivos móveis suportados
Trabalhar com dados e separadores
Esta secção aborda de que forma os controlos que apresentam dados e os separadores afetam o desempenho dos formulários.
Importância do separador predefinido
O separador predefinido é o primeiro separador expandido num formulário. Desempenha um papel especial no carregamento de uma página de formulário. Por definição, os controlos do separador predefinido são sempre apresentados ao abrir um registo. Especificamente, a lógica de inicialização do controlo, como a obtenção de dados, é executada para cada controlo existente no separador.
Por outro lado, um separador secundário não executa esta inicialização nos respetivos controlos quando o formulário é carregado inicialmente. Em vez disso, a inicialização do controlo ocorre no momento em que o separador secundário é aberto através da interação do utilizador ou ao chamar o método da API de cliente setFocus. Isto oferece uma oportunidade para resguardar o carregamento inicial do formulário do processamento excessivo dos controlos, ao colocar determinados controlos em separadores secundários, em vez de os colocar no separador predefinido. Assim, a estratégia de colocação dos controlos pode ter um efeito significativo na capacidade de resposta do carregamento inicial do formulário. Um separador predefinido mais reativo proporciona uma melhor experiência geral para modificar campos importantes, interagir com a barra de comandos e explorar outros separadores e secções.
Coloque sempre os controlos mais utilizados na parte superior do separador predefinido. A arquitetura de disposição e das informações não é importante apenas para o desempenho, mas também para melhorar a produtividade quando os utilizadores interagem com os dados no formulário. Mais informações: Conceber formulários principais produtivos em aplicações condicionadas por modelo
Controlos orientados por dados
Os controlos que necessitam de dados adicionais para além do registo primário produzem a maior tensão na capacidade de resposta e velocidade de carregamento do formulário. Estes controlos obtêm dados sobre a rede e, muitas vezes, envolvem um período de espera (visto como indicadores de progresso) porque pode demorar algum tempo para transmitir os dados.
Alguns dos controlos baseados em dados incluem:
- Formulário de vista rápida
- subgrid
- Linha cronológica
- Assistente (requer o Dynamics 365 Sales Insights)
Mantenha apenas os controlos mais utilizados no separador predefinido. Os restantes controlos orientados por dados devem ser distribuídos por separadores secundários para permitir o rápido carregamento do separador predefinido. Além disso, esta estratégia de esquema reduz a probabilidade de obter dados que acabam por não ser utilizados.
Existem outros controlos menos impactantes do que os controlos orientados por dados, mas continuam a poder participar na estratégia de esquema acima para obter o melhor desempenho. Estes controlos incluem:
browser
Esta secção abrange as boas práticas para utilizar os browsers.
Não abrir novas janelas
O método da API de cliente openForm permite que uma opção de parâmetro apresente um formulário numa nova janela. Não utilize este parâmetro ou defina-o como falso. Defini-lo em falso assegurará que o método openForm executa o comportamento predefinido de apresentar o formulário através da janela existente. Também é possível ligar diretamente para a função JavaScript window.open a partir de um script personalizado ou de outra aplicação; no entanto, isto também deve ser evitado. Abrir uma nova janela significa que todos os recursos da página têm de ser obtidos e carregados do zero, uma vez que a página não consegue tirar partido das capacidades de armazenamento em cache dos dados em memória entre um formulário previamente carregado e o formulário na nova janela. Como alternativa à abertura de novas janelas, considere utilizar a experiência de várias sessões que permite abrir registos em vários separadores, maximizando ao mesmo tempo as vantagens do desempenho da colocação na cache do cliente.
Use navegadores modernos
É fundamental utilizar o browser mais atualizado para assegurar que a sua aplicação condicionada por modelo é executada o mais rapidamente possível. A razão para isto é que muitas das melhorias de desempenho só podem ser utilizadas nos browsers modernos mais recentes.
Por exemplo, se a sua organização tiver versões mais antigas do Firefox, browsers não baseados no Chromium, etc., muitos dos ganhos de desempenho integrados numa aplicação condicionada por modelo não estarão disponíveis nas versões mais antigas do browser porque não suportam funcionalidades das quais a aplicação depende para funcionar de forma rápida e fluida.
Na maioria dos casos, pode esperar ver melhorias no carregamento das páginas com a simples mudança para o Microsoft Edge, ao atualizar para a versão de browser atual mais recente a partir de uma versão mais antiga ou ao mudar para um browser moderno baseado em Chromium.
Personalização do JavaScript
Esta secção cobre como fazer personalizações inteligentes quando utiliza o JavaScript, o que o ajuda criar construir formulários e páginas com bom desempenho numa aplicação condicionada por modelo.
Utilizar JavaScript com formulários
A capacidade de personalizar os formulários com o JavaScript proporciona aos programadores profissionais uma grande flexibilidade em termos de aparência e comportamento de um formulário. O uso inadequado desta flexibilidade pode ter um impacto negativo no desempenho do formulário. Os programadores devem utilizar as seguintes estratégias para maximizar o desempenho do formulário quando implementam personalizações do JavaScript.
Utilizar pedidos de rede assíncronos ao solicitar dados
Solicite os dados de forma assíncrona, e não síncrona, quando são necessários dados adicionais para personalizações. Para os eventos que suportam a espera pela execução de código assíncrono, como os eventos de formulário OnLoad e OnSave, os manipuladores de eventos devem devolver um Promise para que a plataforma aguarde até que Promise seja resolvida. A plataforma mostrará uma IU adequada enquanto o utilizador aguarda pela conclusão do evento.
Para os eventos que não suportam esperar por código assíncrono, como o evento OnChange de formulário, poderá usar uma solução para parar a interação com um formulário enquanto o código está a fazer um pedido assíncrono utilizando showProgressIndicator. Isto é melhor do que utilizar pedidos síncronos porque os utilizadores ainda poderão interagir com outras partes da aplicação à medida que é apresentado um indicador de progresso.
Segue-se um exemplo de utilização de código assíncrono em pontos de extensão 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);
Deverá ter cuidado ao utilizar código assíncrono num processador de eventos que não suporte a espera por código assíncrono. Isto é particularmente verdade para o código que precisa que uma ação seja tomada ou processada na resolução do código assíncrono. O código assíncrono pode causar problemas se o processador de resolução esperar que o contexto da aplicação permaneça o mesmo que era quando o código assíncrono foi iniciado. O seu código deve verificar se o utilizador está no mesmo contexto após cada ponto de continuação assíncrono.
Por exemplo, poderá existir código num processador de eventos para fazer um pedido de rede e alterar um controlo para ser desativado com base nos dados da resposta. Antes de ser recebida a resposta do pedido, o utilizador pode ter interagido com o controlo ou navegado para uma página diferente. Como o utilizador está numa página diferente, o contexto do formulário poderá não estar disponível, o que poderá gerar a erros, ou poderão existir outros comportamentos indesejados.
Suporte assíncrono nos eventos OnLoad de formulário e OnSave de formulário
Os eventos OnLoad e OnSave de formulário suportam processadores que devolvem promessas. Os eventos aguardarão pela resolução de quaisquer promessas devolvidas por um processador, até um período de tempo limite. Este suporte pode ser ativado através das definições da aplicação.
Mais informações:
Limitar a quantidade de dados pedidos durante o carregamento do formulário
Solicite apenas o volume mínimo de dados necessários para executar lógica de negócio num formulário. Coloque em cache os dados que são solicitados o máximo possível, sobretudo para os dados que não mudam frequentemente ou não precisam de estar atualizados. Por exemplo, imagine que há um formulário que solicita dados da tabela setting. Baseado nos dados na tabela de definições, o formulário poderá optar por ocultar uma secção do formulário. Neste caso, o JavaScript pode colocar dados em cache em sessionStorage para os dados só serem solicitados uma vez por sessão (onLoad1). Também poderá ser utilizada uma estratégia "obsoleto durante a revalidação" quando o JavaScript utilizar os dados a partir de sessionStorage ao pedir dados para a navegação seguinte para o formulário (onLoad2). Por fim, poderia ser usada uma estratégia de desduplicação caso um manipulador seja chamado várias vezes consecutivas (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
}
}
Utilize as informações disponíveis na API de cliente em vez de fazer pedidos. Por exemplo, em vez de solicitar os direitos de acesso de um utilizador ao carregar o formulário, poderá utilizar getGlobalContext.userSettings.roles.
Carregar código apenas quando for necessário
Carregue o código necessário para os eventos de um determinado formulário. Se tiver um código que seja apenas para o formulário A e formulário B, não deve ser incluído numa biblioteca que seja carregada para o formulário C. Devia estar na sua própria biblioteca.
Evite carregar bibliotecas no evento OnLoad se só forem utilizadas apenas para os eventos OnChange ou OnSave. Em vez disso, carregue-nos nesses eventos. Desta forma, a plataforma pode adiar o respetivo carregamento até depois de o formulário carregar. Mais informações: Otimizar o desempenho do formulário
Remover a utilização de APIs de consola no código de produção
Não utilize os métodos de API da consola, como console.log no código de produção. Registar dados na consola pode aumentar significativamente a procura de memória e pode impedir que os dados sejam limpos na memória. Isto pode fazer com que a aplicação se torne mais lenta com o tempo e, eventualmente, falhe.
Evitar fugas de memória
As fugas de memória no seu código podem levar a um desempenho mais lento ao longo do tempo e, eventualmente, causar a falha da sua aplicação. As fugas de memória ocorrem quando a aplicação não liberta memória quando já não é necessária. Com todas as personalizações e componentes de código no seu formulário, deve:
- Considerar minuciosamente e testar cenários para qualquer coisa responsável pela limpeza da memória, como classes responsáveis pela gestão do ciclo de vida de objetos.
- Limpar todas as subscrições e escutas de eventos, especialmente se estiverem no objeto
window. - Limpar todos os temporizadores, por exemplo
setInterval. - Evite, limite e limpe referências a objetos globais ou estáticos.
Para componentes de controlo personalizado, a limpeza pode ser feita no método de destruir.
Para obter mais informações sobre a correção de problemas de memória, aceda a esta documentação do programador do Edge.
Ferramentas que pode utilizar para ajudar a melhorar o desempenho das aplicações
Esta secção descreve as ferramentas que podem ajudá-lo a compreender os problemas de desempenho e a oferecer recomendações sobre como otimizar as suas personalizações em aplicações condicionadas por modelo.
Verificador de soluções
O verificador de soluções é uma potente ferramenta que pode analisar personalizações de clientes e servidores para problemas de desempenho ou fiabilidade. Pode analisar o JavaScript do lado do cliente, o XML do formulário e os plug-ins do lado do servidor .NET, e fornecer insights direcionados sobre o que pode tornar os utilizadores finais mais lentos. Recomendamos que execute verificadores de soluções sempre que publique alterações num ambiente de desenvolvimento para quaisquer preocupações de desempenho serem detetadas antes de chegarem aos utilizadores finais. Mais informações: Utilize o verificador de soluções para validar as aplicações condicionadas por modelo no Power Apps
Alguns exemplos de problemas relacionados com o desempenho encontrados com o verificador de soluções:
- il-specify-column. Evite selecionar todas as colunas através de APIs de consulta do Dataverse.
- web-use-async. Interagir com recursos HTTP e HTTPS de forma assíncrona.
-
web-avoid-ui-refreshribbon. Evite utilizar
refreshRibbonnoOnLoadeEnableRuledo formulário.
Verificador de objetos
O verificador de objetos executa diagnósticos em tempo real em objetos componentes dentro da sua solução. Se forem detetados problemas, é devolvida uma recomendação que descreve como corrigir o problema. Mais informações: Utilizar o verificador de objetos para diagnosticar um componente da solução (pré-visualização)
Passos seguintes
Conceber formulários principais eficazes em aplicações condicionadas por modelos