Compartir a través de


Optimización de código

A medida que las aplicaciones de lienzo evolucionan para satisfacer diversos requisitos comerciales, el desafío de mantener un rendimiento óptimo se convierte en una consideración crítica. Las complejidades del manejo de datos, el diseño de la interfaz de usuario y la funcionalidad dentro de las aplicaciones de lienzo requieren un enfoque matizado para la optimización del código.

A medida que las aplicaciones de lienzo se vuelven más complejas, los desarrolladores enfrentan desafíos relacionados con la recuperación de datos, la complejidad de las fórmulas y las velocidades de renderizado. La necesidad de lograr un equilibrio entre una funcionalidad sólida y una interfaz de usuario responsiva subraya la importancia de adoptar un enfoque sistemático para la optimización del código.

Power Fx optimización de fórmulas

Función With

La función With evalúa una fórmula para un solo registro. La fórmula puede calcular un valor o realizar acciones, como modificar datos o trabajar con una conexión. Utilice With para mejorar la legibilidad de fórmulas complejas dividiéndolas en subfórmulas con nombres más pequeños. Estos valores nombrados actúan como variables locales simples confinadas al alcance de With. Es preferible usar With que variables de contexto o globales, ya que es autónomo, fácil de entender y puede usarse en cualquier contexto de fórmula declarativa. Más información acerca de la función With.

Una captura de pantalla de una fórmula Power Fx que utiliza la función With

Función Concurrent

La función Concurrent permite evaluar, de forma simultánea, varias fórmulas especificadas dentro de la misma propiedad si tienen conector o llamadas de Dataverse. Normalmente, para evaluar varias fórmulas estas se encadenan con el operador ; (punto y coma), que evalúa cada fórmula de manera secuencial. Con la función Concurrent, la aplicación evaluará todas las fórmulas de una misma propiedad simultáneamente, incluso después de usar el operador ;. Esta simultaneidad ayuda a los usuarios a esperar menos para obtener el mismo resultado. Si las llamadas de datos no se inician hasta que terminan las llamadas anteriores, la aplicación debe esperar la suma de todos los tiempos de solicitud. Si las llamadas de datos se inician al mismo tiempo, la aplicación solo debe esperar el tiempo de solicitud más largo. Más información acerca de la función Concurrent.

Concurrent(
    ClearCollect(colAccounts1, Accounts),
    ClearCollect(colUsers1, Users),
    ClearCollect(colEnvDef1, 'Environment Variable Definitions'),
    ClearCollect(colEnvVal1, 'Environment Variable Values')
);

Función Coalesce

La función Coalesce evalúa sus argumentos en orden y devuelve el primer valor que no sea blank o una cadena vacía. Use esta función para reemplazar los valores blank o las cadenas vacías por un valor diferente dejando sin cambios los valores que no sean blank o cadenas vacías. Si todos los argumentos son blank o cadenas vacías, la función devuelve blank, lo que hace de Coalesce una buena forma de convertir cadenas vacías en valores blank.

Por ejemplo:

If(Not IsBlank(value1), value1, Not IsBlank(value2), value2)

Requiere que el valor 1 y el valor 2 se evalúen dos veces. Esta función se puede reducir a:

Coalesce(value1, value2)

Función IsMatch

La función IsMatch comprueba si una cadena de texto coincide con un patrón que puede incluir caracteres normales, patrones predefinidos o una expresión regular. Más información acerca de la función IsMatch.

Por ejemplo, esta fórmula establece una coincidencia con un número de la Seguridad Social de Estados Unidos:

IsMatch(TextInput1.Text, "\d{3}-\d{2}-\d{4}")

Explicación de la expresión regular:

\\d Coincide con cualquier dígito (0-9).

{3} Especifica que el patrón de dígitos anterior (\d) debe aparecer exactamente tres veces.

- Coincide con el carácter guion.

{2} Especifica que el patrón de dígitos anterior (\d) debe aparecer exactamente dos veces.

