Dizajniranje obrazaca za performanse u aplikacijama stvorenim prema modelu

Stvaranje iskustava u kojima se zadaci mogu brzo i učinkovito dovršiti ključno je za zadovoljstvo korisnika. Aplikacije stvorene prema modelu mogu se u velikoj mjeri prilagoditi za stvaranje iskustava koja zadovoljavaju potrebe vaših korisnika, ali važno je znati kako učinkovito kodirati, graditi i pokretati aplikacije stvorene prema modelu koje se brzo učitavaju kada korisnik otvori vašu aplikaciju i kreće se po njoj dok radi na svakodnevnim zadacima. Pokazalo se da su performanse ključni pokretač nezadovoljstva aplikacijom kada nije optimizirana za performanse.

Inteligentna prilagođavanja i efikasni obrasci važni su aspekti izgradnje visoko učinkovitih i produktivnih obrazaca. Također je važno osigurati da stvarate visoko produktivne obrasce s najboljom praksom u dizajnu i izgledu korisničkog sučelja. Informacije o dizajniranju obrazaca za učinkovitost i produktivnost potražite u odjeljku Dizajniranje produktivnih glavnih obrazaca u aplikacijama stvorenim prema modelu.

Također je važno osigurati da korisnici koriste preporučene i podržane uređaje s minimalno potrebnim specifikacijama. Dodatne informacije: Podržani web-preglednici i mobilni uređaji

Rad s podacima i karticama

Ovaj odjeljak objašnjava kako kontrole koje prikazuju podatke i kartice utječu na performanse obrasca.

Značaj zadane kartice

Zadana kartica je prva proširena kartica na obrascu. Ona igra posebnu ulogu pri učitavanju stranice obrasca. Po dizajnu, kontrole zadane kartice uvijek se generiraju pri otvaranju zapisa. Konkretno, logika inicijalizacije kontrole, poput dohvata podataka, poziva se za svaku kontrolu na kartici.

Nasuprot tome, sekundarna kartica ne izvodi ovu inicijalizaciju na svojim kontrolama kada se obrazac učita u početku. Umjesto toga, inicijalizacija kontrole događa se u trenutku otvaranja sekundarne kartice ili korisničkom interakcijom ili metodom poziva klijentskog API-ja setFocus. To pruža mogućnost da se početno učitavanje obrasca zaštiti od pretjerane obrade kontrola postavljanjem određenih kontrola na sekundarne kartice umjesto zadane kartice. Dakle, strategija postavljanja kontrole može imati značajan utjecaj na odaziv početnog učitavanja obrasca. Responzivnija zadana kartica pruža bolje cjelokupno iskustvo za izmjenu važnih polja, interakciju s naredbenom trakom i istraživanje drugih kartica i odjeljaka.

Uvijek postavite kontrole koje se najviše koriste na vrh zadane kartice. Arhitektura izgleda i informacija nije važna samo za performanse, već i za poboljšanje produktivnosti kada korisnici stupaju u interakciju s podacima na obrascu. Dodatne informacije: Dizajniranje produktivnih glavnih obrazaca u aplikacijama stvorenim prema modelu

Kontrole na temelju podataka

Kontrole koje zahtijevaju dodatne podatke izvan primarnog zapisa stvaraju najveći pritisak na odaziv obrasca i brzinu učitavanja. Ove kontrole dohvaćaju podatke putem mreže i često uključuju razdoblje čekanja (smatra se pokazateljima napretka) jer može proći neko vrijeme za prijenos podataka.

Neke od kontrola na temelju podataka uključuju:

Na zadanoj kartici zadržite samo najčešće korištene kontrole. Preostale kontrole na temelju podataka trebale bi se distribuirati na sekundarne kartice kako bi se omogućilo brzo učitavanje zadane kartice. Nadalje, ova strategija rasporeda smanjuje mogućnost dohvaćanja podataka koji na kraju ostanu nekorišteni.

Postoje i druge kontrole koje su manje utjecajne od kontrola na temelju podataka, ali i dalje mogu sudjelovati u gornjoj strategiji rasporeda kako bi se postigle najbolje performanse. Ove kontrole uključuju:

Preglednik

Ovaj odjeljak pokriva dobre prakse za korištenje s web-preglednicima.

Nemojte otvoriti nove prozore

