Udostępnij za pośrednictwem


Optymalizacja kodu

W miarę ewolucji aplikacji opartych na kanwie w celu dostosowania się do różnych potrzeb biznesowych kluczowe znaczenie ma utrzymanie optymalnej wydajności. Obsługa danych, projektowanie interfejsu użytkownika i funkcjonalność aplikacji wymagają starannego podejścia do optymalizacji kodu.

Gdy aplikacje kanwy stają się bardziej złożone, możesz napotkać problemy z pobieraniem danych, złożonością formuły i szybkością renderowania. Aby zrównoważyć silną funkcjonalność za pomocą dynamicznego interfejsu użytkownika, użyj systematycznego podejścia do optymalizacji kodu.

Optymalizacja formuł Power Fx

Ta sekcja zawiera najlepsze rozwiązania dotyczące optymalizowania formuł Power Fx.

Funkcja With

Funkcja With ocenia formułę dla pojedynczego rekordu. Formuła może obliczać wartość i/lub wykonywać akcje, takie jak modyfikowanie danych lub współdziałanie z połączeniem. Użyj With, aby poprawić czytelność złożonych formuł, dzieląc je na mniejsze nazwane podformuły. Te nazwane wartości działają tak samo, jak proste zmienne lokalne, które są ograniczone do With. With jest lepsza niż kontekst lub zmienne globalne, ponieważ jest samodzielna, łatwa do zrozumienia i działa w dowolnym kontekście formuł deklaratywnych. Dowiedz się więcej o funkcji With.

Zrzut ekranu przedstawiający formułę Power Fx używającą funkcji With.

Funkcja równoległa

Funkcja Concurrent umożliwia jednoczesną ewaluację wielu formuł w tej samej właściwości, jeśli mają łącznik lub wywołania Dataverse. Zwykle wiele formuł jest obliczanych w tym samym czasie, gdy są one połączone z operatorem ; (średnik). Dzięki Concurrent temu aplikacja ocenia wszystkie formuły we właściwości w tym samym czasie, nawet po użyciu operatora ;. Ta współbieżność oznacza, że użytkownicy oczekują mniej czasu na wyniki. Jeśli kolejne wywołania danych nie są uruchamiane przed zakończeniem poprzednich, aplikacja musi czekać przez czas będący sumą czasów wszystkich żądań. Jeśli wywołania danych są uruchamiane jednocześnie, czas oczekiwania aplikacji zostanie skrócony do najdłużej wykonywanego żądania. Dowiedz się więcej o funkcji Concurrent.

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

Funkcja Coalesce

Funkcja Coalesce ocenia kolejno swoje argumenty i zwraca pierwszą wartość, która nie jest pusta lub pusty ciąg. Tej funkcji należy użyć do zastąpienia pustej wartości lub pustego ciągu innym ciągiem, ale pozostawienia niepustych i wypełnionych wartości ciągów bez zmian. Jeśli wszystkie argumenty są puste lub zawierają puste ciągi znaków, funkcja zwraca wartość pustą. Coalesce to dobry sposób konwertowania pustych ciągów na puste wartości. Dowiedz się więcej o funkcji Coalesce.

W tym przykładzie wymagane jest dwukrotne ocenienie value1 i value2.

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

Funkcję tę można sprowadzić do:

Coalesce(value1, value2)

Funkcja IsMatch

Funkcja IsMatch sprawdza, czy ciąg tekstowy jest zgodny ze wzorcem, który może zawierać znaki zwykłe, wstępnie zdefiniowane wzorce lub wyrażenie regularne. Dowiedz się więcej o funkcji IsMatch.

Na przykład ta formuła pasuje do numeru ubezpieczenia społecznego Stanów Zjednoczonych.

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

Wyjaśnienie wyrażenia regularnego:

  • \\d dopasowuje dowolną cyfrę (0-9).

  • {3} Określa, że poprzedzający wzorzec cyfr (\d) powinien wystąpić dokładnie trzy razy.

  • - dopasowuje znak myślnika.

  • {2} Określa, że poprzedzający wzorzec cyfr (\d) powinien wystąpić dokładnie 2 razy.

  • {4} Określa, że poprzedzający wzorzec cyfr (\d) powinien wystąpić dokładnie 4 razy.