{4} Especifica que el patrón de dígitos anterior (\d) debe aparecer exactamente cuatro veces.

Más ejemplos de IsMatch:

IsMatch(TextInput1.Text, "Hello World")
IsMatch(TextInput1\_2.Text, "(?!^\[0-9\]\\\*$)(?!^\[a-zA-Z\]\\\*$)(\[a-zA-Z0-9\]{8,10})")

Optimizar OnStart de la aplicación

La propiedad OnStart de las aplicaciones de lienzo desempeña un papel crucial a la hora de definir las acciones que se producen cuando se inicia la aplicación. Esta propiedad permite a los desarrolladores de aplicaciones ejecutar tareas de inicialización globales, configurar variables y realizar acciones que deberían ocurrir solo una vez durante el proceso de inicio de la aplicación. Comprender y utilizar eficazmente la propiedad OnStart es esencial para crear aplicaciones de lienzo receptivas y eficientes.

Un enfoque recomendado es simplificar la función App.OnStart migrando configuraciones de variables a fórmulas con nombre. Las fórmulas con nombre, especialmente aquellas configuradas al principio del ciclo de vida de la aplicación, resultan ventajosas. Estas fórmulas manejan la inicialización de variables basadas en llamadas de datos, proporcionando una estructura más limpia y organizada para su código. Más detalles Crea aplicaciones de lienzo grandes y complejas - Power Apps | Microsoft Learn.

Nota

La propiedad OnStart es imperativa. Es una lista ordenada de trabajo que debe realizarse antes de que se muestre la primera pantalla. Porque es tan específico no solo acerca de qué hay que hacer, sino también cuándo se debe hacer ese trabajo en función del orden, limita la reordenación y el aplazamiento de optimizaciones que de otro modo podrían realizarse.

Iniciar pantalla

Si App.OnStart contiene una llamada de función Navigate, incluso si está en una función If que se llama raramente, debemos completar la ejecución de App. OnStart antes de mostrar la primera pantalla de la aplicación.  App.StartScreen es la nueva forma declarativa de indicar qué pantalla se debe mostrar primero, que no bloquea las optimizaciones.

Al configurar la propiedad StartScreen se muestra la primera pantalla antes de que se complete App.OnStart . App.StartScreen declares qué objeto de pantalla mostrar primero sin requerir ningún procesamiento previo.

En lugar de escribir código como:

App.OnStart = Collect(OrdersCache, Orders);
If(Param("AdminMode") = "1", Navigate(AdminScreen), Navigate(HomeScreen))

Cambio del código a:

App.OnStart = Collect(OrdersCache, Orders);
App.StartScreen = If(Param("AdminMode") = "1", AdminScreen, HomeScreen)

Consulte <https://Power Apps.microsoft.com/es-es/blog/app-startscreen-a-new-declarative-alternative-to-navigate-in-app-onstart/>para más detalles.

Advertencia

Evite dependencias entre StartScreen y OnStart. Hacer referencia a una fórmula con nombre que a su vez hace referencia a una variable global puede provocar una condición de carrera en la que StartScreen no se aplica correctamente. Nota: no deberíamos tener dependencias entre StartScreen y OnStart. Bloqueamos las referencias a variables globales en StartScreen, pero podemos hacer referencia a una fórmula con nombre, que a su vez hace referencia a una variable global, y eso puede causar una condición de carrera en la que StartScreen no se aplica correctamente.

Fórmulas con nombre

Las fórmulas con nombre son estáticas o constantes que se pueden definir en la sección App.Formulas. Una vez declarados en App.Formulas, se pueden usar en cualquier parte de la aplicación y su valor siempre permanece actualizado. Las fórmulas con nombre en Power Apps permiten la definición de valores o conjuntos de valores que la plataforma administra y actualiza automáticamente. Esta funcionalidad transfiere la responsabilidad del cálculo del valor y el mantenimiento del desarrollador a Power Apps, agilizando el proceso de desarrollo. Las fórmulas con nombre en Power Apps son una potente funcionalidad que puede mejorar significativamente el rendimiento y la capacidad de mantenimiento de la aplicación.

