{"componentChunkName":"component---src-templates-blog-post-js","path":"/blog/power-apps-canvas-performance-delegacao-concurrent/","result":{"data":{"markdownRemark":{"frontmatter":{"title":"Power Apps Canvas: performance com delegação e concurrent","description":"Apps canvas lentos quase sempre têm a mesma raiz: delegação quebrada e carregamento serial. Veja padrões práticos para acelerar telas e queries no Dataverse.","date":"09 de agosto de 2026","thumbnail":null},"html":"<p>App canvas rápido em ambiente de teste e lento em produção é um clássico. Na maioria dos casos o problema não está no dispositivo do usuário, e sim em duas decisões de arquitetura tomadas cedo demais: como as queries são delegadas para a fonte de dados e como o <code>OnStart</code>/<code>OnVisible</code> carrega os dados. Este post é um roteiro prático para quem já entrega apps canvas em escala e precisa domar tempo de abertura e responsividade de tela.</p>\n<p><strong>Delegação: o gargalo silencioso</strong></p>\n<p>Delegação é a capacidade do Power Apps de empurrar o processamento de um filtro/ordenação para a fonte de dados, em vez de baixar tudo para o cliente e processar localmente. Quando uma função não é delegável para aquela fonte, o Power Apps traz apenas os primeiros 500 registros (ajustável até 2000 em Settings) e aplica a lógica localmente — resultado: números errados, listas truncadas e a temida barra amarela (delegation warning) no editor.</p>\n<p>Pontos que mudam na prática:</p>\n<ul>\n<li>A delegação depende do par <strong>função + conector</strong>. <code>Filter</code> com <code>StartsWith</code> é delegável no Dataverse e no SQL Server, mas <code>Search</code> não é delegável em vários conectores. Em SharePoint, o suporte é mais restrito que no Dataverse.</li>\n<li>Operações que quase sempre quebram delegação: <code>Filter</code> sobre colunas calculadas, comparações com funções não delegáveis (ex.: parte de datas manipulada em fórmula), <code>in</code> em texto e algumas combinações com <code>And</code>/<code>Or</code> aninhados.</li>\n<li>O limite de 500/2000 é um teto, não um alerta. Um app pode parecer correto no teste porque a tabela tem 300 linhas, e falhar silenciosamente em produção com 50 mil.</li>\n</ul>\n<p><strong>Como projetar para delegar</strong></p>\n<ol>\n<li>Prefira <strong>Dataverse</strong> como fonte para apps com volume — o suporte a delegação é o mais amplo da plataforma.</li>\n<li>Faça o filtro pesado na fonte e traga um conjunto reduzido. Se precisar de lógica não delegável, aplique-a depois sobre o conjunto já filtrado e pequeno.</li>\n<li>Materialize valores em variáveis antes do <code>Filter</code> quando a fórmula referencia funções não delegáveis: em vez de <code>Filter(Contas, Modified > DateAdd(Now(), -7, Days))</code>, calcule a data em <code>Set(dtCorte, ...)</code> e use <code>Filter(Contas, Modified > dtCorte)</code>.</li>\n<li>Trate o delegation warning como bug, não como aviso cosmético. Se ele aparece, assuma que os dados estão errados até prova em contrário.</li>\n</ol>\n<p><strong>Carregamento serial vs. Concurrent</strong></p>\n<p>O segundo grande vilão do tempo de abertura é o <code>OnStart</code> que executa uma dúzia de chamadas de dados em sequência. Cada <code>ClearCollect</code> espera o anterior terminar. A função <code>Concurrent</code> executa fórmulas independentes em paralelo:</p>\n<pre><code>Concurrent(\n    ClearCollect(colUsuarios, Filter(Usuarios, Ativo = true)),\n    ClearCollect(colCategorias, Categorias),\n    Set(varConfig, LookUp(Config, Chave = \"app\"))\n)\n</code></pre>\n<p>Se você tem cinco chamadas de ~400ms cada, o serial gasta ~2s e o <code>Concurrent</code> tende a gastar o tempo da mais lenta, não a soma. A regra: só paralelize fórmulas que <strong>não dependem</strong> do resultado uma da outra.</p>\n<p><strong>Menos no OnStart, mais sob demanda</strong></p>\n<p>O instinto de pré-carregar tudo no <code>OnStart</code> para \"deixar rápido depois\" costuma piorar o tempo de abertura, que é o momento em que o usuário mais percebe lentidão. Estratégias que ajudam:</p>\n<ul>\n<li>Carregue no <code>OnVisible</code> da tela apenas o que aquela tela precisa, não o app inteiro.</li>\n<li>Use <code>App.StartScreen</code> (propriedade nativa) em vez de <code>Navigate</code> dentro do <code>OnStart</code> — ele elimina a espera do <code>OnStart</code> para decidir a primeira tela.</li>\n<li>Evite <code>ClearCollect</code> de tabelas grandes só para exibir em uma galeria: aponte a galeria diretamente para a fonte delegável e deixe o Power Apps paginar.</li>\n<li>Cuidado com galerias aninhadas e fórmulas complexas em <code>Items</code> — elas reavaliam a cada scroll.</li>\n</ul>\n<p><strong>Medir antes de otimizar</strong></p>\n<p>Não otimize no achismo. O <strong>Monitor</strong> (dentro do Power Apps Studio, aba Advanced tools) mostra cada chamada de rede, sua duração e a fonte, permitindo identificar exatamente qual query está lenta e se foi delegada. Combine com o painel de análise de performance do app para separar o custo de rede do custo de renderização de controles.</p>\n<p><strong>Impacto de licenciamento</strong></p>\n<p>Vale lembrar que usar Dataverse como fonte — recomendação central para delegação e performance — exige licenciamento <strong>Power Apps Premium</strong> (per app ou per user) para os usuários do app. Conectores standard como SharePoint entram no Microsoft 365, mas com o custo de uma delegação mais limitada. Essa é uma decisão de arquitetura com efeito direto no TCO do app, e deve ser feita no início do projeto, não depois que a tabela cresceu.</p>\n<p>Apps canvas performáticos raramente são fruto de um truque isolado; são o resultado de projetar delegação desde o modelo de dados e disciplinar o carregamento. Se sua empresa mantém apps críticos que estão lentos conforme os dados crescem, a Dynamic Soluções pode revisar a arquitetura, o licenciamento e os padrões de fórmula com você — seja em um projeto pontual ou dentro de um plano de suporte contínuo.</p>\n<p>A canvas app that flies in testing and crawls in production is a classic. In most cases the problem isn't the user's device — it's two architecture decisions made too early: how queries are delegated to the data source, and how <code>OnStart</code>/<code>OnVisible</code> loads data. This post is a practical roadmap for teams already shipping canvas apps at scale who need to tame startup time and screen responsiveness.</p>\n<p><strong>Delegation: the silent bottleneck</strong></p>\n<p>Delegation is Power Apps' ability to push a filter/sort down to the data source instead of downloading everything to the client and processing locally. When a function isn't delegable for that source, Power Apps only pulls the first 500 records (adjustable up to 2000 in Settings) and applies the logic locally — the result: wrong numbers, truncated lists, and the dreaded yellow delegation warning in the editor.</p>\n<p>What changes in practice:</p>\n<ul>\n<li>Delegation depends on the <strong>function + connector</strong> pair. <code>Filter</code> with <code>StartsWith</code> is delegable in Dataverse and SQL Server, but <code>Search</code> isn't delegable in several connectors. In SharePoint, support is more limited than in Dataverse.</li>\n<li>Operations that almost always break delegation: <code>Filter</code> over calculated columns, comparisons with non-delegable functions (e.g., a date part manipulated inside a formula), <code>in</code> on text, and some nested <code>And</code>/<code>Or</code> combinations.</li>\n<li>The 500/2000 limit is a ceiling, not an alert. An app can look correct in testing because the table has 300 rows and then fail silently in production with 50,000.</li>\n</ul>\n<p><strong>Designing to delegate</strong></p>\n<ol>\n<li>Prefer <strong>Dataverse</strong> as the source for high-volume apps — it has the broadest delegation support on the platform.</li>\n<li>Do the heavy filtering at the source and bring back a small set. If you need non-delegable logic, apply it afterwards on the already-filtered, small set.</li>\n<li>Materialize values into variables before <code>Filter</code> when the formula references non-delegable functions: instead of <code>Filter(Accounts, Modified > DateAdd(Now(), -7, Days))</code>, compute the date in <code>Set(cutoffDate, ...)</code> and use <code>Filter(Accounts, Modified > cutoffDate)</code>.</li>\n<li>Treat the delegation warning as a bug, not a cosmetic notice. If it appears, assume the data is wrong until proven otherwise.</li>\n</ol>\n<p><strong>Serial loading vs. Concurrent</strong></p>\n<p>The second big villain of startup time is an <code>OnStart</code> running a dozen data calls in sequence. Each <code>ClearCollect</code> waits for the previous one to finish. The <code>Concurrent</code> function runs independent formulas in parallel:</p>\n<pre><code>Concurrent(\n    ClearCollect(colUsers, Filter(Users, Active = true)),\n    ClearCollect(colCategories, Categories),\n    Set(varConfig, LookUp(Config, Key = \"app\"))\n)\n</code></pre>\n<p>If you have five calls of ~400ms each, serial spends ~2s while <code>Concurrent</code> tends to spend the time of the slowest one, not the sum. The rule: only parallelize formulas that <strong>don't depend</strong> on each other's result.</p>\n<p><strong>Less in OnStart, more on demand</strong></p>\n<p>The instinct to pre-load everything in <code>OnStart</code> to \"make it fast later\" usually worsens startup time — the very moment the user perceives lag most. Strategies that help:</p>\n<ul>\n<li>Load in a screen's <code>OnVisible</code> only what that screen needs, not the whole app.</li>\n<li>Use <code>App.StartScreen</code> (a native property) instead of <code>Navigate</code> inside <code>OnStart</code> — it removes the wait for <code>OnStart</code> to decide the first screen.</li>\n<li>Avoid <code>ClearCollect</code> of large tables just to display them in a gallery: point the gallery directly at the delegable source and let Power Apps paginate.</li>\n<li>Beware of nested galleries and complex formulas in <code>Items</code> — they re-evaluate on every scroll.</li>\n</ul>\n<p><strong>Measure before optimizing</strong></p>\n<p>Don't optimize on hunches. <strong>Monitor</strong> (inside Power Apps Studio, Advanced tools tab) shows every network call, its duration and its source, letting you pinpoint exactly which query is slow and whether it was delegated. Combine it with the app's performance analysis panel to separate network cost from control rendering cost.</p>\n<p><strong>Licensing impact</strong></p>\n<p>Remember that using Dataverse as the source — the central recommendation for delegation and performance — requires <strong>Power Apps Premium</strong> licensing (per app or per user) for the app's users. Standard connectors like SharePoint are included in Microsoft 365, but at the cost of more limited delegation. This is an architecture decision with a direct effect on the app's TCO, and it should be made at the start of the project, not after the table has grown.</p>\n<p>Performant canvas apps rarely come from a single trick; they're the result of designing delegation from the data model up and disciplining data loading. If your company runs critical apps that slow down as data grows, Dynamic Soluções can review the architecture, licensing and formula patterns with you — whether in a one-off project or within an ongoing support plan.</p>"}},"pageContext":{"slug":"/blog/power-apps-canvas-performance-delegacao-concurrent/","previousPost":{"frontmatter":{"title":"Power Automate + Azure Functions: quando sair do connector nativo"},"fields":{"slug":"/blog/power-automate-azure-functions-integracao-quando-usar/"}},"nextPost":{"frontmatter":{"title":"Power BI: reduza tamanho do modelo com otimização de VertiPaq"},"fields":{"slug":"/blog/power-bi-otimizacao-modelo-vertipaq-cardinalidade/"}}}},"staticQueryHashes":["2269431855"]}