Споделяне чрез


Форми за проектиране за изпълнение в приложения, управлявани от модели

Изграждането на опит, при който задачите могат да се изпълняват бързо и ефективно, е от решаващо значение за удовлетвореността на потребителите. Приложенията, управлявани от модели, могат да бъдат силно персонализирани, за да създават опит, който отговаря на нуждите на вашите потребители, но е важно да знаете как ефективно да кодирате, изграждате и стартирате управлявани от модели приложения, които се зареждат бързо, когато потребителят отваря и навигира в приложението ви докато работите върху ежедневни задачи. Доказано е, че производителността е ключов двигател на недоволството от приложение, когато то не е оптимизирано за производителност.

Интелигентните персонализации и ефективните форми са важни аспекти за изграждането на високоефективни и продуктивни форми. Също така е важно да се уверите, че изграждате високопродуктивни форми с най -добрите практики в дизайна и оформлението на потребителския интерфейс. За информация относно проектирането на формуляри за ефективност и производителност вижте Проектирайте продуктивни основни форми в приложения, управлявани от модели.

Също така е важно да се гарантира, че потребителите са на препоръчани и поддържани устройства и минимални необходими спецификации. Още информация: Поддържани уеб браузъри и мобилни устройства

Работа с данни и раздели

Този раздел обхваща как контролите, които показват данни и раздели, влияят върху производителността на формуляра.

Значение на раздела по подразбиране

Разделът по подразбиране е първият разгънат раздел във формуляр. Той играе специална роля при зареждането на страница с формуляр. По дизайн контролите на раздела по подразбиране винаги се изобразяват при отваряне на запис. По -конкретно, логиката за инициализация на контрола, като извличане на данни, се извиква за всяка контрола в раздела.

За разлика от това, вторичен раздел не изпълнява тази инициализация върху своите контроли, когато формулярът е първоначално зареден. Вместо това инициализацията на контролата се случва в момента, когато вторичният раздел се отваря или чрез взаимодействие с потребителя, или чрез извикване на setFocus клиентски API метод. Това дава възможност да се защити първоначалното натоварване на формуляра от прекомерна обработка на контрола, като се поставят определени контроли във вторични раздели, вместо в раздела по подразбиране. По този начин стратегията за поставяне на контрол може да има значителен ефект върху отзивчивостта на първоначалното зареждане на формуляра. По -отзивчив раздел по подразбиране осигурява по -добро цялостно изживяване за промяна на важни полета, взаимодействие с командната лента и проучване на други раздели и секции.

Винаги поставяйте контролите, които се използват най -много, в горната част на раздела по подразбиране. Оформлението и информационната архитектура са важни не само за производителността, но и за подобряване на производителността, когато потребителите взаимодействат с данните във формуляра. Повече информация: Проектирайте продуктивни основни форми в приложения, управлявани от модели

Управлявани от данни контроли

Контролите, които изискват допълнителни данни извън основния запис, произвеждат най -голям натиск върху отзивчивостта на формата и скоростта на зареждане. Тези контроли извличат данни през мрежата и често включват период на изчакване (разглеждан като индикатори за напредък), защото може да отнеме време за предаване на данните.

Някои от управляваните от данни контроли включват:

Оставете само най -често използваните от тези контроли в раздела по подразбиране. Останалите контроли, управлявани от данни, трябва да бъдат разпределени във вторични раздели, за да позволят раздела по подразбиране да се зарежда бързо. Освен това тази стратегия за оформление намалява шанса за извличане на данни, които в крайна сметка остават неизползвани.

Има и други контроли, които са по-малко ефективни от управляваните от данни контроли, но все пак могат да участват в горната стратегия за оформление, за да се постигне най-добрата производителност. Тези контроли включват:

Уеб браузър

Този раздел обхваща добрите практики за използване с уеб браузъри.

Не отваряйте нови прозорци

Методът на клиентският API openForm позволява опция за параметър да показва формуляр в нов прозорец. Не използвайте този параметър и не го задавайте на false. Задаването му на false ще гарантира, че openForm методът изпълнява поведението по подразбиране за показване на формуляра, използвайки съществуващия прозорец. Възможно е и директно извикване на window.open JavaScript функция от персонализиран скрипт или друго приложение; това обаче също трябва да се избягва. Отварянето на нов прозорец означава, че всички ресурси на страницата трябва да бъдат изтеглени и заредени от нулата, тъй като страницата не е в състояние да използва възможностите за кеширане на данни в паметта между предварително заредена форма и формуляра в нов прозорец. Като алтернатива на отварянето на нови прозорци, помислете за използването на мултисесионното изживяване, което позволява отварянето на записи в множество раздели, като същевременно увеличава максимално ползите от производителността на кеширането на клиента.