Las fórmulas con nombre también pueden tratar la declaración de temas de aplicaciones. En muchos casos en los que se crean aplicaciones empresariales, queremos que la aplicación tenga temas comunes para brindar una apariencia y una experiencia de usuario consistentes. Para crear un tema, hay decenas y centenas de variables que deben declararse en App OnStart. Esto aumentó la longitud del código y el tiempo de inicialización de la aplicación.

Los controles modernos también pueden ayudar significativamente con la tematización y ayudar a reducir la lógica personalizada para manejar la tematización. Los controles modernos se encuentran actualmente en versión preliminar.

Por ejemplo, el siguiente código en App.OnStart se puede mover a App.Formulas, reduciendo así el tiempo de inicio de las declaraciones de variables globales.

Set(BoardDark, RGBA(181,136,99, 1));
Set(BoardSelect, RGBA(34,177,76,1));
Set(BoardRowWidth, 10);                      // expected 8 plus two guard characters for regular expressions.
Set(BoardMetadata, 8 \* BoardRowWidth + 1);   // which player is next, have pieces moved for castling rules, etc.
Set(BoardBlank, "----------------------------------------------------------------\_00000000000000");
Set(BoardClassic, "RNBQKBNR\_\_PPPPPPPP------------------------\_--------\_\_pppppppp\_\_rnbqkbnr\_\_0000000000");

El código se puede mover a App.Formulas de la siguiente manera:

BoardSize = 70;
BoardLight = RGBA(240,217,181, 1);
BoardDark = RGBA(181,136,99, 1);
BoardSelect = RGBA(34,177,76,1);
BoardRowWidth = 10;                      // expected 8 plus two guard characters for regular expressions
BoardMetadata = 8 \* BoardRowWidth + 1;   // which player is next, have pieces moved for castling rules, etc.
BoardBlank = "----------------------------------------------------------------\_00000000000000";
BoardClassic = "RNBQKBNR\_\_PPPPPPPP------------------------\_--------\_\_pppppppp\_\_rnbqkbnr\_\_0000000000";

Otro ejemplo es en la configuración de Lookups. Aquí, se requiere un cambio en una fórmula de búsqueda para obtener la información del usuario de Office 365, en lugar de Dataverse. Solo hay un lugar donde se requiere el cambio sin cambiar el código en todas partes.

UserEmail = User().Email;
UserInfo = LookUp(Users, 'Primary Email' = User().Email);
UserTitle = UserInfo.Title;
UserPhone = Switch(UserInfo.'Preferred Phone', 'Preferred Phone (Users)'.'Mobile Phone', UserInfo.'Mobile Phone',
UserInfo.'Main Phone');

Estas fórmulas representan la esencia del cálculo. Expresan el proceso para determinar UserEmail, UserInfo, UserTitle y UserPhone en función de otros valores. Esta lógica está encapsulada, lo que permite una utilización generalizada en toda la aplicación y se puede modificar en una ubicación singular. La adaptabilidad se extiende al cambio de la tabla de usuarios de Dataverse al conector de Office 365 sin necesidad de realizar modificaciones en las fórmulas repartidas por la aplicación.

Otro enfoque es optimizar countRows.

varListItems = CountRows(SampleList)

Con la función Set , la variable varListItems deberá inicializarse con el recuento inicial de filas en la lista de muestra y configurarse nuevamente después de agregar o eliminar los elementos de la lista. Con las fórmulas con nombre, a medida que cambian los datos, las variables varListitems se actualizan automáticamente.

Las fórmulas con nombre en la propiedad App.Formulas brindan un enfoque más flexible y declarativo para administrar valores y cálculos en toda la aplicación, lo que ofrece ventajas en términos de independencia temporal, actualizaciones automáticas, mantenibilidad y definiciones inmutables en comparación con depender únicamente de App.OnStart.

