Udostępnij przez


Kompilowanie dużych i złożonych aplikacji kanwy

Większość artykułów w tej części dokumentacji obejmuje wydajność aplikacji podczas działania, doświadczaną przez osoby, które z nich korzystają. W tym artykule omówiono wydajność aplikacji zgodnie z doświadczeniem osób, które je tworzą.

Gdy aplikacje stają się coraz bardziej złożone, program Power Apps Studio musi ładować większą liczbę kontrolek, formuł i źródeł danych oraz zarządzać nimi, a wszystko to z współzależnościami, które rosną wykładniczo. Czas ładowania aplikacji Power Apps Studio może być dłuższy, a funkcje takie jak IntelliSense i kodowanie kolorami mogą się opóźniać. Skorzystaj z poniższych zaleceń, aby lepiej pracować z dużymi i złożonymi aplikacjami w programie Power Apps Studio. Mogą one również pomóc w poprawie wydajności środowiska uruchomieniowego aplikacji.

Przykłady w tym artykule korzystają z przykładowego rozwiązania Hospital Emergency Response.

Użyj elementu App.Formulas zamiast App.OnStart

Napiwek

Możesz użyć funkcji With oraz niestandardowych właściwości wyjściowych komponentu kanwy jako alternatywy dla nazwanych formuł.

Najlepszym sposobem skrócenia czasu ładowania zarówno dla programu Power Apps Studio, jak i aplikacji jest zastąpienie inicjowania zmiennych i kolekcji w pliku App.OnStartnazwanymi formułami w aplikacji App.Formulas.

Przyjrzyjmy się następującego przykładowi, który używa elementu 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
    );
);

Ponieważ są to sekwencja instrukcji, aplikacja musi ocenić te wywołania Set and Collect w kolejności, zanim będzie mogła wyświetlić pierwszy ekran, co sprawia, że aplikacja jest ładowana wolniej. Ponieważ cały element App.OnStart musi być traktowany jako całość, kolejność musi zostać zachowana, a błędy zebrane przed zwróceniem końcowego wyniku, formuła jest skomplikowana podczas analizy w Power Apps Studio.

Jest lepszy sposób. Zamiast tego użyj elementu App.Formulas i zdefiniuj te zmienne i kolekcje jako nazwane formuły, jak w poniższym przykładzie.

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

Ta zmiana może wydawać się niewielka, ale może mieć ogromny wpływ. Ponieważ każda nazwana formuła jest niezależna od innych, program Power Apps Studio może analizować je niezależnie, efektywnie dzieląc duży element App.OnStart na mniejsze elementy. Widzieliśmy spadek czasu ładowania programu Power Apps Studio o aż 80% z tą zmianą.

Twoja aplikacja ładuje się również szybciej, ponieważ nie musi przetwarzać tych formuł, dopóki nie będzie potrzebny wynik. Pierwszy ekran aplikacji jest wyświetlany natychmiast.

Formuł nazwanych nie można używać we wszystkich sytuacjach, ponieważ nie można ich zmodyfikować ani używać w zestawie. Niektóre sytuacje wymagają użycia zmiennej stanu, którą można zmodyfikować. Zestaw jest idealny w tych sytuacjach i należy go nadal używać. Zazwyczaj używasz zmiennych globalnych w środowisku OnStart, aby skonfigurować wartości statyczne, które nie zmieniają się. W takich przypadkach nazwana formuła jest lepszym wyborem.

Ponieważ nazwane formuły są niezmienne, prefiks var (skrót od "zmiennej") jako konwencja nazewnictwa nie jest już odpowiednia. Nie zmieniliśmy nazw w tym przykładzie, ponieważ wymagałoby to wprowadzenia zmian w pozostałej części aplikacji do dopasowania.

Kuszące jest umieszczenie nazwanej formuły w App.OnStart, ale nie rób tego. Nie należą tam. Jako właściwość zachowania 'On', App.OnStart ocenia każdą ze swoich instrukcji w kolejności, tworząc zmienne globalne i rozmawiając z bazami danych tylko raz, gdy aplikacja jest ładowana. Nazwane formuły to formuły, które definiują sposób obliczania czegoś zawsze, gdy jest to konieczne i są zawsze prawdziwe. Ten charakter formuły umożliwia jej zachowanie niezależności i umożliwia zakończenie ładowania aplikacji przed oszacowaniem formuł.

Dzielenie długich formuł

Element App.OnStart to jeden z najgorszych elementów do użycia w długich formułach, można od niego zacząć, ale nie jest to jedyna sprawa.