Metoda klijentskog API-ja openForm omogućuje parametarskoj opciji prikaz obrasca u novom prozoru. Nemojte koristiti ovaj parametar niti ga postaviti na false. Postavljanje na false osigurat će da metoda openForm izvodi zadano ponašanje prikaza obrasca pomoću postojećeg prozora. Također je moguće izravno pozvati JavaScript funkciju window.open iz prilagođene skripte ili druge aplikacije; međutim, i to treba izbjegavati. Otvaranje novog prozora znači da se svi resursi stranice moraju dohvatiti i učitati ispočetka jer stranica ne može iskoristiti mogućnosti predmemoriranja podataka u memoriji između prethodno učitanog obrasca i obrasca u novom prozoru. Kao alternativu otvaranju novih prozora, razmislite o korištenju iskustva s više sesija koje omogućuje otvaranje zapisa na više kartica, a istovremeno maksimizira prednosti performansi predmemoriranja klijenta.

Upotreba modernih preglednika

Korištenje najnovijeg web-preglednika ključno je za osiguravanje što bržeg izvođenja vaše aplikacije stvorene prema modelu. Razlog tome je što se mnoga poboljšanja performansi mogu koristiti samo u novijim modernim preglednicima.

Na primjer, ako vaša tvrtka ili ustanova ima starije verzije preglednika Firefox, preglednika koji nisu na temelju Chromiuma itd., mnoga poboljšanja performansi ugrađena u aplikaciju stvorenu prema modelu neće biti dostupna u starijim verzijama preglednika jer ne podržavaju značajke o kojima aplikacija ovisi radi brzog i neometanog pokretanja.

U većini slučajeva možete očekivati poboljšanja učitavanja stranice jednostavnim prelaskom na Microsoft Edge, ažuriranjem na najnoviju trenutnu verziju preglednika sa starije verzije ili prelaskom na moderni preglednik temeljen na Chromiumu.

Prilagođavanje jezika JavaScript

Ovaj odjeljak opisuje kako izvršiti inteligentna prilagođavanja kada koristite JavaScript koji vam pomaže u izgradnji izvedbenih obrazaca i stranica u aplikaciji stvorenoj prema modelu.

Upotreba jezika JavaScript s obrascima

Mogućnost prilagođavanja obrazaca pomoću jezika JavaScript pruža profesionalnim razvojnim inženjerima veliku fleksibilnost u pogledu izgleda i ponašanja obrasca. Nepravilno korištenje ove fleksibilnosti može negativno utjecati na performanse obrasca. Razvojni inženjeri bi trebali koristiti sljedeće strategije za povećanje performansi obrasca pri implementaciji JavaScript prilagođavanja.

Upotreba asinkronih mrežnih zahtjeva prilikom zahtjeva za podacima

Zatražite podatke asinkrono, a ne sinkrono kada su za prilagođavanja potrebni dodatni podaci. Za događaje koji podržavaju čekanje na asinkroni kod poput događaja obrasca OnLoad i obrasca OnSave, rukovatelji događajima trebaju vratiti Promise kako bi platforma pričekala dok se Promise ne riješi. Platforma će prikazati odgovarajuće korisničko sučelje dok korisnik čeka da se događaj završi.

Za događaje koji ne podržavaju čekanje na asinkroni kôd, poput događaja obrasca OnChange, možete koristiti zaobilazno rješenje za zaustavljanje interakcije s obrascem dok kôd radi asinkroni zahtjev pomoću showProgressIndicator. To je bolje od korištenja sinkronih zahtjeva jer će korisnici i dalje moći komunicirati s drugim dijelovima aplikacije dok se prikazuje pokazatelj napretka.

Evo primjera korištenja asinkronog koda u sinkronim točkama dodatka.

//Only do this if an extension point does not yet support asynchronous code
try {
    await Xrm.WebApi.retrieveRecord("settings_entity", "7333e80e-9b0f-49b5-92c8-9b48d621c37c");
    //do other logic with data here
} catch (error) {
    //do other logic with error here
} finally {
    Xrm.Utility.closeProgressIndicator();
}

// Or using .then/.finally
Xrm.Utility.showProgressIndicator("Checking settings...");
Xrm.WebApi.retrieveRecord("settings_entity", "7333e80e-9b0f-49b5-92c8-9b48d621c37c")
    .then(
        (data) => {
            //do other logic with data here
        },
        (error) => {
            //do other logic with error here
        }
    )
    .finally(Xrm.Utility.closeProgressIndicator);