Aspecto Fórmulas con nombre (App.Formulas) App.OnStart
Independencia temporal Las fórmulas están disponibles al instante y se pueden calcular en cualquier orden. Las variables pueden introducir dependencias de tiempo, lo que afecta la disponibilidad.
Actualizaciones automáticas Las fórmulas se actualizan automáticamente cuando cambian las dependencias. Las variables se establecen una vez durante el arranque; puede ser necesario actualizarlas manualmente.
Mantenimiento Las fórmulas centralizadas en una ubicación mejoran la mantenibilidad. Las variables dispersas pueden requerir búsqueda y actualización en varios lugares.
Definiciones inmutables Las definiciones de fórmulas en App.Formulas son inmutables. Los valores variables pueden ser susceptibles a cambios accidentales.

Funciones definidas por el usuario

Las funciones definidas por el usuario son una funcionalidad experimental de Power Apps Authoring Studio que permite a los usuarios crear su propia función personalizada.

Para utilizar esta característica, en la configuración experimental, seleccione Nuevo motor de análisis y Función definida por el usuario (UDF)

Defina una fórmula en App.Formulas de la siguiente manera:

FunctionName(Parameter1:DataType1, Parameter2:DataType2):OutputDataType = Formula

El código funciona así:

  • FunctionName se utiliza para invocar la función

  • Parameter es el nombre de la entrada. Se permiten una o más entradas

  • DataType es un argumento que se pasa a la función y debe coincidir con este tipo de datos. Los tipos de datos disponibles incluyen booleano, color, fecha, fecha y hora, GUID, hipervínculo, texto, hora y objeto sin tipo.

  • OutputDataType es el tipo de datos en el que estará la salida de la función

  • Formula es la salida de la función

// Function to calculate the area of a circle based on the radius
calcAreaOfCircle(radius: Number): Number = 
    IfError(Pi() * radius * radius, 0);

Use IfError para implementar la gestión de errores dentro de la función definida.

Llame a la función definida desde el control de texto/etiqueta.

calcAreaOfCircle(Int(*TextInput1*.Text))

Nota

Se trata de una función experimental y está sujeta a cambios. Algunos tipos de datos, como registros y filtros, aún no se admiten.

Optimizar variables

Las variables se utilizan para definir y establecer valores locales y globales que se utilizarán en todas partes de las aplicaciones. Si bien son convenientes, demasiados de ellos pueden hacer que la aplicación esté menos optimizada.

El siguiente ejemplo demuestra la configuración de una variable para cada atributo de un objeto, lo que requiere usar Set para cada propiedad.

Set(varEmpName, Office365Users.MyProfile().DisplayName);
Set(varEmpCity, Office365Users.MyProfile().City);
Set(varEmpPhone, Office365Users.MyProfile().BusinessPhones);
Set(varEmpUPN, Office365Users.MyProfile().UserPrincipalName);
Set(varEmpMgrName, Office365Users.ManagerV2(varEmpUPN).DisplayName);

Un enfoque más optimizado consiste en utilizar la propiedad cuando la necesite:

Set(varEmployee, Office365Users.MyProfile())
"Welcome " & varEmployee.DisplayName

Utilice sabiamente las variables de contexto y las variables globales. Si el alcance de una variable se expande más allá de una sola pantalla, considere usar variables globales en lugar de variables de contexto.

Demasiadas variables no utilizadas contribuyen a un mayor uso de la memoria y a una inicialización de la aplicación ligeramente más lenta. Esto se debe a que se asignan recursos para estas variables aunque no se utilicen activamente. Demasiadas variables no utilizadas también pueden generar una complejidad general de la lógica de la aplicación. Si bien el impacto de las variables no utilizadas puede no ser grave, es una buena práctica mantener una Power App limpia y bien organizada para garantizar un rendimiento óptimo y facilidad de desarrollo.

Optimizar colecciones