Więcej przykładów IsMatch:

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

Optymalizacja aplikacji OnStart

Właściwość OnStart w aplikacjach canvas odgrywa kluczową rolę w definiowaniu działań podejmowanych podczas uruchamiania aplikacji. Ta właściwość pozwala twórcom aplikacji na wykonywanie globalnych zadań inicjalizacyjnych, konfigurowanie zmiennych i wykonywanie działań, które powinny być wykonywane tylko raz podczas procesu uruchamiania aplikacji. Zrozumienie i efektywne używanie właściwości OnStart do tworzenia dynamicznych i wydajnych aplikacji kanwy.

Usprawnij App.OnStart funkcję, migrując konfiguracje zmiennych do nazwanych formuł. Formuły nazwane, zwłaszcza te skonfigurowane na wczesnym etapie cyklu życia aplikacji, są korzystne. Formuły te obsługują inicjalizację zmiennych na podstawie wywołań danych, zapewniając czystszą i bardziej zorganizowaną strukturę kodu. Dowiedz się więcej w Tworzenie dużych i skomplikowanych aplikacji canvas.

Notatka

Właściwość OnStart jest konieczna. Jest to uporządkowana lista prac, które należy wykonać przed wyświetleniem pierwszego ekranu. Ponieważ precyzyjnie określa nie tylko co należy wykonać, ale także kiedy ta praca musi być wykonana zgodnie z kolejnością, ogranicza to możliwość optymalizacji poprzez zmiany kolejności i odroczenie, które w innych okolicznościach można by zastosować.

Ekran startowy

Jeśli App.OnStart zawiera wywołanie funkcji Navigate, nawet jeśli jest to rzadko wywoływana funkcja If, aplikacja musi ukończyć wykonywanie App.OnStart przed wyświetleniem pierwszego ekranu aplikacji.  App.StartScreen to deklaratywny sposób wskazywania, który ekran powinien być wyświetlany jako pierwszy i nie blokuje optymalizacji.

Ustawienie właściwości StartScreen pokazuje pierwszy ekran przed zakończeniem App.OnStart. App.StartScreen deklaruje, który obiekt ekranu ma być wyświetlany jako pierwszy bez konieczności wstępnego przetwarzania.

Zamiast pisać kod typu:

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

Zmień kod na:

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

Więcej informacji: App.StartScreen: deklaratywna alternatywa dla nawigacji w aplikacji App.OnStart.

Ostrzeżenie

Unikaj zależności pomiędzy StartScreen i OnStart. Odwoływanie się do nazwanej formuły, która z kolei odwołuje się do zmiennej globalnej, może spowodować stan współzawodnictwa, w którym StartScreen nie jest prawidłowo stosowany.

Nie twórz zależności między elementami StartScreen i OnStart. Podczas gdy aplikacja blokuje odwoływanie się do zmiennych globalnych w programie StartScreen, można odwołać się do nazwanej formuły, która z kolei odwołuje się do zmiennej globalnej. Takie podejście może spowodować warunek współzawodnictwa, w którym być może StartScreen nie zostanie zastosowany poprawnie.

Nazwane formuły

Nazwane formuły są statyczne lub stałe, które można zdefiniować w pliku App.Formulas. Po zadeklarowaniu w App.Formulas, można ich używać w dowolnym miejscu w aplikacji, a ich wartości są zawsze aktualne. Nazwane formuły w Power Apps umożliwiają definiowanie wartości lub zestawów wartości, którymi platforma automatycznie zarządza i aktualizuje. Ta funkcja zmienia odpowiedzialność za obliczanie wartości i utrzymanie od dewelopera do Power Apps, usprawniając proces programowania. Nazwane formuły w Power Apps to zaawansowana funkcja, która może znacznie zwiększyć wydajność aplikacji i łatwość konserwacji.

Nazwane formuły pomagają również podczas deklarowania motywów aplikacji. Podczas tworzenia aplikacji dla przedsiębiorstw często chcesz, aby aplikacja miała typowe motywy, które zapewniają spójny wygląd i środowisko użytkownika. Aby utworzyć motyw, należy zadeklarować dziesiątki do setek zmiennych w pliku App.OnStart. Ta deklaracja zwiększa długość kodu i czas inicjowania aplikacji.

