Compartilhar via


Criar aplicativos de tela grandes e complexos

A maioria dos artigos nesta seção da documentação abrange o desempenho do tempo de execução de aplicativos conforme experimentado pelas pessoas que os usam. Este artigo aborda o desempenho do aplicativo conforme experimentado pelas pessoas que os criam.

À medida que os aplicativos se tornam maiores e mais complexos, o Power Apps Studio precisa carregar e gerenciar um número maior de controles, fórmulas e fontes de dados, todos com interdependências que crescem exponencialmente. O Power Apps Studio pode levar mais tempo para carregar, e recursos como o IntelliSense e a codificação de cores podem atrasar. Use as recomendações a seguir para trabalhar melhor com aplicativos grandes e complexos no Power Apps Studio. Eles também podem ajudar a melhorar o desempenho do tempo de execução de seus aplicativos.

Os exemplos neste artigo usam a solução de exemplo Hospital Emergency Response..

Usar App.Formulas em vez de App.OnStart

Dica

Você pode usar a função With e as propriedades de saída personalizadas do componente de função e tela como alternativa a fórmulas nomeadas.

A melhor maneira de reduzir o tempo de carregamento no Power Apps Studio e em seu aplicativo é substituir a inicialização de variáveis e de coleções em App.OnStart por fórmulas nomeadas em App.Formulas.

Vamos dar uma olhada no exemplo a seguir, que usa App.OnStart.

// Get the color of text on a dark background.
Set(varColorOnDark,RGBA(0, 0, 0, 1));

// Get the color of the menu icons.
Set(varColorMenuIcon,"#0070a9");

// Get the styles for a form.
Set(varFormStyle,
    {
        DataCard: { Height: 50 },
        Title: { Height: 50, Size: 21, Color: varColorOnDark },
        Control: { Height: 50, Size: 18 },
        Label: { Size: 18, Color: varColorOnDark }
    }
);

ClearCollect(
    FacilitiesList,
    ForAll(
        Facilities,
        { Name: 'Facility Name', Id: Facility }
    )
);
If(
    Not IsBlank(Param("FacilityID")),
    Set(ParamFacility,
        LookUp(
            FacilitiesList,
            Id = GUID(Param("FacilityID"))
        ).Name
    );
);

Como elas são uma sequência de instruções, seu aplicativo deve avaliar essas chamadas a Set e Collect em ordem antes que a primeira tela possa ser exibida, o que faz com que o aplicativo seja carregado mais lentamente. E como o App.OnStart deve ser considerado com um todo, ordem preservada e erros agregados antes de retornar o resultado final, a fórmula é complexa para o Power Apps Studio analisar.

Há uma maneira melhor. Em vez disso, use App.Formulas e defina essas variáveis e coleções como fórmulas nomeadas, como no exemplo a seguir.

// Get the color of text on a dark background.
varColorOnDark = RGBA(0, 0, 0, 1);

// Get the color of the menu icons.
varColorMenuIcon = "#0070a9";

// Get the styles for a form.
varFormStyle = 
    {
        DataCard: { Height: 50 },
        Title: { Height: 50, Size: 21, Color: varColorOnDark },
        Control: { Height: 50, Size: 18 },
        Label: { Size: 18, Color: varColorOnDark }
    };

FacilitiesList =
    ForAll(
        Facilities,
        { Name: 'Facility Name', Id: Facility }
    );

ParamFacility = 
    If( Not IsBlank(Param("FacilityID")),
        LookUp(
            FacilitiesList,
            Id = GUID(Param("FacilityID"))
        ).Name,
        Blank()
    );

Essa mudança pode parecer pequena, mas pode ter um impacto enorme. Como cada fórmula nomeada é independente das outras, o Power Apps Studio pode analisá-los de forma independente, dividindo efetivamente um grande App.OnStart em partes menores. Nós vimos o tempo de carregamento do Power Apps Studio cai em até 80% somente com essa alteração.

Seu aplicativo também carregará mais rápido porque ela não precisará avaliar essas fórmulas até que precise do resultado. A primeira tela do aplicativo é exibida imediatamente.

