Dizajniranje obrazaca za performanse u aplikacijama zasnovanim na modelu

Iskustva izrade u kojima se zadaci mogu obaviti brzo i efikasno ključna je za zadovoljstvo korisnika. Aplikacije zasnovane na modelu mogu biti visoko prilagođene za kreiranje iskustava koja zadovoljavaju potrebe vaših korisnika, ali važno je znati kako efikasno kodirati, praviti i pokretati aplikacije zasnovane na modelu koje se brzo učitavaju kada korisnik otvori aplikaciju i kreće kroz nju dok radi na svakodnevnim zadacima. Pokazalo se da su performanse ključni pokretač nezadovoljstva aplikacije kada nije optimizovana za performanse.

Inteligentna prilagođavanja i performanse su važni aspekti izgradnje visoko efikasnih i produktivnih obrazaca. Takođe je važno obezbediti da pravite visoko produktivne obrasce sa najboljim praksama u dizajnu i izgledu korisničkog interfejsa. Za informacije o dizajniranju obrazaca za efikasnost i produktivnost, pogledajte Dizajniranje produktivne glavnih obrazaca u aplikacijama zasnovanim na modelu.

Takođe je važno obezbediti da korisnici budu na preporučenim i podržanim uređajima i sa minimalno potrebnim specifikacijama. Još informacija: Podržani veb-pregledači i mobilni uređaji

Rad sa podacima i karticama

Ovaj odeljak pokriva način na koji kontrole koje prikazuju podatke i kartice utiču na performanse obrasca.

Značaj podrazumevane kartice

Podrazumevana kartica je prva proširena kartica na obrascu. On igra posebnu ulogu pri učitavanju stranice obrasca. Po dizajnu, kontrole podrazumevane kartice uvek se prikazuju pri otvaranju zapisa. Konkretno, logika inicijalizacije kontrole, kao što je preuzimanje podataka, poziva se za svaku kontrolu na kartici.

Nasuprot tome, sekundarna kartica ne obavlja ovu inicijalizaciju na svojim kontrolama pri prvom učitavanju obrasca. Umesto toga, inicijalizacija kontrole se dešava u trenutku otvaranja sekundarne kartice bilo putem interakcije korisnika ili pozivanjem klijentskog API metoda setFocus. Ovo pruža mogućnost da se početno učitavanje obrasca zaštiti od prekomerne obrade kontrola tako što će se određene kontrole postaviti na sekundarne kartice umesto na podrazumevanu karticu. Stoga, strategija postavljanja kontrola može imati značajan uticaj na odziv pri početnom učitavanju obrasca. Odgovarajuća podrazumevana kartica pruža bolje opšte iskustvo za izmenu važnih polja, interakciju sa komandnom trakom i istraživanje drugih kartica i odeljaka.

Uvek postavite kontrole koje se najviše koriste na vrh podrazumevane kartice. Arhitektura izgleda i informacija nije važna samo za performanse, već i za poboljšanje produktivnosti kada korisnici stupaju u interakciju sa podacima na obrascu. Još informacija: Dizajniranje produktivnih glavnih obrazaca u aplikacijama zasnovanim na modelu

Kontrole zasnovane na podacima

Kontrole koje zahtevaju dodatne podatke izvan primarnog zapisa proizvode najveći pritisak na odziv obrasca i brzinu učitavanja. Te kontrole preuzimaju podatke preko mreže i često uključuju period čekanja (koji se vidi kao pokazatelj napretka) jer može proći neko vreme za prenos podataka.

Neke od kontrola zasnovanih na podacima uključuju sledeće elemente:

Zadržite samo najčešće korišćene od ovih kontrola na podrazumevanoj kartici. Preostale kontrole zasnovane na podacima treba da rasporedite na sekundarne kartice kako bi se omogućilo brzo učitavanje podrazumevane kartice. Štaviše, ova strategija rasporeda smanjuje mogućnost preuzimanja podataka koji na kraju ostanu neiskorišćeni.

Postoje i druge kontrole koje su manje uticajne od kontrola zasnovanih na podacima, ali i dalje mogu učestvovati u gornjoj strategiji izgleda kako bi se postigle najbolje performanse. Ove kontrole uključuju:

Veb-pregledač

Ovaj odeljak pokriva dobre prakse za korišćenje sa veb-pregledačima.

Ne otvarajte nove prozore

Klijentska API metoda openForm dozvoljava opciji parametra da prikaže obrazac u novom prozoru. Nemojte koristiti ovaj parametar niti ga postaviti na netačno. Postavljanje na netačno će obezbediti da metoda openForm izvede podrazumevano ponašanje prikaza obrasca koristeći postojeći prozor. Takođe je moguće direktno pozvati JavaScript funkciju window.open iz prilagođene skripte ili druge aplikacije; međutim, i to treba izbegavati. 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 keširanja podataka u memoriji između prethodno učitanog obrasca i obrasca u novom prozoru. Kao alternativu otvaranju novih prozora, razmislite o korišćenju iskustva sa više sesija koje omogućava otvaranje zapisa na više kartica, a istovremeno maksimalno povećava performanse keširanja klijenta.