Las colecciones son estructuras de almacenamiento de datos temporales que se pueden utilizar para almacenar y manipular datos dentro de una aplicación Power Apps . Sin embargo, existe una delgada línea sobre cuándo las colecciones pueden provocar una sobrecarga en el rendimiento. Por lo tanto, limite el uso de colecciones. Intente utilizarlas solo cuando sean necesarias.

// Use this pattern
ClearCollect(colErrors, {Text: gblErrorText, Code: gblErrorCode});

// Do not use this pattern
Clear(colErrors);
Collect(colErrors, {Text: gblErrorText, Code: gblErrorCode});

Para contar los registros en una colección local, use CountIf en lugar de Count(Filter()).

Considere esta guía cuando trabaje con colecciones:

Limite el tamaño y el número de colecciones. Dado que las colecciones son locales de la aplicación, se almacenan en la memoria del dispositivo móvil. Cuantos más datos contengan las colecciones o mayor sea el número de colecciones, peor será el rendimiento. Utilice la función ShowColumns para obtener solo las columnas específicas. Agregue la función Filter para obtener solo los datos relevantes.

La siguiente función de ejemplo devuelve el conjunto de datos completo.

ClearCollect(colDemoAccount, Accounts);

Compare con el código siguiente que devolverá solo registros y columnas específicos:

ClearCollect(colAcc,
              ShowColumns(
                Filter(Accounts, !IsBlank('Address 1: City')),
                "name","address1_city"))

El código de ejemplo devuelve este conjunto de datos:

Una captura de pantalla de un conjunto de datos con una tabla denominada colAcc y dos columnas con datos, address1_city y name

Establezca una frecuencia de actualización de la fuente de datos. Si está agregando nuevos registros a la colección, debe actualizarla o recopilarla para obtener los registros nuevos o modificados en la colección. Si varios usuarios actualizan su fuente de datos, deberá actualizar la colección para obtener los registros nuevos o modificados. Más llamadas de actualización significan más interacción con el servidor.

Almacene datos en caché en colecciones y variables

Una colección, esencialmente una variable de tabla, se distingue porque almacena filas y columnas de datos en lugar de un único elemento de datos. Su utilidad radica en dos propósitos principales: en primer lugar, agregar datos antes de transmitirlos a la fuente de datos y, en segundo lugar, almacenar información en caché, eliminando la necesidad de realizar consultas frecuentes a la fuente de datos. Como las colecciones se alinean con la estructura tabular tanto de la fuente de datos como de Power Apps, ofrecen un medio eficiente para interactuar con los datos, incluso en escenarios fuera de línea.

// Clear the contents of EmployeeCollection, it already contains data
ClearCollect(
    colEmployee,
    {
        Id: "1",
        Name: "John",
        Department: "IT"
    },
    {
        Id: "2",
        Name: "Nestor",
        Department: "IT"
    }
)

Eliminar variables y medios no utilizados

Si bien los medios y las variables no utilizados pueden no crear un impacto drástico en el rendimiento de la aplicación, es importante limpiar su aplicación de cualquier medio o variable no utilizados.

  • Los archivos multimedia no utilizados contribuyen al aumento general del tamaño de la aplicación. Esto puede provocar tiempos de carga de aplicaciones más lentos.

  • Las variables no utilizadas contribuyen a un mayor uso de la memoria y a una inicialización de la aplicación ligeramente más lenta. Esto se debe a que se asignan recursos para estas variables aunque no se utilicen activamente. Además, demasiadas variables no utilizadas pueden generar una complejidad general de la lógica de la aplicación.

  • Utilice App Checker para revisar los medios y variables no utilizados.

Optimizar las pantallas y los controles

Evitar controles cruzados

Los controles que hacen referencia a controles en otras pantallas pueden ralentizar la carga y navegación de la aplicación. Hacer esto puede forzar a la aplicación a cargar las otras pantallas inmediatamente, en lugar de esperar hasta que el usuario navegue hasta esa pantalla. Para solucionar este problema, utilice variables, colecciones y contexto de navegación para compartir el estado entre pantallas.

