Udostępnij przez


Projektowanie formularzy pod kątem wydajności w aplikacjach opartych na modelu

Tworzenie środowisk, w których zadania mogą być wykonywane szybko i wydajnie, ma kluczowe znaczenie dla zadowolenia użytkowników. Aplikacje oparte na modelu mogą być wysoce dostosowywane, aby tworzyć doświadczenia spełniające potrzeby użytkowników, ale ważne jest, aby wiedzieć, jak efektywnie kodować, tworzyć i uruchamiać aplikacje oparte na modelu, które szybko ładują się po otwarciu i umożliwiają sprawne nawigowanie podczas pracy nad codziennymi zadaniami. Wydajność okazała się kluczowym czynnikiem niezadowolenia aplikacji, gdy nie jest zoptymalizowana pod kątem wydajności.

Inteligentne dostosowania i wydajne formy są ważnymi aspektami tworzenia wysoce wydajnych i wydajnych formularzy. Ważne jest również, aby upewnić się, że tworzysz wysoce produktywne formularze przy użyciu najlepszych rozwiązań w projektowaniu i układzie interfejsu użytkownika. Aby uzyskać informacje na temat projektowania formularzy pod kątem wydajności i produktywności, zobacz Projektowanie wydajnych formularzy głównych w aplikacjach opartych na modelu.

Należy również upewnić się, że użytkownicy znajdują się na zalecanych i obsługiwanych urządzeniach oraz minimalnych wymaganych specyfikacjach. Więcej informacji: Obsługiwane przeglądarki internetowe i urządzenia przenośne

Praca z danymi i kartami

W tej sekcji opisano sposób, w jaki kontrolki wyświetlające dane i karty wpływają na wydajność formularzy.

Znaczenie karty domyślnej

Domyślna zakładka jest pierwszą rozwiniętą zakładką na formularzu. Odgrywa ona szczególną rolę w ładowaniu strony formularza. Z założenia kontrolki domyślnej zakładki są zawsze wyświetlane podczas otwierania rekordu. W szczególności, logika inicjalizacji kontrolki, taka jak pobieranie danych, jest wywoływana dla każdej kontrolki na karcie.

W przeciwieństwie do tego, drugorzędna karta nie wykonuje tej inicjalizacji na swoich kontrolkach, gdy formularz jest początkowo ładowany. Zamiast tego inicjalizacja kontrolki odbywa się w momencie otwarcia zakładki drugorzędnej za pośrednictwem interakcji użytkownika lub wywołania metody klienta API setFocus. Zapewnia to możliwość zabezpieczenia początkowego obciążenia formularza przed nadmiernym przetwarzaniem kontroli przez umieszczenie niektórych kontrolek na kartach pomocniczych zamiast domyślnej karty. W związku z tym strategia umieszczania kontrolek może mieć znaczący wpływ na czas odpowiedzi początkowego obciążenia formularza. Bardziej elastyczna karta domyślna zapewnia lepsze ogólne środowisko modyfikowania ważnych pól, interakcji z paskiem poleceń oraz eksplorowania innych kart i sekcji.

Zawsze umieszczaj kontrolki, które są najczęściej używane w górnej części karty domyślnej. Architektura układu i informacji jest nie tylko ważna dla wydajności, ale także zwiększa produktywność, gdy użytkownicy wchodzą w interakcje z danymi w formularzu. Więcej informacji: Projektowanie wydajnych formularzy głównych w aplikacjach opartych na modelu

Kontrolki sterowane danymi

Kontrolki, które wymagają dodatkowych danych poza rekordem podstawowym, generują największe obciążenie responsywności formularza i szybkości jego ładowania. Te mechanizmy kontroli pobierają dane za pośrednictwem sieci i często obejmują okres oczekiwania (widoczny jako wskaźniki postępu), ponieważ przesyłanie danych może zająć trochę czasu.

Niektóre kontrolki oparte na danych obejmują:

Zachowaj tylko najczęściej używane te kontrolki na karcie domyślnej. Pozostałe kontrolki oparte na danych powinny być dystrybuowane do kart pomocniczych, aby umożliwić szybkie ładowanie karty domyślnej. Ponadto ta strategia rozmieszczenia zmniejsza prawdopodobieństwo pobrania danych, które pozostają niewykorzystane.