Nowoczesne elementy sterujące mogą również znacznie pomóc w tworzeniu motywów i zredukować logikę tworzoną przez użytkowników do obsługi motywów. Nowoczesne sterowanie jest obecnie w wersji zapoznawczej.

Na przykład można przenieść następujący kod z App.OnStart do App.Formulas, co skraca czas uruchamiania związany z deklaracjami zmiennych globalnych.

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

Kod można przenieść do App.Formulas w następujący sposób:

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";

Innym przykładem jest ustawienie Lookups. W tym miejscu wymagana jest zmiana w formule Lookup, aby uzyskać informacje o użytkowniku z Office 365 zamiast usługi Dataverse. Wystarczy wprowadzić zmianę w jednym miejscu bez zmiany kodu wszędzie.

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

Formuły te ucieleśniają istotę obliczeń. Opisują one proces określania UserEmail, UserInfo, UserTitle i UserPhone na podstawie innych wartości. Ta logika jest hermetyzowana, umożliwiając szerokie wykorzystanie w całej aplikacji i może być modyfikowana w jednym miejscu. Możliwość adaptacji jest rozszerzana na przełączanie z tabeli Dataverse Users do łącznika Office 365 bez konieczności wprowadzania zmian w formułach rozproszonych w całej aplikacji.

Innym podejściem jest optymalizacja countRows.

varListItems = CountRows(SampleList)

Za pomocą Set funkcji należy zainicjować zmienną varListItems z początkową liczbą wierszy na przykładowej liście i ustawić ją ponownie po dodaniu lub usunięciu elementów listy. W przypadku nazwanych formuł wraz ze zmianą danych zmienna varListItems jest aktualizowana automatycznie.

Nazwane formuły w właściwości App.Formulas zapewniają bardziej elastyczne i deklaratywne podejście do zarządzania wartościami i obliczeniami w całej aplikacji. Oferują one zalety w zakresie niezależności czasu, automatycznych aktualizacji, łatwości konserwacji i niezmiennych definicji w porównaniu do właściwości App.OnStart.

Aspekt Nazwane formuły (App.Formulas) App.OnStart
Niezależność od czasu Formuły są dostępne natychmiast i można je obliczyć w dowolnej kolejności. Zmienne mogą wprowadzać zależności czasowe, które wpływają na dostępność.
Aktualizacje automatyczne Formuły są automatycznie aktualizowane, gdy zmieniają się zależności. Zmienne są ustawiane raz podczas uruchamiania; mogą być potrzebne aktualizacje ręczne.
Możliwość konserwacji Scentralizowane formuły w jednej lokalizacji poprawiają łatwość konserwacji. Zmienne rozproszone mogą wymagać znajdowania i aktualizowania w wielu miejscach.
Definicje niezmienne Definicje formuł w programie App.Formulas są niezmienne. Wartości zmiennych mogą być podatne na przypadkowe zmiany.

Funkcje zdefiniowane przez użytkownika

Funkcje zdefiniowane przez użytkownika w programie Power Apps Studio umożliwiają tworzenie funkcji użytkownika.

Zdefiniuj formułę w App.Formulas w następujący sposób:

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

Kod działa w następujący sposób:

  • FunctionName wywołuje funkcję .

  • Parameter jest nazwą wejścia. Można uwzględnić co najmniej jedno wejście.

  • DataType to typ danych, z którym argument przekazany do funkcji musi być zgodny. Dostępne typy danych obejmują Boolean, kolor, datę, datę/godzinę, typ dynamiczny, identyfikator GUID, hiperłącze, tekst i czas.

  • OutputDataType to typ danych wyjściowych funkcji.

  • Formula to dane wyjściowe funkcji.

Użyj IfError polecenia, aby zaimplementować obsługę błędów w zdefiniowanej funkcji:

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

Wywołaj zdefiniowaną funkcję z kontrolki tekstu lub etykiety.

calcAreaOfCircle(Int(*TextInput1*.Text))

Optymalizacja zmiennych