Power Apps El verificador de aplicaciones dentro del estudio de creación muestra controles con referencias cruzadas. Revise el Comprobador de aplicaciones con regularidad para solucionar este problema.

A continuación se muestra un ejemplo de controles con referencias cruzadas. En la imagen siguiente, los controles de la Galería 1 tienen una referencia cruzada en la Pantalla 2, control Etiqueta 2.

Una captura de pantalla de Power Apps Studio que muestra un control con referencias cruzadas

Si hace referencia a un control desde la primera pantalla de la aplicación en la segunda pantalla, no habrá ningún impacto en el rendimiento ya que la primera pantalla ya se ha cargado y esto puede ser algo bueno ya que la aplicación es declarativa en lugar de usar variables.

Si hace referencia a controles que aún no se han cargado, como la primera pantalla que hace referencia a un control llamado Label 3 de la pantalla 3, requerirá que la pantalla se cargue en memoria.

Habilitar DelayOutput para controles de texto

Retrasar la configuración de salida Cuando se establece en true, la entrada del usuario se registra después de un retraso de medio segundo. Resulta útil para retrasar operaciones costosas hasta que el usuario completa la entrada de texto, es decir, para el filtrado cuando la entrada se utiliza en otras fórmulas.

Por ejemplo, para una Galería cuyos elementos se filtran según lo que se ingresa en el control TextInput:

  • Con DelayOutput establecido en falso, que es el valor predeterminado, la Galería se filtra tan pronto como se escribe cualquier texto. Si tiene una galería con muchos elementos, recargar la Galería con los cambios inmediatamente ralentiza el rendimiento; sería más beneficioso esperar un poco. Esto es práctico cuando utiliza TextInput para una cadena de búsqueda (consulte Buscar o la nueva función StartsWith).

  • Con DelayOutput establecido en verdadero, hay un segundo retraso antes de que se detecten los cambios. Esto se hace para darle tiempo de terminar de escribir lo que desea. El retraso funciona bien cuando se utiliza para ayudar a la propiedad TextInput.OnChange. Si tiene acciones vinculadas a cambios, no querrá que se activen hasta que se escriba todo lo que desea en el campo.

Delegación y procesamiento del lado del servidor

Delegación

La delegación en Power Apps es un concepto que se refiere a la capacidad de la aplicación para trasladar ciertas operaciones al origen de datos subyacente en lugar de procesar las operaciones dentro de Power Apps misma. Al utilizar la delegación en Power Apps, los desarrolladores pueden crear aplicaciones más eficientes y escalables que funcionan bien incluso en escenarios que involucran grandes conjuntos de datos. Es importante ser consciente de las limitaciones de delegación para fuentes de datos y operaciones específicas y diseñar aplicaciones en consecuencia para lograr un rendimiento óptimo.

![NOTA] No todas las funciones son delegables. Consulte Entendiendo la Delegación para obtener más información sobre la delegación.

La delegación tiene varias ventajas, como la optimización de consultas, y agrega soporte para grandes conjuntos de datos. Además, si los datos de origen cambian con frecuencia, la delegación ayuda a mantener los datos actualizados.

Reducir las llamadas API al origen de datos

A veces, puede resultar conveniente simplemente seguir prácticas de codificación, como crear colecciones realizando uniones dentro de la aplicación Canvas. Consulte el código siguiente:

En este ejemplo, hay dos tablas, Conductores y Camiones. El desarrollador escribe el código para crear una colección de conductores y detalles de camiones y, para cada camión, invoca a los conductores que son propietarios de los camiones.