Korišćenje modernih pregledača

Korišćenje najažurnijeg veb-pregledača ključno je za obezbeđenje što bržeg pokretanja aplikacije zasnovane na modelu. Razlog za to je što se mnoga poboljšanja performansi mogu koristiti samo u novijim modernim pregledačima.

Na primer, ako vaša organizacija ima starije verzije pregledača Firefox, pregledače koji nisu zasnovani na jezgru Chromium i slično, mnogi dobici od performansi ugrađeni u aplikaciju zasnovanu na modelu neće biti dostupni u starijim verzijama pregledača, jer one ne podržavaju funkcije od kojih zavisi brzo i glatko pokretanje aplikacije.

U većini slučajeva možete očekivati poboljšanja učitavanja stranice samo prelaskom na Microsoft Edge, ažuriranje na najnoviju trenutnu verziju pregledača sa starije verzije ili prelazak na savremeni pregledač zasnovan na jezgru Chromium.

JavaScript prilagođavanje

Ovaj odeljak pokriva kako da napravite inteligentna prilagođavanja kada koristite JavaScript koji vam pomaže da napravite efikasne obrasce i stranice u aplikaciji zasnovanoj na modelu.

Korišćenje JavaScript-a sa obrascima

Mogućnost prilagođavanja obrazaca pomoću JavaScript-a pruža profesionalnim programerima veliku fleksibilnost u pogledu izgleda i ponašanja obrasca. Nepravilna upotreba ove fleksibilnosti može negativno uticati na performanse obrasca. Programeri bi trebalo da koriste sledeće strategije za maksimalnu uvećanje performansi obrasca pri primeni JavaScript prilagođavanja.

Koristite zahteve asinhrone mreže pri zahtevanju podataka

Zahtevajte podatke asinhrono, a ne sinhrono, kada su za prilagođavanja potrebni dodatni podaci. Za događaje koji podržavaju čekanje na asinhroni kôd, poput događaja obrasca OnLoad i događaja obrasca OnSave, rukovaoci događajima treba da vrate Promise kako bi platforma sačekala da Promise obavi svoju funkciju. Platforma će prikazati odgovarajući korisnički interfejs dok korisnik sačeka da se događaj završi.

Za događaje koji ne podržavaju čekanje na asinhroni kôd, poput događaja OnChange u obrascu, možete koristiti zaobilazno rešenje da biste zaustavili interakciju sa obrascem dok kôd izvršava asinhroni zahtev koristeći showProgressIndicator. To je bolje od korišćenja sinhronih zahteva, jer će korisnici i dalje moći da komuniciraju sa drugim delovima aplikacije dok se prikazuje indikator napretka.

Evo primera korišćenja asinhronog koda u sinhronim tačkama proširenja.

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

Trebalo bi da budete oprezni kada koristite asinhroni kôd u rukovaocu događaja koji ne podržava čekanje na asinhroni kôd. Ovo posebno važi za kôd kome je potrebna radnja koja treba da se preduzme ili kojom treba da se rukuje pri rešavanju asinhronog koda. Asinhroni kôd može izazvati probleme ako rukovalac rešavanja očekuje da kontekst aplikacije ostane isti kao što je bio kada je asinhroni kôd pokrenut. Vaš kôd bi trebalo da proveri da li je korisnik u istom kontekstu nakon svake asinhrone tačke nastavka.

Na primer, u obrađivaču događaja može postojati kôd za postavljanje mrežnog zahteva i promenu kontrole koja će biti onemogućena na osnovu podataka o odgovoru. Pre nego što bude primljen odgovor iz zahteva, korisnik je možda stupio u interakciju sa 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 grešaka ili može doći do drugog neželjenog ponašanja.

Asinhrona podrška za u događajima obrasca OnLoad i OnSave

Događaji obrasca OnLoad i OnSave podržavaju rukovaoce koji vraćaju obećanja. Događaji će čekati na obećanja koja je rukovalac vratio da razreše, do perioda isteka. Ova podrška se može omogućiti putem postavki aplikacije.

Još informacija:

Ograničite količinu zahtevanih podataka tokom učitavanja obrasca