Zmienne definiują i ustawiają wartości lokalne i globalne, których używasz w całej aplikacji. Chociaż są one wygodne, używanie zbyt wielu zmiennych może sprawić, że aplikacja będzie mniej wydajna.

W poniższym przykładzie pokazano, jak ustawić zmienną dla każdego atrybutu obiektu, co wymaga użycia Set dla każdej właściwości.

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

Bardziej efektywnym podejściem jest korzystanie z właściwości tylko wtedy, gdy jest potrzebna:

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

Mądrze używaj zmiennych kontekstowych i globalnych. Jeśli zakres zmiennej wykracza poza pojedynczy ekran, należy użyć zmiennych globalnych zamiast zmiennych kontekstowych.

Zbyt wiele nieużywanych zmiennych zwiększa zużycie pamięci i może spowolnić inicjalizację aplikacji. Zasoby są przydzielane dla tych zmiennych, nawet jeśli ich nie używasz. Nieużywane zmienne również zwiększają złożoność logiki aplikacji. Zachowaj czystą i zorganizowaną aplikację Power App, aby uzyskać lepszą wydajność i łatwiejsze programowanie.

Optymalizowanie kolekcji

Kolekcje to tymczasowe struktury przechowywania danych, które używasz do przechowywania danych i manipulowania nimi w aplikacji Power Apps. Jednak kolekcje mogą powodować obciążenie wydajności systemu. Ogranicz korzystanie z kolekcji i korzystaj z nich tylko wtedy, gdy jest to konieczne.

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

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

Aby zliczać rekordy w kolekcji lokalnej, użyj CountIf zamiast Count(Filter()).

Rozważ to podejście podczas pracy z kolekcjami:

  • Ograniczenie rozmiaru i liczby kolekcji. Ponieważ kolekcje są lokalne dla aplikacji, są przechowywane w pamięci urządzenia mobilnego. Im więcej kolekcji danych przechowuje lub im więcej kolekcji używasz, tym gorsza wydajność. Użyj funkcji ShowColumns, aby uzyskać tylko określone kolumny. Dodaj funkcję Filter, aby uzyskać tylko istotne dane.

    Poniższa przykładowa funkcja zwraca cały zestaw danych:

    ClearCollect(colDemoAccount, Accounts);
    

    Porównaj tę funkcję z następującym kodem, który zwraca tylko określone rekordy i kolumny:

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

    W tym przykładzie zwracany jest następujący zestaw danych:

    Zrzut ekranu przedstawiający zestaw danych z tabelą o nazwie colAcc i dwie kolumny, address1_city i nazwa.

  • Ustawienie częstotliwości odświeżania źródła danych. Jeśli dodasz nowe rekordy do kolekcji, odśwież ją lub zbierz nowe rekordy do niej, aby uzyskać nowe lub zmienione rekordy. Jeśli źródło danych jest aktualizowane przez wielu użytkowników, odśwież kolekcję, aby pobrać nowe lub zmienione rekordy. Więcej wywołań odświeżania oznacza więcej interakcji z serwerem.

Buforowanie danych w kolekcjach i zmiennych

Kolekcja to zmienna tabeli, w której są przechowywane wiersze i kolumny danych, a nie tylko pojedynczy element danych. Kolekcje są przydatne z dwóch głównych powodów: agregowania danych przed wysłaniem ich do źródła danych oraz buforowania informacji w celu uniknięcia częstych zapytań. Ponieważ kolekcje pasują do struktury tabelarycznej źródła danych i Power Apps, umożliwiają wydajną interakcję z danymi nawet wtedy, gdy jesteś w trybie offline.

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

Usuwanie nieużywanych zmiennych i mediów

Chociaż nieużywane nośniki i zmienne mogą nie mieć znaczącego wpływu na wydajność aplikacji, ważne jest, aby wyczyścić aplikację, usuwając wszelkie nieużywane nośniki lub zmienne.

  • Nieużywane pliki multimedialne zwiększają rozmiar aplikacji, co może spowolnić czas ładowania aplikacji.

  • Nieużywane zmienne zwiększają zużycie pamięci i mogą nieco spowolnić inicjalizację aplikacji. Zasoby są przydzielane dla tych zmiennych, nawet jeśli nie są używane. Zbyt wiele nieużywanych zmiennych może również sprawić, że logika aplikacji będzie bardziej złożona.

  • Użyj App Checker, aby sprawdzić nieużywane nośniki i zmienne.