// Bad code
ClearCollect(vartruckdata, AddColumns('Truck Details',
    "CITY",LookUp(Drivers, 'Truck Details'\[@'Dummy ID'\] = Drivers\[@'Truck Details'\],City),
        "FIRSTNAME",LookUp(Drivers, 'Truck Details'\[@'Dummy ID'\] = Drivers\[@'Truck Details'\],'Driver First Name'),
    "LASTNAME",LookUp(Drivers, 'Truck Details'\[@'Dummy ID'\] = Drivers\[@'Truck Details'\],'Driver Last Name'),
        "STATE",LookUp(Drivers, 'Truck Details'\[@'Dummy ID'\] = Drivers\[@'Truck Details'\],State)));

Realizar dichas operaciones de unión desde la aplicación Canvas puede generar numerosas llamadas a la fuente de datos, lo que lleva a tiempos de carga muy lentos.

Un mejor enfoque es:

// Good code
Set(
    varTruckData,
    LookUp(
        Drivers,
        'Dummy ID' = ThisRecord.'Dummy ID',
        'Driver First Name'
    ) & LookUp(
        Drivers,
        'Dummy ID' = ThisRecord.'Dummy ID',
        'Driver Last Name'
        )
);

Set(
    varTruckData,
    With(
        {
            vDriver: LookUp(
                Drivers,
                'Dummy ID' = ThisRecord.'Dummy ID'
            )
        },
        vDriver.'Driver First Name' & vDriver.'Driver Last Name'
    )
)

En el escenario de tiempo real, es posible reducir los tiempos de carga de 5 minutos a menos de 10 segundos simplemente corrigiendo los datos en el nivel de la fuente de datos.

Procesamiento del lado del servidor

Diferentes fuentes de datos, como SQL y Dataverse le permiten delegar el procesamiento de datos, como filtros y consultas, a la fuente de datos. En SQL Server, los usuarios pueden crear vistas que tienen contenido definido por una consulta. De manera similar, con Dataverse, los usuarios pueden crear complementos de bajo código para escribir lógica para el procesamiento de datos en el lado del servidor y solo obtener los resultados finales en las aplicaciones de lienzo.

Delegar el procesamiento de datos en el servidor puede mejorar el rendimiento general, reducir el código en el lado del cliente y es fácil de mantener.

Más información acerca de complementos en Dataverse.

Optimizar patrones de datos de consulta

Usar la selección de columnas explícitas

La característica de selección explícita de columnas (ECS) está habilitada de forma predeterminada para todas las aplicaciones nuevas. Si no está habilitada para su aplicación, debe habilitarla. ECS reduce automáticamente la cantidad de columnas recuperadas a solo las que se utilizan en la aplicación. Si ECS no está habilitada, es posible que esté recuperando más datos de los que necesita, lo que puede afectar el rendimiento. En ocasiones, cuando una aplicación extrae datos a través de colecciones, se puede perder el linaje o el origen de una columna. No sabemos si se está utilizando y lo descartamos usando ECS. Por lo general, puede forzar a ECS a trabajar con una columna faltante usando la expresión PowerFx ShowColumns después de una referencia de colección o usándola en un control.

Evitar llamar a Power Automate para rellenar una colección

Una práctica común es utilizar Power Automate para buscar y rellenar colecciones en Power Apps. Si bien este enfoque es válido, hay situaciones en las que podría no ser la opción más eficiente. Llamar a Power Automate provoca una sobrecarga de latencia de red y agrega un coste de rendimiento de 0,6 segundos para instanciar el flujo de Power Automate.

El uso excesivo de flujos de Power Automate también puede provocar limitaciones de ejecución y limitación. Por lo tanto, evalúe siempre las compensaciones entre la latencia de la red y el coste de rendimiento.

Eliminar el problema N+1

El problema N+1 es un problema común en las consultas de bases de datos donde, en lugar de recuperar todos los datos requeridos en una sola consulta, se realizan varias consultas adicionales para recuperar datos relacionados. Esto puede provocar problemas de rendimiento, ya que cada consulta adicional genera una sobrecarga.

Una simple llamada como esta para cargar una colección puede generar N+1 llamadas a la fuente de datos.

ClearCollect(MyCollection, OrdersList,
    {
        LookUp(CustomersList,CustomerID = OrdersList[@CustomerID])
    }
)