As fórmulas nomeadas não podem ser usadas em todas as situações porque você não pode modificá-las ou usá-las com Set. Algumas situações requerem o uso de uma variável de estado que pode ser modificada. Set é perfeita para essas situações e você deve continuar a usá-la. Mas, na maioria das vezes, você está usando variáveis globais em OnStart para configurar valores estáticos que não mudam. Nesses casos, uma fórmula nomeada é a melhor escolha.

Como as fórmulas nomeadas são imutáveis, o prefixo var (abreviação de "variável") como uma convenção de nomenclatura não é mais apropriado. Não alteramos os nomes neste exemplo porque seria necessário fazer alterações no restante do aplicativo para corresponder.

É tentador colocar uma fórmula nomeada em App.OnStart, mas não faça isso. Eles não pertencem a esse lugar. Como uma propriedade de comportamento On, App.OnStart avalia cada uma de suas instruções em ordem, criando variáveis globais e conversando com bancos de dados apenas uma vez quando o aplicativo é carregado. As fórmulas nomeadas são fórmulas que definem como calcular algo sempre que necessário e são sempre verdadeiras. É a natureza dessas fórmulas que permite que elas sejam independentes e permite que o aplicativo termine de ser carregado antes que elas sejam avaliadas.

Dividir fórmulas longas

App.OnStart é um dos piores infratores para fórmulas longas e definitivamente por onde você deve começar, mas não é o único caso.

Nossos estudos mostraram que quase todos os aplicativos com longo tempo de carregamento do Power Apps Studio têm pelo menos uma fórmula com mais de 256.000 caracteres. Alguns aplicativos com os tempos de carregamento mais longos têm fórmulas com mais de 1 milhão de caracteres. Fórmulas desse tamanho uma pressão significativa no Power Apps Studio.

Para piorar a situação, copiar e colar um controle com uma fórmula longa duplicará a fórmula nas propriedades do controle sem que isso seja percebido. Power Apps é modelado com base n o Excel, onde várias cópias de uma fórmula são comuns. No entanto, no Excel, as fórmulas são limitadas a uma expressão e limitadas a 8.000 caracteres. As fórmulas do Power Apps podem crescer muito mais com a introdução da lógica imperativa e do operador de encadeamento (; ou ;;, dependendo da localidade).

A solução geral é dividir fórmulas longas em partes menores e reutilizar as partes, como fizemos na seção anterior quando alteramos instruções Set/Collect em App.OnStart para as fórmulas nomeadas em App.Formulas. Em outras linguagens de programação, as partes reutilizáveis geralmente são chamadas de sub-rotinas ou funções definidas pelo usuário. Você pode considerar as fórmulas nomeadas como uma forma simples de funções definidas pelo usuário sem parâmetros ou efeitos colaterais.

Usar fórmulas nomeadas em todos os lugares

No exemplo anterior, usamos fórmulas nomeadas como uma substituição para App.OnStart. No entanto, você pode usá-las para substituir um cálculo em qualquer lugar de um aplicativo.

Por exemplo, uma das telas na solução de exemplo Hospital Emergency Response inclui essa lógica em Screen.OnVisible:

ClearCollect(
    MySplashSelectionsCollection,
    {
        MySystemCol: First(
            Filter(
                Regions,
                Region = MyParamRegion
            )
        ).System.'System Name',
        MyRegionCol: First(
            Filter(
                Regions,
                Region = MyParamRegion
            )
        ).'Region Name',
        MyFacilityCol: ParamFacility,
          MyFacilityColID:  LookUp(
            FacilitiesList,
            Id = GUID(Param("FacilityID"))
        ).Id
    }
); 

Essa fórmula pode ser dividida em um conjunto de fórmulas nomeadas. Isso também torna a fórmula mais fácil de ler.

MyRegion = LookUp(
                    Regions,
                    Region = MyParamRegion
           );