Optymalizacja ekranów i elementów sterujących

Aby zoptymalizować ekrany i kontrolki w Power Apps, należy wziąć pod uwagę następujące najlepsze rozwiązania.

Unikaj krzyżowych odniesień do elementów sterujących

Elementy sterujące, które odwołują się do elementów sterujących na innych ekranach, mogą spowolnić ładowanie aplikacji i nawigację. Takie podejście może wymusić załadowanie innych ekranów przez aplikację zamiast czekać, aż użytkownik przejdzie do tego ekranu. Aby rozwiązać ten problem, użyj zmiennych, kolekcji i kontekstu nawigacji, aby udostępnić stan między ekranami.

Sprawdzanie aplikacji w Power Apps Studio pokazuje kontrolki, do których istnieją odsyłacze. Regularnie sprawdzaj Kontroler aplikacji, aby rozwiązać ten problem.

Na poniższej ilustracji kontrolka Galeria 1 odwołuje się krzyżowo do kontrolki Etykieta 2 na ekranie 2.

 Zrzut ekranu Power Apps Studio przedstawiający kontrolkę o odnośnikach krzyżowych.

Jeśli odwołujesz się do kontrolki z pierwszego ekranu aplikacji na drugim ekranie, nie ma spadku wydajności, ponieważ pierwszy ekran jest już załadowany. To zachowanie jest rzeczywiście korzystne, ponieważ aplikacja jest deklaratywna zamiast używać zmiennych.

Jeśli odwołujesz się do kontrolek, które nie zostały jeszcze załadowane, takie jak pierwszy ekran odwołujący się do kontrolki z ekranu 3 Label 3, aplikacja ładuje ten ekran do pamięci.

Włącz DelayOutput dla kontrolek tekstowych

Ustawienie DelayOutput po ustawieniu wartości true rejestruje dane wejściowe użytkownika po pół sekundowym opóźnieniu. To opóźnienie jest przydatne w przypadku opóźniania kosztownych operacji do momentu zakończenia wprowadzania tekstu przez użytkownika, takiego jak filtrowanie, gdy dane wejściowe są używane w innych formułach.

Rozważmy na przykład galerię, której elementy są filtrowane w zależności od tego, co użytkownik wprowadza w kontrolce TextInput:

  • Jeśli ustawisz wartość DelayOutput na false, co jest wartością domyślną, galeria filtruje natychmiast po wpiseniu dowolnego tekstu. Jeśli masz galerię z wieloma elementami, ponowne ładowanie galerii z zmianami od razu spowalnia wydajność. Lepiej poczekać. To zachowanie jest praktyczne, gdy używasz TextInput jako ciągu wyszukiwania lub funkcji StartsWith.

  • Jeśli ustawisz wartość DelayOutput na true, nastąpi krótkie opóźnienie przed wykryciem zmian. To opóźnienie zapewnia czas na zakończenie wpisywania. Opóźnienie działa dobrze z właściwością TextInput.OnChange. Jeśli masz akcje powiązane ze zmianami, nie chcesz ich wyzwalać, dopóki nie zakończysz wpisywania w polu.

Delegowanie i przetwarzanie po stronie serwera

Użycie delegowania i przetwarzania po stronie serwera umożliwia aplikacji wydajną obsługę dużych zestawów danych przez odciążanie operacji do źródła danych.

Delegowanie

Delegowanie w Power Apps odnosi się do zdolności aplikacji do przekazywania pewnych operacji do bazowego źródła danych, zamiast przetwarzać je bezpośrednio w Power Apps. Korzystając z delegowania w Power Apps, można tworzyć bardziej wydajne i skalowalne aplikacje, które działają dobrze nawet w scenariuszach obejmujących duże zestawy danych. Należy pamiętać o ograniczeniach delegowania dla określonych źródeł danych i operacji oraz odpowiednio zaprojektować aplikację, aby osiągnąć optymalną wydajność.