Използвайте съвременни браузъри

Използването на най-актуалния уеб браузър е от ключово значение за осигуряване на възможно най-бързото изпълнение на приложението, управлявано от модела. Причината за това е, че много от подобренията в производителността могат да се използват само в по -новите съвременни браузъри.

Например, ако вашата организация има по-стари версии на Firefox, браузъри, които не са базирани на Chromium, и така нататък, много от повишенията на производителността, които са вградени в приложение, управлявано от модел, няма да бъдат налични в по-старите версии на браузъра, защото не поддържат функции, от които приложението зависи за бързо стартиране и плавно.

В повечето случаи можете да очаквате да видите подобрения при зареждането на страници, като просто преминете към Microsoft Edge, актуализиране до най-новата актуална версия на браузъра от по-стара версия или преминаване към модерен браузър, базиран на Chromium.

JavaScript персонализиране

Този раздел обхваща как да направите интелигентни персонализации, когато използвате JavaScript, които ви помагат да изграждате ефективни форми и страници в приложение, управлявано от модел.

Използване на JavaScript с формуляри

Възможността формулярите да бъдат персонализирани от JavaScript предоставя на професионалните разработчици голяма гъвкавост за това как изглежда и как се държи формулярът. Неправилното използване на тази гъвкавост може да повлияе негативно на работата на формата. Разработчиците трябва да използват следните стратегии, за да увеличат максимално производителността на формуляра, когато прилагат персонализиране на JavaScript.

Използвайте асинхронни мрежови заявки, когато заявявате данни

Искайте данни асинхронно, а не синхронно, когато са необходими допълнителни данни за персонализиране. За събития, които поддържат изчакване на асинхронен код като формата OnLoad и форма OnSave събития, обработващите събития трябва да върнат Promise, за да може платформата да изчака докато Promise се уреди. Платформата ще показва подходящ потребителски интерфейс, докато потребителят изчака събитието да завърши.

За събития, които не поддържат изчакване за асинхронен код, като OnChange събитие на формуляр, можете да използвате заобиколно решение, за да спрете взаимодействието с формуляр, докато кодът прави асинхронна заявка, като използвате showProgressIndicator. Това е по -добре от използването на синхронни заявки, тъй като потребителите все още ще могат да взаимодействат с други части на приложението, тъй като се показва индикатор за напредък.

Ето пример за използване на асинхронен код в синхронни точки на разширение.

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

Трябва да бъдете внимателни, когато използвате асинхронен код в манипулатор на събития, който не поддържа изчакване за асинхронен код. Това е особено вярно за код, който се нуждае от действие, което да се предприеме или обработи за разрешаването на асинхронния код. Асинхронният код може да причини проблеми, ако манипулаторът за разрешаване очаква контекстът на приложението да остане същият, както при стартирането на асинхронния код. Вашият код трябва да провери дали потребителят е в същия контекст след всяка асинхронна точка на продължение.

Например, може да има код в манипулатор на събития, който да направи мрежова заявка и да промени контрола, която да бъде деактивирана въз основа на данните за отговора. Преди да бъде получен отговорът от заявката, потребителят може да е взаимодействал с контролата или да е преминал към друга страница. Тъй като потребителят е на друга страница, контекстът на формуляра може да не е наличен, което може да доведе до грешки или да има друго нежелано поведение.

Асинхронна поддръжка във формат OnLoad и във формат OnSave събития

OnLoad и OnSave събития на формуляр поддържат манипулатори, които връщат обещания. Събитията ще изчакат всички обещания, върнати от манипулатор за разрешаване, до период на изчакване. Тази поддръжка може да бъде активирана чрез настройките на приложението.

Допълнителна информация:

Ограничете количеството данни, поискани по време на зареждане на формуляра

Искайте само минималното количество данни, което е необходимо за извършване на бизнес логика на формуляр. Кеширайте данните, които се изискват възможно най -много, особено за данни, които не се променят често или не е необходимо да са пресни. Например, представете си, че има формуляр, който иска данни от таблицата настройка. Въз основа на данни в таблицата с настройки формулярът може да избере да скрие част от формуляра. В този случай JavaScript може да кешира данни в sessionStorage така че данните се искат само веднъж на сесия (onLoad1). Може да се използва и застояла при повторна проверка стратегия, когато JavaScript използва данните от sessionStorage докато изисквате данни за следващата навигация към формуляра (onLoad2). И накрая, може да се използва стратегия за дедупликация в случай, че манипулатор се извика няколко пъти подред (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   
    }
}