Zatražite samo minimalnu količinu podataka koja je neophodna za izvođenje poslovne logike na obrascu. Keširajte podatke koji su zahtevani što je više moguće, posebno za podatke koji se ne menjaju često ili ne moraju da budu sveži. Na primer, zamislite da postoji obrazac koji zahteva podatke od tabele podešavanje. Na osnovu podataka u tabeli sa podešavanjima, obrazac može izabrati da sakrije deo obrasca. U ovom slučaju, JavaScript može da kešira podatke u sessionStorage tako da se podaci traže samo jednom po sesiji (onLoad1). Strategija zastoja dok traje ponovna provera valjanosti se takođe može koristiti tamo gde JavaScript koristi podatke iz objekta sessionStorage dok traži podatke za sledeću navigaciju do obrasca (onLoad2). Konačno, strategija deduplikacije bi se mogla koristiti u slučaju da se rukovalac 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   
    }
}

Koristite podatke dostupne u klijentskom API-ju umesto da šaljete zahteve. Na primer, umesto da tražite bezbednosne uloge korisnika pri učitavanju obrasca, možete da koristite getGlobalContext.userSettings.roles.

Učitajte kôd samo kada je to 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 trebalo da bude uključen u biblioteku koja se učitava za obrazac V. Taj kôd bi trebalo da bude u sopstvenoj biblioteci.

Izbegavajte učitavanje biblioteka u događaju OnLoad ako se one koriste samo za događaje OnChange ili OnSave. Umesto toga, učitajte ih u te događaje. Na ovaj način platforma može odložiti njihovo učitavanje sve dok se obrazac ne učita. Još informacija: Optimizujte performanse obrasca

Uklanjanje korišćenja API-ja konzole u kodu proizvodnje

Nemojte koristiti API metode konzole kao što je console.log u kodu proizvodnje. Evidentiranje podataka na konzolu može značajno da poveća potražnju za memorijom i može sprečiti čišćenje podataka u memoriji. To može dovesti do toga da aplikacija vremenom postane sporija i napokon padne.

Izbegavajte curenje memorije

Curenja memorije u kodu mogu dovesti do sporijih performansi tokom vremena i na kraju dovesti do pada aplikacije. Curenja memorije se javljaju kada aplikacija ne uspe da oslobodi memoriju kada to više nije potrebno. Sa svim prilagođavanjima i komponentama koda u obrascu, trebalo bi da:

  • Temeljno razmotrite i testirate scenarije za sve što je odgovorno za čišćenje memorije, kao što su klase odgovorne za upravljanje životnim ciklusom objekata.
  • Očistite sve osluškivače događaja i pretplate, naročito ako je reč o objektu window.
  • Čišćenje svih tajmera kao što je setInterval.
  • Izbegavajte, ograničavajte i čistite reference na globalne ili statičke objekte.

Za prilagođene komponente kontrole, čišćenje se može obaviti metodom destroy.

Za više informacija o rešavanju problema sa memorijom, pogledajte ovu dokumentaciju za Edge programere.

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

Ovaj odeljak opisuje alate koji vam mogu pomoći da razumete probleme sa performansama i nudi preporuke o tome kako da optimizujete prilagođavanja u aplikacijama zasnovanim na modelu.

Uvidi u performanse

Uvid u performanse je samouslužna alatka za autore aplikacija u preduzećima koja analizira telemetrijske podatke u toku izvođenja i daje listu preporuka po prioritetu kako bi se poboljšale performanse aplikacija zasnovanih na modelu. Ova funkcija pruža svakodnevni skup analitičkih uvida koji se odnose na performanse Power Apps aplikacija zasnovanih na modelu ili aplikacija za angažovanje klijenata, kao što su Dynamics 365 Sales ili Dynamics 365 Service,, sa preporukama i operativnim stavkama koje se mogu primeniti. Autori aplikacija za preduzeća mogu da vide detaljne uvide u performanse na nivou aplikacije u usluzi Power Apps. Još informacija: Šta su uvidi u performanse? (verzija za pregled)

Kontrolor rešenja

Provera rešenja je moćan alat koji može da analizira prilagođavanja klijenta i servera radi problema sa performansama ili pouzdanošću. Može analizirati JavaScript na strani klijenta, u XML-u obrasca i .NET dodacima na strani servera i dati ciljani uvid u ono što može usporiti krajnje korisnike. Preporučujemo da pokrenete proveru rešenja svaki put kada objavite promene u razvojnom okruženju, tako da se pre nego što doprete do krajnjih korisnika pojave sve nedoumice oko performansi. Još informacija: Koristite kontrolor rešenja za potvrdu valjanosti aplikacija koje pokreće model u usluzi Power Apps

Neki primeri problema vezanih za performanse pronađenih pomoću alata za proveru rešenja:

Kontrolor objekata

Provera objekata pokreće dijagnostiku u realnom vremenu na objektima komponenti u okviru vašeg rešenja. Ako se otkriju problemi, vraća se preporuka koja opisuje kako da rešite problem. Još informacija: Koristite alatku za proveru objekata da biste dijagnostikovali komponentu rešenja (verzija za pregled)

Sledeći koraci

Dizajnirajte produktivne glavne obrasce u aplikacijama zasnovanim na modelu