Notatka

Nie wszystkie funkcje są delegowalne. Dowiedz się więcej o delegowaniu w temacie Ograniczenia zapytań: Delegowanie i limity zapytań.

Delegowanie ma kilka zalet, takich jak optymalizacja zapytań i obsługa dużych zestawów danych. Ponadto, jeśli dane źródłowe często się zmieniają, delegowanie pomaga zachować aktualność danych.

Redukcja wywołań API do źródła danych

Czasami tworzenie kolekcji przez wykonywanie sprzężeń w aplikacjach kanwy może wydawać się wygodne. Rozważmy poniższy przykład. W tym przykładzie istnieją dwie tabele: Kierowcy i Ciężarówki. Kod tworzy kolekcję kierowców i szczegółów ciężarówek, a dla każdej ciężarówki wywołuje kierowcę, który posiada ciężarówkę.

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

Wykonanie takiego sprzężenia w aplikacji kanwy może wygenerować wiele wywołań źródła danych, co prowadzi do powolnego ładowania czasów.

Lepszym podejściem jest:

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

W scenariuszu czasu rzeczywistego można skrócić czas ładowania z pięciu minut do poniżej 10 sekund, naprawiając dane w źródle.

Przetwarzanie po stronie serwera

Różne źródła danych, takie jak SQL i Dataverse, umożliwiają delegowanie przetwarzania danych, takiego jak filtry i wyszukiwania, do źródła danych. W SQL Server można tworzyć widoki zdefiniowane przez zapytanie. W Dataverse mozesz tworzyć niskokodowe wtyczki do przetwarzania danych na serwerze i zwracania tylko końcowych wyników do swojej aplikacji kanwy.

Delegowanie przetwarzania danych do serwera może poprawić wydajność, zmniejszyć ilość kodu po stronie klienta i ułatwić konserwację aplikacji.

Dowiedz się więcej o wtyczkach w Dataverse.

Optymalizacja wzorców danych zapytań

Optymalizowanie sposobu, w jaki aplikacja wykonuje zapytania dotyczące danych, może znacznie skrócić czas ładowania i poprawić ogólny czas odpowiedzi.

Użyj jawnego wyboru kolumn

Funkcja jawnego wyboru kolumn (ECS) jest domyślnie włączona dla wszystkich nowych aplikacji. Jeśli dana funkcja nie jest włączona w aplikacji, włącz ją. ECS automatycznie zmniejsza liczbę pobieranych kolumn tylko do tych, które są używane w aplikacji. Jeśli usługa ECS nie jest włączona, możesz uzyskać więcej danych niż potrzebujesz, co może mieć wpływ na wydajność. Czasami, gdy aplikacja pobiera dane za pośrednictwem kolekcji, oryginalne źródło kolumny może zostać utracone. Usługa ECS usuwa kolumny, jeśli nie może określić, czy są używane. Aby wymusić utrzymanie brakującej kolumny przez ECS, użyj wyrażenia Power Fx ShowColumns po odwołaniu do kolekcji lub w kontrolce.

Unikaj wywoływania Power Automate w celu wypełnienia kolekcji

Typowym rozwiązaniem jest użycie Power Automate do pobierania i wypełniania kolekcji w Power Apps. Choć podejście to jest godne weryfikacji, istnieją sytuacje, w których może ono nie być najskuteczniejszym wyborem. Wywołanie usługi Power Automate dodaje opóźnienie sieci oraz obciążenie wydajnościowe rzędu 0,6 sekundy, aby zainicjować przepływ Power Automate.

Nadużywanie przepływów Power Automate może również prowadzić do ograniczeń wykonywania i dławienia. Zawsze oceniaj kompromisy między opóźnieniami sieci a kosztami wydajności.

Wyeliminowanie problemu N+1

Problem N+1 jest częstym problemem w zapytaniach do baz danych, w których zamiast pobierać wszystkie wymagane dane w jednym zapytaniu, wykonywanych jest wiele dodatkowych zapytań w celu pobrania powiązanych danych. Ten problem może prowadzić do problemów z wydajnością, ponieważ każde dodatkowe zapytanie wiąże się z obciążeniem.