Istnieją inne kontrolki, które mają mniejszy wpływ niż kontrolki oparte na danych, ale nadal mogą uczestniczyć w powyższej strategii układu, aby osiągnąć najlepszą wydajność. Te kontrolki obejmują:

przeglądarka internetowa

W tej sekcji omówiono dobre praktyki dotyczące korzystania z przeglądarek internetowych.

Nie otwieraj nowych okien

Metoda API klienta openForm umożliwia za pomocą parametru opcję wyświetlenia formularza w nowym oknie. Nie używaj tego parametru ani nie ustawiaj go na wartość false. Ustawienie wartości false spowoduje, że openForm metoda wykonuje domyślne zachowanie wyświetlania formularza przy użyciu istniejącego okna. Można również bezpośrednio wywołać window.open funkcję JavaScript ze skryptu niestandardowego lub innej aplikacji, jednak należy tego uniknąć. Otwarcie nowego okna oznacza, że wszystkie zasoby strony muszą zostać pobrane i załadowane od podstaw, ponieważ strona nie może wykorzystać możliwości buforowania danych w pamięci między wcześniej załadowanym formularzem a formularzem w nowym oknie. Jako alternatywę do otwierania nowych okien, rozważ użycie środowiska z wieloma sesjami, które pozwala na otwieranie rekordów w wielu kartach, jednocześnie maksymalizując korzyści z wydajności buforowania klienta.

Korzystanie z nowoczesnych przeglądarek

Korzystanie z najbardziej up-to- date przeglądarki internetowej jest kluczem do zapewnienia, że aplikacja oparta na modelu działa tak szybko, jak to możliwe. Powodem jest to, że wiele ulepszeń wydajności może być używanych tylko w nowszych nowoczesnych przeglądarkach.

Jeśli na przykład twoja organizacja ma starsze wersje przeglądarek Firefox, nienależących do chromium i tak dalej, wiele zysków wydajności wbudowanych w aplikację opartą na modelu nie będzie dostępnych w starszych wersjach przeglądarki, ponieważ nie obsługują one funkcji, od których aplikacja zależy od szybkiego i bezproblemowego działania.

W większości przypadków można spodziewać się ulepszeń ładowania stron, przełączając się na przeglądarkę Microsoft Edge, aktualizując do najnowszej bieżącej wersji przeglądarki ze starszej wersji lub przechodząc do nowoczesnej przeglądarki opartej na chromium.

Dostosowywanie języka JavaScript

W tej sekcji opisano sposób tworzenia inteligentnych dostosowań podczas korzystania z języka JavaScript, który ułatwia tworzenie wydajnych formularzy i stron w aplikacji opartej na modelu.

Używanie języka JavaScript z formularzami

Możliwość dostosowywania formularzy przez język JavaScript zapewnia profesjonalnym deweloperom dużą elastyczność w zakresie wyglądu i zachowania formularza. Niewłaściwe wykorzystanie tej elastyczności może negatywnie wpłynąć na wydajność formy. Deweloperzy powinni użyć następujących strategii, aby zmaksymalizować wydajność formularzy podczas implementowania dostosowań języka JavaScript.

Używanie asynchronicznych żądań sieciowych podczas żądania danych

Żądaj danych asynchronicznie, a nie synchronicznie, gdy dodatkowe dane są niezbędne do dostosowania. Dla zdarzeń, które wspierają oczekiwanie na kod asynchroniczny jak formularz OnLoad i formularz OnSave, obsługa zdarzeń powinna zwracać Promise, aby platforma czekała aż Promise zostanie rozliczona. Platforma będzie wyświetlać odpowiedni interfejs użytkownika, gdy użytkownik czeka na ukończenie zdarzenia.

W przypadku zdarzeń, które nie obsługują oczekiwania na kod asynchroniczny, taki jak zdarzenie formularza OnChange , można użyć obejścia, aby zatrzymać interakcję z formularzem, gdy kod wykonuje żądanie asynchroniczne przy użyciu polecenia showProgressIndicator. Jest to lepsze niż używanie żądań synchronicznych, ponieważ użytkownicy nadal będą mogli korzystać z innych części aplikacji w miarę wyświetlania wskaźnika postępu.

