Návrhy formulářů orientovaných na výkon v modelem řízených aplikacích
Klíčem ke spokojenosti uživatelů je vytváření prostředí, ve kterých lze úkoly plnit rychle a efektivně. Modelem řízené aplikace lze přizpůsobit tak, aby vytvářely prostředí splňující potřeby vašich uživatelů, ale je důležité vědět, jak efektivně kódovat, vytvářet a spouštět modelem řízené aplikace, které se rychle načtou, když je uživatel ve vaší aplikaci při práci na každodenních úkolech otevře. Ukázalo se, že výkon je klíčovým hnacím motorem nespokojenosti s aplikací, pokud není patřičně optimalizována.
Inteligentní přizpůsobení a výkonné formuláře jsou důležitými aspekty při vytváření vysoce efektivních a produktivních formulářů. Je také důležité zajistit, abyste vytvářeli vysoce produktivní formuláře s využitím osvědčených postupů při návrhu a rozložení uživatelského rozhraní. Informace o navrhování formulářů s důrazem na efektivitu a produktivitu najdete v tématu Návrh produktivních hlavních formulářů v modelem řízených aplikacích.
Je také důležité zajistit, aby uživatelé používali doporučená a podporovaná zařízení splňující minimální požadované specifikace. Další informace: Podporované webové prohlížeče a mobilní zařízení
Práce s daty a kartami
Tato část popisuje, jak výkonnost formuláře ovlivňují ovládací prvky, které zobrazují data a karty.
Význam výchozí karty
Výchozí karta je první rozbalená karta ve formuláři. Hraje zvláštní roli při načítání stránky formuláře. Ve výchozím nastavení se ovládací prvky výchozí karty vždy vykreslí při otevírání záznamu. Logika inicializace ovládacího prvku, jako je načítání dat, je vyvolána pro každý ovládací prvek na kartě.
Oproti tomu sekundární karta při počátečním načtení formuláře neprovádí tuto inicializaci svých ovládacích prvků. Místo toho dojde k inicializaci ovládacího prvku v okamžiku otevření sekundární karty, a to buď prostřednictvím interakce uživatele nebo voláním metody setFocus
klientského API. Takto je počáteční načítání formuláře chráněno před nadměrným zpracováním ovládacích prvků, kdy jsou určité ovládací prvky umístěny na sekundární kartu místo na výchozí. Strategie umístění ovládacího prvku tedy může mít významný vliv na rychlost počátečního načtení formuláře. Výchozí karta s rychlejší reakcí poskytuje lepší prostředí pro úpravu důležitých polí, interakce s panelem příkazů a zkoumání dalších karet a sekcí.
Do horní části výchozí karty vždy umístěte ovládací prvky, které se používají nejvíce. Rozložení a informační architektura nejsou důležité pouze z hlediska výkonu, ale také pro zvýšení produktivity, když uživatelé interagují s daty ve formuláři. Více informací: Návrh produktivních hlavních formulářů v modelem řízených aplikacích
Ovládací prvky řízené daty
Ovládací prvky, které vyžadují další data mimo primární záznam, kladou největší nároky na odezvu formuláře a rychlost načítání. Tyto ovládací prvky načítají data přes síť a často zahrnují čekací dobu (zobrazenou jako indikátory průběhu), protože přenos dat může nějakou dobu trvat.
Mezi některé ovládací prvky řízené daty patří:
- Formulář pro rychlé zobrazení
- Podmřížka
- Časová osa
- Asistent (vyžaduje Dynamics 365 Sales Insights)
Na výchozí kartě ponechejte pouze nejčastěji používané ovládací prvky. Zbývající ovládací prvky řízené daty by měly být umístěny na sekundární karty, aby bylo možné rychle načíst výchozí kartu. Tato strategie rozložení navíc snižuje pravděpodobnost zbytečného načítání dat, která nebudou použita.
Existují další ovládací prvky, které mají menší výkonový dopad než ovládací prvky řízené daty, ale přesto se mohou podílet na výše uvedené strategii rozvržení, aby přispěly k co nejvyššímu výkonu. Mezi tyto ovládací prvky patří:
Webový prohlížeč
Tato část popisuje osvědčené postupy pro použití ve webových prohlížečích.
Neotvírat nová okna
Metoda openForm
klientského rozhraní API má parametr pro zobrazení formuláře v novém okně. Tento parametr nepoužívejte ani jej nenastavujte na hodnotu false. Nastavením na hodnotu false zajistíte, že metoda openForm
provede výchozí chování zobrazení formuláře pomocí existujícího okna. Je také možné přímo zavolat funkci window.open
jazyka JavaScript z vlastního skriptu nebo jiné aplikace; tomu by se však také mělo zabránit. Otevření nového okna znamená, že všechny zdroje stránky je třeba načíst od začátku, protože stránka nemůže využívat schopnosti ukládání do mezipaměti dat v paměti mezi dříve načteným formulářem a formulářem v novém okně. Jako alternativu k otevírání nových oken zvažte použití prostředí vícenásobné relace, které umožňuje otevírání záznamů na více kartách při maximalizaci výhod výkonu ukládání do mezipaměti klienta.
Používejte moderní prohlížeče
Používání nejaktuálnějšího webového prohlížeče je klíčem k zajištění toho, aby vaše modelem řízená aplikace běžela co nejrychleji. Důvodem je to, že mnoho vylepšení výkonu lze použít pouze v novějších moderních prohlížečích.
Pokud má vaše organizace například starší verze prohlížeče Firefox, které nejsou založeny na jádru Chromium atp., mnoho zisků v oblasti výkonu, které jsou integrovány do modelem řízené aplikace, nebude ve starších verzích prohlížeče k dispozici, protože tyto verze nepodporují funkce umožňující rychlé a bezproblémové spuštění aplikace.
Ve většině případů můžete očekávat zrychlené načítání stránky pouhým přechodem na prohlížeč Microsoft Edge, aktualizací na nejnovější aktuální verzi prohlížeče ze starší verze nebo přechodem na moderní prohlížeč založený na jádru Chromium.
Přizpůsobení jazyka JavaScript
Tato část popisuje, jak provádět inteligentní přizpůsobení pomocí jazyka JavaScript, který vám pomůže vytvářet výkonné formuláře a stránky v modelem řízené aplikaci.
Použití jazyka JavaScript ve formulářích
Možnost přizpůsobení formulářů pomocí kódu jazyka JavaScript poskytuje profesionálním vývojářům velkou flexibilitu v tom, jak formulář vypadá a jak se chová. Nesprávné použití této flexibility může negativně ovlivnit výkonnost formuláře. Pro maximalizaci výkonu formuláře pomocí implementace přizpůsobení psaných v jazyce JavaScript by vývojáři měli použít následující strategie.
Při žádosti o data používat asynchronní síťové požadavky
Pokud jsou pro přizpůsobení nutná další data, požadujte je asynchronně, nikoli synchronně. U událostí, které podporují čekání na asynchronní kód, jako jsou události OnLoad
a OnSave
formuláře, by obslužné rutiny událostí měly vrátit Promise
, aby platforma počkala do vyřízení Promise
. Platforma zobrazí příslušné uživatelské rozhraní, zatímco uživatel čeká na dokončení události.
U událostí, které nepodporují čekání na asynchronní kód, jako je událost OnChange
formuláře, můžete použít náhradní řešení k zastavení interakce s formulářem, zatímco kód provádí asynchronní požadavek – pomocí showProgressIndicator
. Je to lepší než používání synchronních požadavků, protože uživatelé budou stále moci komunikovat s jinými částmi aplikace v době, kdy se zobrazuje indikátor průběhu.
Zde je příklad použití asynchronního kódu v bodech synchronního rozšíření.
//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);
Při používání asynchronního kódu v obslužných rutinách událostí, které nepodporují čekání na asynchronní kód, buďte opatrní. To platí zejména pro kód, u kterého je třeba provést akci nebo zpracovat řešení asynchronního kódu. Asynchronní kód může způsobit problémy, pokud obslužná rutina řešení očekává, že kontext aplikace zůstane stejný jako při spuštění asynchronního kódu. Váš kód by měl po každém asynchronním bodu pokračování zkontrolovat, zda je uživatel ve stejném kontextu.
Například v obslužné rutině událostí může být kód pro vytvoření síťového požadavku a změnu ovládacího prvku, který má být zakázán na základě dat odezvy. Než bude odpověď z požadavku přijata, uživatel mohl interagovat s ovládacím prvkem nebo přejít na jinou stránku. Protože je uživatel na jiné stránce, kontext formuláře nemusí být k dispozici, což může vést k chybám, nebo může dojít k jinému nežádoucímu chování.
Asynchronní podpora v událostech OnLoad a OnSave formulářů
Události OnLoad
a OnSave
formuláře podporují obslužné rutiny, které vracejí Promise. Události počkají na vyřešení všech Promise vrácených obslužnou rutinou, a to až do časového limitu. Tuto podporu lze aktivovat prostřednictvím nastavení aplikace.
Další informace:
Omezte množství dat požadovaných během načítání formuláře
Vyžadujte pouze minimální množství dat, které je nutné k provedení obchodní logiky ve formuláři. Ukládejte data, která jsou požadována, co nejvíce do mezipaměti, zejména data, která se často nemění nebo nemusí být čerstvá. Představte si například, že existuje formulář, který požaduje data z tabulky setting. Na základě údajů v tabulce setting se formulář může rozhodnout skrýt část formuláře. V tomto případě může JavaScript ukládat data do mezipaměti sessionStorage
, takže data jsou požadována pouze jednou za relaci (onLoad1
). Pokud JavaScript používá data ze sessionStorage
při požadavku na data pro další navigaci do formuláře (onLoad2
), může být také použita strategie stale-while-revalidate. A konečně je možné použít deduplikační strategii v případě, že je obslužný program volán vícekrát za sebou (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
}
}
Místo vytváření požadavků použijte informace dostupné v klientském rozhraní API. Namísto vyžadování rolí zabezpečení uživatele při načítání formulářů můžete například použít getGlobalContext.userSettings.roles.
Načítejte kód pouze v případě potřeby
Pro události v konkrétním formuláři načtěte pouze tolik kódu, kolik je potřeba. Pokud máte kód, který je určen pouze pro formulář A a formulář B, neměl by být součástí knihovny, která je načtena pro formulář C. Měl by to být ve vlastní knihovně.
Vyhněte se načítání knihoven v události OnLoad
, pokud jsou použity pouze v událostech OnChange
nebo OnSave
. Načítejte je v těchto událostech. Platforma tak může odložit jejich načítání až po načtení formuláře. Více informací: Optimalizace výkonu formuláře
Odeberte použití konzolových API v produkčním kódu
Nepoužívejte metody konzolového API jako console.log
v produkčním kódu. Protokolování dat do konzoly může výrazně zvýšit nároky na paměť a může zabránit vyčištění dat v paměti. To může vést k tomu, že se aplikace časem zpomalí a nakonec se zhroutí.
Vyhněte se únikům paměti
Úniky paměti ve vašem kódu mohou časem vést ke zpomalení a nakonec způsobit selhání aplikace. K únikům paměti dochází, když se aplikaci nepodaří uvolnit paměť, která již není potřeba. Při všech úpravách a u všech komponent kódu ve formuláři byste měli:
- Důkladně zvážit a otestovat scénáře pro cokoli zodpovědné za čištění paměti, jako jsou třídy zodpovědné za správu životního cyklu objektů.
- Vyčistit všechny posluchače událostí a odběry, zejména pokud jsou na objektu
window
. - Vyčistit všechny časovače jako
setInterval
. - Nepoužívat, omezit a vyčistit reference na globální nebo statické objekty.
U vlastních ovládacích komponent lze čištění provést v metodě destroy.
Další informace o opravách problémů s pamětí naleznete v této dokumentaci pro vývojáře Edge.
Nástroje, které můžete použít ke zvýšení výkonu aplikací
Tato část popisuje nástroje, které vám mohou pomoci porozumět problémům s výkonem a nabídnout doporučení pro optimalizaci vašich přizpůsobení v modelem řízených aplikacích.
Přehledy výkonu
Přehledy výkonu jsou samoobslužný nástroj pro tvůrce podnikových aplikací, který analyzuje běhová data telemetrie a poskytuje seznam doporučení podle priorit, který má pomoci zlepšit výkon modelem řízených aplikací. Tato funkce poskytuje denní sadu analytických poznatků souvisejících s výkonem modelem řízené aplikace Power Apps nebo zapojení zákazníků, jako je Dynamics 365 Sales nebo Dynamics 365 Service, s doporučeními a akčními položkami. Tvůrci podnikových aplikací mohou zobrazit podrobné statistiky výkonu na úrovni aplikace v Power Apps. Více informací: Co jsou přehledy výkonu? (preview)
Kontrola řešení
Kontrola řešení je výkonný nástroj, který dokáže analyzovat přizpůsobení klientů a serverů z hlediska problémů s výkonem nebo spolehlivostí. Může analyzovat JavaScript na straně klienta, formuláře XML a doplňky .NET na straně serveru a poskytovat cílené informace o tom, co může zpomalit koncové uživatele. Doporučujeme spustit kontrolu řešení pokaždé, když publikujete změny ve vývojovém prostředí, abyste odhalili jakékoli problémy s výkonem předtím, než aplikaci začnou používat koncoví uživatelé. Další informace: Použití kontroly řešení k ověření vašich aplikací řízených podle modelu v Power Apps
Několik příkladů problémů souvisejících s výkonem nalezených pomocí nástroje Kontrola řešení:
- il-specify-column. Vyvarujte se výběru všech sloupců pomocí rozhraní API dotazu Dataverse.
- web-use-async. Pracujte s prostředky HTTP a HTTPS asynchronně.
- web-avoid-ui-refreshribbon. Vyhněte se používání metody
refreshRibbon
v událostiOnLoad
a metoděEnableRule
formuláře.
Kontrola objektů
Kontrola objektů spouští diagnostiku objektů komponent v rámci vašeho řešení v reálném čase. Pokud jsou zjištěny problémy, vrátí se doporučení, které popisuje, jak problém vyřešit. Více informací: Použití kontroly objektů k diagnostice komponenty řešení (preview)
Další kroky
Návrh hlavních produktivních formulářů v modelem řízených aplikacích