Използвайте наличната информация в клиентския API, вместо да отправяте заявки. Например, вместо да изисквате потребителски роли за сигурност при зареждане на формуляр, можете да използвате getGlobalContext.userSettings.roles.

Зареждайте код само когато е необходим

Заредете толкова код, колкото е необходимо за събития за конкретна форма. Ако имате код, който е само за форма А и форма В, не трябва да се включва в библиотека, която се зарежда за форма С. Тя трябва да бъде в собствена библиотека.

Избягвайте зареждането на библиотеки в OnLoad събитие, ако се използват само за OnChange или OnSave събития. Вместо това ги заредете в тези събития. По този начин платформата може да отложи зареждането им, докато формулярът не се зареди. Повече информация: Оптимизирайте работата на формуляра

Премахнете използването на API на конзолата в производствения код

Не използвайте конзолни API методи като console.log в производствен код. Записването на данни в конзолата може значително да увеличи търсенето на памет и може да попречи на данните да бъдат изчистени в паметта. Това може да доведе до по-бавно приложение с течение на времето и в крайна сметка до срив.

Избягвайте изтичане на памет

Изтичането на памет във вашия код може да доведе до по-бавна производителност с течение на времето и в крайна сметка да доведе до срив на приложението ви. Изтичане на памет възниква, когато приложението не успее да освободи памет, когато вече не е необходима. С всички персонализации и компоненти на код във формуляра ви трябва:

  • Внимателно обмислете и тествайте сценарии за всичко, отговорно за почистването на паметта, като класове, отговорни за управлението на жизнения цикъл на обектите.
  • Почистете всички слушатели на събития и абонаменти, особено ако е на window обект.
  • Почистване на всички таймери като setInterval.
  • Избягвайте, ограничавайте и почиствайте препратки към глобални или статични обекти.

За персонализирани контролни компоненти почистването може да се извърши в destroy метод.

За повече информация относно отстраняването на проблеми с паметта отидете на тази документация за разработчици на Edge.

Инструменти, които можете да използвате, за да направите приложенията по-ефективни

Този раздел описва инструментите, които могат да ви помогнат да разберете проблемите с производителността и предлага препоръки за това как да оптимизирате вашите персонализации в приложения, управлявани от модели.

Прозрения за производителността

Анализът на ефективността е инструмент за самообслужване за създателите на корпоративни приложения, който анализира данните от телеметрията по време на изпълнение и предоставя приоритетен списък с препоръки, които да помогнат за подобряване на производителността на управлявани от модели приложения. Тази функция осигурява ежедневен набор от аналитични данни, свързани с производителността на приложение, управлявано от модел, на Power Apps или приложение на Customer Engagement, като Dynamics 365 Sales или Dynamics 365 Service, с препоръки и елементи за действие. Производителите на корпоративни приложения могат да преглеждат подробна информация за ефективността на ниво приложение в Power Apps. Повече информация: Какви са представите за ефективността? (преглед)

Инструмент за проверка на решения

Проверката на решения е мощен инструмент, който може да анализира персонализациите на клиента и сървъра за проблеми с производителността или надеждността. Той може да анализира JavaScript от страна на клиента, да формира XML и .NET сървърни приставки и да дава целенасочена информация за това, което може да забави крайните потребители. Препоръчваме ви да стартирате проверка на решения всеки път, когато публикувате промени в среда за разработка, така че всички проблеми с производителността да се появят, преди да достигнат до крайните потребители. Повече информация: Използване на инструмента за проверка на решения за валидиране на базирани на модел приложения в Power Apps

Някои примери за проблеми, свързани с производителността, открити при проверка на решения:

  • il-specify-column. Избягвайте да избирате всички колони чрез API на заявки на Dataverse.
  • web-use-async. Взаимодействие с HTTP и HTTPS ресурси асинхронно.
  • web-avoid-ui-refreshribbon. Избягвайте използването refreshRibbon в OnLoad и EnableRule на формуляр.

Проверка на обекти

Проверката на обекти изпълнява диагностика в реално време на компоненти на обекти в решението. Ако се открият проблеми, се връща препоръка, която описва как да отстраните проблема. Повече информация: Използвайте проверка на обекти, за да диагностицирате компонент на решение (преглед)

Следващи стъпки

Проектиране на продуктивни основни формуляри в приложения, управлявани от модел