Oto przykład użycia kodu asynchronicznego w punktach rozszerzenia synchronicznego.

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

Należy zachować ostrożność podczas używania kodu asynchronicznego w procedurze obsługi zdarzeń, która nie obsługuje oczekiwania na kod asynchroniczny. Jest to szczególnie prawdziwe w przypadku kodu, który wymaga akcji, która ma zostać podjęta lub obsłużona po rozwiązaniu kodu asynchronicznego. Kod asynchroniczny może powodować problemy, jeśli program obsługi rozwiązywania oczekuje, że kontekst aplikacji pozostanie taki sam jak podczas uruchamiania kodu asynchronicznego. Kod powinien sprawdzić, czy użytkownik znajduje się w tym samym kontekście po każdym asynchronicznym punkcie kontynuacji.

Na przykład może istnieć kod w procedurze obsługi zdarzeń w celu utworzenia żądania sieciowego i zmiany kontrolki, która ma zostać wyłączona na podstawie danych odpowiedzi. Przed odebraniem odpowiedzi z żądania użytkownik mógł wchodzić w interakcję z kontrolką lub przechodzić do innej strony. Ponieważ użytkownik znajduje się na innej stronie, kontekst formularza może być niedostępny, co może prowadzić do błędów lub może wystąpić inne niepożądane zachowanie.

Obsługa asynchroniczności w zdarzeniach OnLoad i OnSave formularza

Zdarzenia OnLoad i OnSave formularzy obsługują programy do obsługi, które zwracają obietnice. Zdarzenia będą czekać na rozwiązanie obietnic zwróconych przez handler, aż do momentu przekroczenia limitu czasu. Tę obsługę można włączyć za pośrednictwem ustawień aplikacji.

Więcej informacji:

Ogranicz ilość danych żądanych podczas ładowania formularza

Zażądaj tylko minimalnej ilości danych niezbędnych do wykonania logiki biznesowej w formularzu. Buforuj żądane dane tak bardzo, jak to możliwe, zwłaszcza w przypadku danych, które nie zmieniają się często lub nie muszą być świeże. Załóżmy na przykład, że istnieje formularz, który żąda danych z tabeli ustawień . Na podstawie danych w tabeli ustawień formularz może wybrać opcję ukrycia sekcji formularza. W takim przypadku język JavaScript może buforować dane w sessionStorage pamięci podręcznej, dzięki czemu dane są żądane tylko raz na sesję (onLoad1). Strategia 'stale-while-revalidate' może być również używana, gdy JavaScript korzysta z danych z sessionStorage podczas żądania danych do następnej nawigacji do formularza (onLoad2). Wreszcie, strategia deduplikacji może być użyta w przypadku, gdy handler jest wywoływany wiele razy z rzędu (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   
	}
}

Użyj informacji dostępnych w interfejsie API klienta, a nie żądań. Na przykład zamiast żądać ról zabezpieczeń użytkownika podczas ładowania formularza, możesz użyć polecenia getGlobalContext.userSettings.roles.

Załaduj kod tylko wtedy, gdy jest potrzebny

Załaduj tyle kodu, ile jest potrzebnych do zdarzeń dla konkretnego formularza. Jeśli masz kod przeznaczony tylko dla formularza A i formularza B, nie powinien być uwzględniony w bibliotece załadowanej dla formularza C. Powinna ona znajdować się we własnej bibliotece.

Unikaj ładowania bibliotek w zdarzeniu OnLoad, jeśli są one używane tylko dla zdarzeń OnChange lub OnSave. Zamiast tego należy załadować je w tych zdarzeniach. Dzięki temu platforma może odroczyć ładowanie ich do momentu załadowania formularza. Więcej informacji: Optymalizowanie wydajności formularza

Usuń użycie interfejsów API konsoli w kodzie produkcyjnym