Nasze badania wykazały, że prawie wszystkie aplikacje z długim czasem ładowania dla programu Power Apps Studio mają co najmniej jedną formułę zawierającą ponad 256 000 znaków. Niektóre aplikacje z najdłuższym czasem ładowania mają formuły o długości ponad 1 miliona znaków. Formuły, które długo obciążają program Power Apps Studio.

Co gorsza, skopiowanie i wklejenie kontrolki z długą formułą powoduje nieświadome duplikowanie formuły we właściwościach kontrolki. Usługa Power Apps jest modelowana po programie Excel, gdzie często występują wiele kopii formuły. Jednak w formułach programu Excel jest ograniczona do jednego wyrażenia i jest ograniczona do 8000 znaków. Formuły w usłudze Power Apps mogą się znacznie wydłużyć dzięki wprowadzeniu logiki imperatywnej i operatora łańcuchowego (; lub ;;, w zależności od ustawień regionalnych).

Ogólnym rozwiązaniem jest podzielenie długich formuł na mniejsze części i ponowne użycie części, tak jak w poprzedniej sekcji, gdy zmieniliśmy instrukcje Set/Collect w app.OnStart na nazwane formuły w app.Formulas. W innych językach programowania części wielokrotnego użytku są często określane jako podprogramy lub funkcje zdefiniowane przez użytkownika. Nazwane formuły można traktować jako prostą formę funkcji zdefiniowanej przez użytkownika bez parametrów ani skutków ubocznych.

Używanie nazwanych formuł wszędzie

We wcześniejszym przykładzie użyto nazwanych formuł jako zamiennika elementu App.OnStart. Można jednak użyć ich do zastąpienia obliczeń w dowolnym miejscu w aplikacji.

Na przykład jeden z ekranów w przykładowym rozwiązaniu Hospital Emergency Response zawiera tę logikę w 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
    }
); 

Tę formułę można podzielić na zestaw nazwanych formuł. Ułatwia to również odczytywanie formuły.

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

Wyodrębniliśmy ParamFacility jako nazwaną formułę wcześniej, gdy przenieśliśmy większość wywołań Set z App.OnStart do nazwanych formuł w App.Formulas.

Nazwane formuły są oceniane tylko wtedy, gdy ich wartości są potrzebne. Jeśli oryginalna intencja użycia funkcji Screen.OnVisible ma na celu odroczenie pracy do momentu wyświetlenia ekranu, praca jest nadal odroczona jako globalne nazwane formuły w App.Formulas.

Użyj funkcji With

Możesz również użyć funkcji With w formule, aby podzielić logikę. Utwórz rekord w pierwszym parametrze z wartościami, których chcesz użyć jako pól, a następnie użyj tych pól w drugim parametrze, aby obliczyć wartość zwracaną z kolumny With. Na przykład poprzedni przykład można napisać jako tylko jedną nazwaną formułę:

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

Jednym z minusów używania With w ten sposób jest to, że nie można użyć MyFacility i MyRegion, ponieważ są one zdefiniowane w tej samej funkcji With, co nie jest problemem w przypadku nazwanych formuł. Jednym z rozwiązań jest zagnieżdżanie funkcji With i używanie słowa kluczowego As, aby nadać nazwę każdemu rekordowi, co umożliwia łatwy dostęp do wszystkich zmiennych With.

Korzystanie ze składników kanwy

Składniki kanwy są najczęściej używane do tworzenia kontrolki interfejsu użytkownika, którą można umieścić na kanwie, podobnie jak kontrolka. Można ich również używać bez umieszczania ich w interfejsie użytkownika do wykonywania obliczeń z niestandardowymi właściwościami wyjściowymi jako alternatywą dla nazwanych formuł. Składniki Canvas są łatwe do udostępniania między aplikacjami za pomocą bibliotek komponentów i, w przeciwieństwie do nazwanych formuł, są w pełni obsługiwane. Są one jednak trudniejsze do skonfigurowania i użycia niż nazwane formuły.

Aby podzielić logikę:

  1. W programie Power Apps Studio przejdź do karty Składniki w widoku Drzewa.
  2. Utwórz nowy składnik.
  3. W okienku Właściwości włącz zakres aplikacji programu Access.
  4. Dodaj właściwość niestandardową.
  5. Ustaw typ właściwości na Dane wyjściowe i typ danych zgodnie z potrzebami.
  6. Wybierz Utwórz.
  7. W selektorze właściwości obok paska formuły w górnej części ekranu wybierz nową właściwość.
  8. Napisz algorytm logiki, aby podzielić i ponownie wykorzystać.

Aby użyć logiki:

  1. Przejdź do karty Ekrany w widoku drzewa.
  2. W okienku Wstaw rozwiń pozycję Niestandardowe i wstaw składnik.
  3. Aby obliczyć wartość z właściwością, użyj właściwości ComponentName.PropertyName.