Trebate biti oprezni pri upotrebi asinkronog koda u rukovatelju događaja koji ne podržava čekanje asinkronog koda. To osobito vrijedi za kôd koji treba poduzeti radnju za rješavanje asinkronog koda. Asinkroni kod može uzrokovati probleme ako rukovatelj rješavanja očekuje da kontekst aplikacije ostane isti kao što je bio pri pokretanju asinkronog koda. Vaš kôd trebao bi provjeriti je li korisnik u istom kontekstu nakon svake asinkrone točke nastavka.

Na primjer, u rukovatelju događaja može postojati kôd za stvaranje mrežnog zahtjeva i promjenu kontrole koja će biti onemogućena na temelju podataka o odgovoru. Prije primanja odgovora na zahtjev, korisnik je možda stupio u interakciju s kontrolom ili prešao na drugu stranicu. Budući da se korisnik nalazi na drugoj stranici, kontekst obrasca možda neće biti dostupan, što može dovesti do pogrešaka ili može doći do drugog neželjenog ponašanja.

Asinkrona podrška u događajima obrasca OnLoad i OnSave

Događaji obrasca OnLoad i OnSave podržavaju rukovatelje koji vraćaju obećanja. Događaji će čekati na sva obećanja koja je rukovatelj vratio za rješavanje, sve dok ne istekne vrijeme. Ta se podrška može omogućiti u postavkama aplikacije.

Dodatne informacije:

Ograničavanje količine podataka zatraženih tijekom učitavanja obrasca

Zatražite samo minimalnu količinu podataka koja je potrebna za izvođenje poslovne logike na obrascu. Predmemorirajte podatke koji se traže što je više moguće, osobito podatke koji se ne mijenjaju često ili ne moraju biti svježi. Na primjer, zamislite da postoji obrazac koji traži podatke tablice postavke. Na temelju podataka u tablici postavki, obrazac može odabrati sakriti dio obrasca. U tom slučaju JavaScript može predmemorirati podatke u sessionStorage tako da se podaci traže samo jednom po sesiji (onLoad1). Strategija neaktivno-do-ponovne provjere također se može koristiti tamo gdje JavaScript koristi podatke iz sessionStorage dok tražite podatke za sljedeći prelazak na obrazac (onLoad2). Konačno, strategija uklanjanja duplikata mogla bi se koristiti u slučaju da se rukovatelj pozove više puta zaredom (onLoad3).

const SETTING_ENTITY_NAME = "settings_entity";
const SETTING_FIELD_NAME = "settingField1";
const SETTING_VALUE_SESSION_STORAGE_KEY = `${SETTING_ENTITY_NAME}_${SETTING_FIELD_NAME}`;

// Retrieve setting value once per session
async function onLoad1(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Ensure there is a stored setting value to use
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestSettingValue();
    }

    // Do logic with setting value here
}

// Retrieve setting value with stale-while-revalidate strategy
async function onLoad2(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Revalidate, but only await if session storage value is not present
    const requestPromise = requestSettingValue();

    // Ensure there is a stored setting value to use the first time in a session
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestPromise;
    }
    
    // Do logic with setting value here
}

// Retrieve setting value with stale-while-revalidate and deduplication strategy
let requestPromise;
async function onLoad3(executionContext) {
    let settingValue = sessionStorage.getItem(SETTING_VALUE_SESSION_STORAGE_KEY);

    // Request setting value again but don't wait on it
    // In case this handler fires twice, don’t make the same request again if it is already in flight
    // Additional logic can be added so that this is done less than once per page
    if (!requestPromise) {
        requestPromise = requestSettingValue().finally(() => {
            requestPromise = undefined;
        });
    }

    // Ensure there is a stored setting value to use the first time in a session
    if (settingValue === null || settingValue === undefined) {
        settingValue = await requestPromise;
    }
    
    // Do logic with setting value here
}

async function requestSettingValue() {
    try {
        const data = await Xrm.WebApi.retrieveRecord(
            SETTING_ENTITY_NAME,
            "7333e80e-9b0f-49b5-92c8-9b48d621c37c",
            `?$select=${SETTING_FIELD_NAME}`);
        try {
            sessionStorage.setItem(SETTING_VALUE_SESSION_STORAGE_KEY, data[SETTING_FIELD_NAME]);
        } catch (error) {
            // Handle sessionStorage error
        } finally {
            return data[SETTING_FIELD_NAME];
        }
    } catch (error) {
        // Handle retrieveRecord error   
    }
}

Radije koristite podatke dostupne u klijentskom API-ju umjesto stvaranja zahtjeva. Na primjer, umjesto da tražite korisničke sigurnosne uloge pri učitavanju obrasca, možete koristiti getGlobalContext.userSettings.roles.