Nie używaj metod interfejsu API konsoli , takich jak console.log w kodzie produkcyjnym. Rejestrowanie danych w konsoli może znacznie zwiększyć zapotrzebowanie na pamięć i może uniemożliwić czyszczenie danych w pamięci. Może to prowadzić do tego, że aplikacja staje się wolniejsza w czasie i ostatecznie ulega awarii.

Unikaj przecieków pamięci

Przecieki pamięci w kodzie mogą prowadzić do wolniejszej wydajności w czasie i ostatecznie spowodować awarię aplikacji. Przecieki pamięci występują, gdy aplikacja nie zwalnia pamięci, gdy nie jest już potrzebna. Dla wszystkich dostosowań i składników kodu w formularzu należy:

  • Rozważyć i dokładnie przetestować scenariusze dotyczące wszystkich obiektów odpowiedzialnych za czyszczenie pamięci, na przykład klas odpowiedzialnych za zarządzanie cyklem życia obiektów.
  • Wyczyść wszystkie odbiorniki zdarzeń i subskrypcje, zwłaszcza jeśli są w obiekcie window.
  • Wyczyść wszystkie czasomierze, takie jak setInterval.
  • Unikaj, ograniczaj i czyścij odwołania do obiektów globalnych lub statycznych.

W przypadku niestandardowych składników sterujących można przeprowadzić czyszczenie w metodzie destroy.

Aby uzyskać więcej informacji na temat rozwiązywania problemów z pamięcią, przejdź do tej dokumentacji dewelopera usługi Edge.

Narzędzia, których można użyć, aby ułatwić wykonywanie aplikacji

W tej sekcji opisano narzędzia, które mogą ułatwić zrozumienie problemów z wydajnością i rekomendacje dotyczące optymalizacji dostosowań w aplikacjach opartych na modelu.

Szczegółowe informacje o wydajności

Szczegółowe informacje o wydajności to narzędzie samoobsługowe dla twórców aplikacji dla przedsiębiorstw, które analizuje dane telemetryczne środowiska uruchomieniowego i udostępnia priorytetową listę zaleceń, które pomagają poprawić wydajność aplikacji opartych na modelu. Ta funkcja zapewnia codzienny zestaw szczegółowych informacji analitycznych związanych z wydajnością aplikacji Power Apps opartej na modelu lub aplikacji typu Customer Engagement, takiej jak Dynamics 365 Sales lub Dynamics 365 Service, wraz z rekomendacjami i elementami, które można podjąć. Twórcy aplikacji dla przedsiębiorstw mogą wyświetlać szczegółowe informacje o wydajności na poziomie aplikacji w usłudze Power Apps. Więcej informacji: Co to są szczegółowe informacje o wydajności? (wersja zapoznawcza)

Sprawdzanie rozwiązania

Narzędzie do sprawdzania rozwiązań to zaawansowane narzędzie, które umożliwia analizowanie dostosowań klienta i serwera pod kątem problemów z wydajnością lub niezawodnością. Może przeanalizować kod JavaScript po stronie klienta, pliki XML i wtyczki po stronie serwera .NET i zapewnić ukierunkowane informacje na temat tego, co może spowolnić użytkowników końcowych. Zalecamy uruchamianie narzędzia do sprawdzania rozwiązań za każdym razem, gdy publikujesz zmiany w środowisku projektowym, aby przed dotarciem do użytkowników końcowych zostały wyświetlone wszelkie problemy z wydajnością. Więcej informacji: Sprawdzanie poprawności aplikacji opartych na modelu w usłudze Power Apps przy użyciu narzędzia do sprawdzania rozwiązań

Niektóre przykłady problemów związanych z wydajnością znalezionych za pomocą narzędzia do sprawdzania rozwiązań:

Kontroler obiektów

Narzędzie do sprawdzania obiektów uruchamia diagnostykę w czasie rzeczywistym na obiektach składników w rozwiązaniu. Jeśli zostaną wykryte problemy, zostanie zwrócone zalecenie, które opisuje sposób rozwiązania problemu. Więcej informacji: Używanie narzędzia sprawdzania obiektów do diagnozowania składnika rozwiązania (wersja zapoznawcza)

Dalsze kroki

Projektowanie wydajnych formularzy głównych w aplikacjach opartych na modelu