Używanie opcji Select z ukrytą kontrolką dla logiki imperatywnej

Logika imperatywna służy do modyfikowania stanu za pomocą polecenia Ustaw i Zbierz, powiadamiania użytkownika za pomocą funkcji Notify, przechodzenia do innego ekranu lub aplikacji za pomocą funkcji Navigate and Launch oraz zapisywania wartości w bazie danych za pomocą funkcji Patch, SubmitForm lub RemoveIf.

Właściwości danych wyjściowych formuły nazwanej i niestandardowy składnik kanwy składnika kanwy nie obsługują logiki koniecznej. Typowym sposobem podziału logiki imperatywnej jest użycie właściwości OnSelect ukrytej kontrolki.

  1. Dodaj kontrolkę Przycisk do ekranu.
  2. Ustaw właściwość OnSelect na logikę imperatywnej, którą chcesz wykonać.
  3. Ustaw właściwość Visible na false, ponieważ nie ma potrzeby, aby użytkownik wyświetlał ją ani z nią wchodzić w interakcje.
  4. Wywołaj metodę Select( Button ) , gdy chcesz wykonać logikę imperatywną.

Na przykład jeden z ekranów w naszym przykładzie ma następującą właściwość OnSelect w kontrolce Przycisk . (Ten prosty przykład dotyczy tylko celów ilustracyjnych. Zwykle ta technika jest używana tylko w przypadku dłuższych formuł).

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

Aby podzielić tę logikę na części, możemy umieścić części w oddzielnych kontrolkach Przycisk i wybrać je z oryginału:

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

Ta technika działa tylko na tym samym ekranie. Inne techniki, które są nieco bardziej skomplikowane, działają na ekranach, jak na przykład użycie kontrolki Toggle, ustawienie OnCheck na logikę, którą chcesz uruchomić, i ustawienie Default na zmienną globalną, a następnie przełączanie zmiennej globalnej za pomocą Set( global, true ); Set( global, false ) w momencie, w którym chcesz uruchomić logikę.

W tym przykładzie wykonano już podział logiki. Komentarz wspomina, że "Kolejne akcje można znaleźć w sekcji OnSuccess". To zdarzenie uruchamia logikę imperatywną po udanym przesłaniu rekordu, rozwiązaniu specyficznym dla funkcji SubmitForm.

Partycjonowanie aplikacji

Niektóre aplikacje rosną do tysięcy kontrolek i setek źródeł danych, co spowalnia program Power Apps Studio. Podobnie jak w przypadku długich formuł, duże aplikacje można podzielić na mniejsze sekcje, które współpracują ze sobą w celu utworzenia jednego środowiska użytkownika.

Dzielenie aplikacji kanwy

Jednym z podejść jest zaimplementowanie sekcji w oddzielnych aplikacjach Canvas i użycie funkcji Launch do nawigacji między tymi aplikacjami oraz do przekazywania wymaganego kontekstu.

To podejście zostało zastosowane w rozwiązaniu przykładu Hospital Emergency Response. Oddzielne aplikacje zarządzają poszczególnymi głównymi obszarami ogólnej aplikacji. Aplikacje udostępniają wspólny składnik tablicy przełączania za pośrednictwem biblioteki składników wyświetlanej na ekranie uruchamiania każdej aplikacji:

Zrzut ekranu aplikacji kanwy przykładowego rozwiązania Reakcja kryzysowa szpitala działająca na telefonie z wyświetlonym składnikiem kanwy tablicy rozdzielczej.

Gdy użytkownik wybierze obszar, składnik używa metadanych dotyczących dostępnych aplikacji i aplikacji hostowania składnika. Jeśli żądany ekran znajduje się w tej aplikacji (tj. ThisItem.Screen nie jest pusty), zostanie wykonane wywołanie Navigate . Jeśli jednak żądany ekran znajduje się w innej aplikacji (czyli ThisItem.PowerAppID nie jest pusty), funkcja Launch jest używana z identyfikatorem aplikacji obiektu docelowego i kontekstem 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
    )
);

Stan w oryginalnej aplikacji zostanie utracony po uruchomieniu innej aplikacji. Pamiętaj, aby zapisać dowolny stan przed wywołaniem funkcji Launch . Zapisz go w bazie danych, wywołaj metodę SaveData lub przekaż stan do aplikacji docelowej z parametrami odczytanymi za pomocą funkcji Param .

Aplikacja oparta na modelu ze stronami niestandardowymi

Sekcje można również zaimplementować jako strony niestandardowe. Podczas nawigacji strony niestandardowe działają jako mini aplikacja kanwy z kontenerem aplikacji opartej na modelu.