Učitavanje koda samo kad je potrebno

Učitajte onoliko koda koliko je potrebno za događaje za određeni obrazac. Ako imate kôd koji je samo za obrazac A i obrazac B, ne bi trebao biti uključen u biblioteku koja je učitana za obrazac C. Trebao bi biti u vlastitoj biblioteci.

Izbjegavajte učitavanje biblioteka u događaj OnLoad ako se koriste samo za događaje OnChange ili OnSave. Umjesto toga, učitajte ih u te događaje. Na taj način platforma može odgoditi njihovo učitavanje sve dok se obrazac ne učita. Dodatne informacije: Optimizacija performansi obrasca

Uklanajnje upotrebe konzole API-ja u kodu proizvodnje

U kodu proizvodnje nemojte upotrebljavati metode konzole API-ja kao što je console.log. Zapisivanje podataka u konzolu može značajno povećati zahtjeve za memorijom i može spriječiti čišćenje podataka u memoriji. To može dovesti do toga da se aplikacija s vremenom usporava i na kraju ruši.

Izbjegavanje curenja memorije

Curenja memorije u kodu može dovesti do sporije izvedbe tijekom vremena i na kraju do rušenja aplikacije. Do curenja memorije dolazi kada aplikacija ne uspije osloboditi memoriju kada ona više nije potrebna. Uz sve prilagodbe i komponente koda u obrascu trebali biste poduzeti sljedeće:

  • Temeljito uzeti u obzir i testirati scenarije za sve što je zaduženo za čišćenje memorije, kao što su klase odgovorne za upravljanje životnim ciklusom objekata.
  • Očistiti sve slušatelje događaja i pretplate, osobito u objektu window.
  • Očistite sve mjerače vremena, kao što je setInterval.
  • Izbjegavajte, ograničite i očistite reference na globalne ili statičke objekte.

Za prilagođene komponente čišćenje se može obaviti u metodi uništi.

Za više informacija o rješavanju problema s memorijom provjerite ovu dokumentaciju za razvojne programere za Edge.

Alati koje možete upotrijebiti za poboljšanje performansi aplikacija

Ovaj odjeljak opisuje alate koji vam mogu pomoći u razumijevanju problema s performansama i nudi preporuke o tome kako optimizirati prilagođavanja u aplikacijama stvorenim prema modelu.

Uvidi u performanse

Uvidi u performanse su samoposlužni alat za autore aplikacija za velike tvrtke koji analizira telemetrijske podatke tijekom izvođenja i pruža prioritetizirani popis preporuka kako bi se poboljšale performanse aplikacija stvorenih prema modelu. Ova značajka pruža dnevni skup analitičkih uvida povezanih s performansama aplikacija stvorenih prema modelu ili angažmanu klijenta Power Apps kao što su Dynamics 365 Sales ili Dynamics 365 Service, s preporukama i aktivnim stavkama. Autori aplikacija za velike tvrtke mogu vidjeti detaljne uvide u performanse na razini aplikacije u servisu Power Apps. Dodatne informacije: Što su uvidi u performanse? (pretpregled)

Provjera rješenja

Alat za provjeru rješenja je moćan alat koji može analizirati prilagođavanja klijenta i poslužitelja radi nalaženja problema s performansama ili pouzdanošću. Može analizirati JavaScript na strani klijenta, XML obrasca i .NET dodatke na strani poslužitelja i dati ciljane uvide u ono što može usporiti krajnje korisnike. Preporučujemo da pokrenete alat za provjeru rješenja svaki put kada objavite promjene u razvojnom okruženju, tako da se prikažu svi problemi u vezi s performansama prije nego dođu do krajnjih korisnika. Dodatne informacije: Provjera aplikacija usmjerenih modelu s pomoću alata za provjeru rješenja na platformi Power Apps

Neki primjeri problema povezanih s performansama pronađenih pomoću alata za provjeru rješenja:

Provjera objekata

Provjeritelj objekata izvodi dijagnostiku u stvarnom vremenu na komponentnim objektima unutar vašeg rješenja. Ako se otkriju problemi, vraća se preporuka koja opisuje kako riješiti problem. Dodatne informacije: Upotreba alata za provjeru objekata za dijagnosticiranje komponente rješenja (pretpregled)

Sljedeći koraci

Dizajniranje produktivnih glavnih obrazaca u aplikacijama stvorenima prema modelu