Proste wywołanie podobne do tego w celu załadowania kolekcji może generować wywołania N+1 do źródła danych:

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

W kontekście aplikacji kanwy i galerii może wystąpić problem N+1 podczas pracy ze źródłami danych i galeriami, które wyświetlają powiązane rekordy. Problem pojawia się zazwyczaj, gdy wykonywanych jest więcej zapytań dla każdego produktu wyświetlanego w galerii, co prowadzi do wąskiego gardła wydajności.

Użyj opcji Wyświetl obiekty w SQL Server, aby uniknąć problemu z zapytaniami N+1 lub zmień interfejs użytkownika, aby uniknąć wyzwalania scenariusza N+1.

Dataverse automatycznie pobiera wymagane dane z powiązanych tabel i można wybrać kolumny z powiązanych tabel.

ThisItem.Account.'Account Name'

Jeśli RelatedDataSource rozmiar jest mały (mniej niż 500 rekordów), buforuj go w kolekcji i użyj kolekcji do obsługi scenariusza zapytania Lookup (N+1).

Ograniczanie rozmiaru pakietu

Mimo że Power Apps optymalizuje ładowanie aplikacji, możesz wykonać kroki w celu zmniejszenia zużycia aplikacji. Zmniejszony rozmiar jest szczególnie ważny dla użytkowników starszych urządzeń lub użytkowników w regionach, w których występuje większe opóźnienie lub zmniejszona przepustowość.

  • Oceń media osadzone w twojej aplikacji. Jeśli coś nie jest używane, usuń to.

    Na przykład obrazy osadzone mogą być zbyt duże. Zamiast plików PNG zobacz, czy możesz użyć obrazów SVG. Należy zachować ostrożność przy użyciu tekstu na obrazach SVG, ponieważ czcionka musi być zainstalowana na kliencie. Sposobem obejścia, gdy trzeba pokazać tekst, jest nałożenie etykiety tekstowej na obraz.

  • Oceń, czy rozdzielczość jest odpowiednia dla danego formatu. Rozdzielczość aplikacji mobilnej nie musi być tak wysoka, jak rozdzielczość aplikacji desktopowej. Eksperymentuj, aby uzyskać odpowiednią równowagę między jakością i rozmiarem obrazu.

  • Jeśli masz nieużywane ekrany, usuń je. Uważaj, aby nie usunąć żadnych ukrytych ekranów, z których korzystają tylko twórcy aplikacji lub administratorzy.

  • Oceń, czy nie próbujesz zmieścić zbyt wielu procesów w jednej aplikacji. Na przykład, czy w tej samej aplikacji znajdują się zarówno ekrany administratora, jak i klienta? Jeśli tak, warto rozważyć podzielenie ich na osobne aplikacje. Takie podejście ułatwia również wielu osobom pracę nad aplikacjami jednocześnie i ogranicza "zakres wpływu" (ilość testów), gdy zmiany aplikacji wymagają pełnego testu.

Optymalizuj ForAll

Funkcja ForAll w Power Apps służy do iterowania przez tabelę rekordów i stosowania formuł lub zestawu formuł do każdego rekordu. Chociaż sama funkcja jest wszechstronna, niewłaściwe użycie ForAll funkcji może szybko sprawić, że aplikacja będzie mniej wydajna.

Funkcja ForAll jest pojedynczą funkcją sekwencyjną zamiast funkcji współbieżnej. W związku z tym analizuje tylko jeden rekord w danym momencie, pobiera wynik, a następnie przechodzi do następnego rekordu, dopóki nie przejdzie przez wszystkie rekordy w swoim zakresie.

Unikaj zagnieżdżania ForAll. Ta praktyka może prowadzić do wykładniczej liczby iteracji i znacząco wpływać na wydajność.

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

Aktualizowanie bazy danych w usłudze Batch

Możesz użyć ForAll i Patch do wsadowego zaktualizowania bazy danych. Należy jednak zachować ostrożność w przypadku użycia kolejności ForAll i Patch.

Poniższa funkcja jest lepszym podejściem, na przykład:

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

Następujące podejście jest mniej wydajne:

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

Następny krok