MyFacility = LookUp(
                    FacilitiesList,
                    Id = GUID(Param("FacilityID")
            );

MySplashSelectionsCollection = 
    {
        MySystemCol: MyRegion.System.'System Name',
        MyRegionCol: MyRegion.'Region Name',
        MyFacilityCol: ParamFacility,
        MyFacilityColID:  MyFacility.Id
    };

Extraímos ParamFacility como uma fórmula nomeada anteriormente quando movemos a maioria das chamadas Set de App.OnStart para fórmulas nomeadas em App.Formulas.

As fórmulas nomeadas são avaliadas apenas quando seus valores são necessários. Se a intenção original do uso de Screen.OnVisible era adiar o trabalho até a tela ser mostrada, então o trabalho ainda será adiado como fórmulas nomeadas globais em App.Formulas.

Usar a função With

Você também pode usar a função With em uma fórmula para dividir a lógica. Crie um registro no primeiro parâmetro com os valores que deseja usar como campos e use esses campos no segundo parâmetro para calcular o valor de retorno de With. Por exemplo, o exemplo anterior pode ser escrito como apenas uma fórmula nomeada:

MySplashSelectionsCollection = 
    With( { MyRegion: LookUp(
                            Regions,
                            Region = MyParamRegion
                      ),
            MyFacility: LookUp(
                            FacilitiesList,
                            Id = GUID(Param("FacilityID")
                      ) 
           },
           {
                MySystemCol: MyRegion.System.'System Name',
                MyRegionCol: MyRegion.'Region Name',
                MyFacilityCol: ParamFacility,
                MyFacilityColID:  MyFacility.Id
           }
    )

Uma desvantagem de usar With dessa maneira é que MyFacility não pode usar MyRegion porque elas são definidas no mesma função With , um problema que não está presente nas fórmulas nomeadas. Uma solução é aninhar funções With e usar a palavra-chave As para nomear o registro de cada uma para facilitar o acesso a todas as variáveis With.

Usar componentes de tela

Os componentes da tela são usados com mais frequência para criar um controle de interface do usuário que pode ser colocado na tela como um controle. Você também pode usá-los sem colocá-los na interface do usuário para realizar cálculos com propriedades de saída personalizadas sendo uma alternativa às fórmulas nomeadas. Os componentes da tela são fáceis de compartilhar entre aplicativos com bibliotecas de componentes e, diferentemente das fórmulas nomeadas, são totalmente compatíveis. No entanto, são mais difíceis de configurar e usar do que as fórmulas nomeadas.

Para dividir a lógica:

  1. No Power Apps Studio, alterne para a guia Componentes no Exibição de árvore.
  2. Crie um novo componente.
  3. No painel Propriedades, ative Acessar escopo do aplicativo.
  4. Adicione uma propriedade personalizada.
  5. Defina o Tipo de propriedade como Saída e o Tipo de dados conforme o apropriado.
  6. Selecione Criar.
  7. No seletor de propriedades ao lado da barra de fórmulas na parte superior da tela, selecione a nova propriedade.
  8. Escreva a fórmula para a lógica a ser dividida e reutilizada.

Para usar a lógica:

  1. Alterne para a guia Telas do Exibição de árvore.
  2. No painel Inserir , expanda Personalizado e insira seu componente.
  3. Para calcular um valor com a propriedade, use ComponentName.PropertyName.

Usar Select com um controle oculto para lógica imperativa

A lógica imperativa é usada para modificar o estado com Set e Collect, notificar o usuário com Notify, navegar para outra tela ou aplicativo com Navigate e Launch e gravar valores em um banco de dados com Patch, SubmitForm ou RemoveIf.

As propriedades de saída personalizadas do componente de tela e as fórmulas nomeadas não oferecem suporte à lógica imperativa. Uma maneira comum de dividir a lógica imperativa é usar a propriedade OnSelect de um controle oculto.

  1. Adicione um controle Botão a uma tela.
  2. Defina a propriedade OnSelect para a lógica imperativa que você deseja executar.
  3. Defina a propriedade Visible como falso, pois não há necessidade de o usuário ver ou interagir com ela.
  4. Chame Select( Button ) quando quiser executar a lógica imperativa.

Por exemplo, uma das telas em nosso exemplo tem esta propriedade OnSelect em um controle Botão. (Este exemplo simples é somente para fins ilustrativos. Normalmente, você só usaria essa técnica para fórmulas mais longas.)

btnAction_17.OnSelect = 
    Trace("Feedback Screen: Submit Button",TraceSeverity.Information);
    If(
        // Proceed if all forms are validated.
        And(
            FormFeedback.Valid
        ),
    
        // Set the updates to static variables.
        Set(updatesFeedback,Patch(Defaults('App Feedbacks'), FormFeedback.Updates));
        // Submit the first form. Subsequent actions can be found in the OnSuccess.
        SubmitForm(FormFeedback);
        ,
    
        Notify("Please complete all fields before proceeding",
               NotificationType.Warning,2000)
    );

Para dividir essa lógica em partes, podemos colocar partes em controles Botão separados e usar Select para selecioná-las no original:

btnTrace.OnSelect = 
    Trace("Feedback Screen: Submit Button",TraceSeverity.Information);

btnSubmit.OnSelect = 
    If(
        // Proceed if all forms are validated.
        And(
            FormFeedback.Valid
        ),
    
        // Set the updates to static variables.
        Set(updatesFeedback,Patch(Defaults('App Feedbacks'), FormFeedback.Updates));
        // Submit the first form. Subsequent actions can be found in OnSuccess.
        SubmitForm(FormFeedback);
        ,
    
        Notify("Please complete all fields before proceeding",
               NotificationType.Warning,2000)
    );

btnAction_17.OnSelect = 
    Select( btnTrace );
    Select( btnSubmit );

Esta técnica só funciona na mesma tela. Outras técnicas um pouco mais complicadas funcionam em várias telas, como usar o controle Alternância , definir OnCheck como a lógica você deseja executar e definir Default como uma variável global e, em seguida, alternar a variável global com Set( global, true ); Set( global, false ) no ponto em que deseja executar a lógica.

Neste exemplo, algumas divisões lógicas já foram feitas. O comentário menciona que "Ações subsequentes podem ser encontradas em OnSuccess". Este evento executa a lógica imperativa após o registro ter sido submetido com êxito, uma solução específica para a função SubmitForm.

Particionar o aplicativo

Alguns aplicativos crescem para milhares de controles e centenas de fontes de dados, o que torna o Power Apps Studio mais lento. Assim como as fórmulas longas, os aplicativos grandes podem ser divididos em seções menores que trabalham juntas para criar uma experiência de usuário.

Separar aplicativos de tela

Uma abordagem é implementar seções em aplicativos de tela separados e usar a função Launch para navegar entre os aplicativos separados e passar o contexto necessário.

Essa abordagem foi usada na solução de exemplo Hospital Emergency Response. Aplicativos separados gerenciam cada uma das principais áreas do aplicativo em geral. Os aplicativos compartilham um componente de menu de controle comum por meio de uma biblioteca de componentes que cada aplicativo mostra em sua tela de inicialização:

Captura de tela do aplicativo de tela da solução de exemplo Hospital Emergency Response em execução em um telefone, mostrando o componente do menu de controle

Quando o usuário seleciona uma área, o componente usa metadados sobre os aplicativos disponíveis e qual aplicativo está hospedando o componente. Se a tela desejada estiver nesse aplicativo (ou seja, ThisItem.Screen não estiver em branco), será feita uma chamada a Navigate. Mas se a tela desejada estiver em um aplicativo diferente (ou seja, ThisItem.PowerAppID não estiver em branco), uma função Launch será usada com a ID do Aplicativo do destino e o contexto de FacilityID:

If(
    IsBlank(ThisItem.Screen),
    If(IsBlank(ThisItem.PowerAppID), 
        Launch(ThisItem.URL),           
        Launch("/providers/Microsoft.PowerApps/apps/" & ThisItem.PowerAppID, 
               "FacilityID", Home_Facility_DD.Selected.Id)
    ),
    Navigate(
        ThisItem.Screen,
        Fade
    )
);

O estado no aplicativo original será perdido quando outro aplicativo for iniciado. Certifique-se de salvar qualquer estado antes de chamar a função Launch. Grave-o em um banco de dados, chame SaveData ou passe o estado para o aplicativo de destino com parâmetros que são lidos com a função Param.

Aplicativo baseado em modelo com páginas personalizadas

As seções também podem ser implementadas como páginas personalizadas. As páginas personalizadas atuam como um mini aplicativo de tela, com um contêiner de aplicativos baseados em modelo para navegação.

Observação

Você pode nos falar mais sobre suas preferências de idioma para documentação? Faça uma pesquisa rápida. (Observe que esta pesquisa está em inglês)

A pesquisa levará cerca de sete minutos. Nenhum dado pessoal é coletado (política de privacidade).