En el contexto de galerías y aplicaciones de lienzo, el problema N+1 puede surgir al trabajar con fuentes de datos y galerías que muestran registros relacionados. El problema suele ocurrir cuando se realizan más consultas para cada elemento que se muestra en la galería, lo que genera un cuello de botella en el rendimiento.

Utilice objetos de vista en SQL Server para evitar problemas de consulta N+1 o cambie la interfaz de usuario para evitar desencadenar el escenario N+1.

Dataverse recupera automáticamente los datos requeridos de las tablas relacionadas y puede seleccionar las columnas de las tablas relacionadas.

ThisItem.Account.'Account Name'

Si el tamaño de RelatedDataSource` es pequeño (<500 registros), puede almacenarlo en caché en una colección y usar la colección para impulsar el escenario de consulta de búsqueda (N+1).

Limitar el tamaño del paquete

Aunque Power Apps hace mucho para optimizar la carga de aplicaciones, puede tomar medidas para reducir el espacio que ocupan las aplicaciones. Una huella reducida es especialmente importante para usuarios de dispositivos más antiguos o usuarios en lugares donde hay mayor latencia o ancho de banda reducido.

  • Evalúe los medios que están integrados en su aplicación. Si algo no se utiliza, elimínelo.

  • Las imágenes incrustadas pueden ser demasiado grandes. En lugar de archivos PNG, vea si puede usar imágenes SVG. Sin embargo, tenga cuidado al usar texto en imágenes SVG, porque la fuente que se use deberá instalarse en el cliente. Una excelente solución cuando necesitas mostrar texto es superponer una etiqueta de texto sobre una imagen.

  • Evalúe si la resolución es apropiada para el factor de forma. No es necesario que la resolución de una aplicación móvil sea tan alta como la resolución de una aplicación de escritorio. Experimente para conseguir el equilibrio adecuado entre calidad y tamaño de imagen.

  • Si tiene pantallas sin usar, elimínelas. Tenga cuidado de no eliminar ninguna pantalla oculta que solo utilicen los creadores o administradores de aplicaciones.

  • Evalúe si está intentando incluir demasiados flujos de trabajo en una sola aplicación. Por ejemplo, ¿tiene pantallas de administrador y pantallas de cliente en la misma aplicación? Si es así, considere dividirlas en aplicaciones individuales. Este enfoque también facilitará que varias personas trabajen en las aplicaciones al mismo tiempo y limita el "ámbito de impacto" (cantidad de prueba) cuando los cambios en la aplicación requieren un pase de prueba completo.

Optimizar ForAll

La función ForAll en Power Apps se utiliza para recorrer una tabla de registros y aplicar una fórmula o un conjunto de fórmulas a cada registro. Si bien la función en sí es versátil, el uso inadecuado de la función ForAll puede hacer que su aplicación disminuya rápidamente su eficiencia de rendimiento.

La función ForAll es una función secuencial singular en lugar de una función concurrente. Por lo tanto, analiza solo un registro a la vez, obtiene el resultado y luego continúa con el siguiente hasta haber revisado todos los registros de su alcance.

Evitar la anidación de ForAll a toda costa. Esto puede generar iteraciones exponenciales y afectar significativamente el rendimiento.

ClearCollect(FollowUpMeetingAttendees.ForAll(ForAll(Distinct(AttendeesList.EmailAddress.Address).Lookup(Attendees))))

Actualizaciones en lotes a la base de datos

ForAll + Patch puede ser un método para actualizar la base de datos por lotes. Sin embargo, tenga cuidado con el orden de uso de For All y Patch.

La función siguiente:

Patch(SampleFoodSalesData, ForAll(colSampleFoodSales,
    {
        demoName:"fromCanvas2"
    })
);

Tiene mejor rendimiento que:

ForAll(colSampleFoodSales, Patch(SampleFoodSalesData,
    {
        demoName:"test"
    })
);

Siguiente paso