Поділитися через


Створення ефективних форм в модельних програмах

Створення інтерфейсів, у яких можна швидко й ефективно виконувати завдання, є важливими для задоволення користувачів. Модельні програми можуть мати широкі можливості налаштування для створення інтерфейсів, які відповідають потребам користувачів, але важливо знати, як ефективно кодувати, створювати та запускати модельні програми, які швидко завантажуються, коли користувач відкриває програму та переходить у ній під час роботи над щоденними завданнями. Ефективність показала себе ключовим фактором незадоволення програмою, якщо її не оптимізовано для ефективності.

Інтелектуальні налаштування та ефективні форми є важливими аспектами створення високоефективних і продуктивних форм. Важливо також переконатися, що ви створюєте високопродуктивні форми за допомогою найкращих методів у створенні та розмітці інтерфейсу користувача. Відомості про створення ефективних і продуктивних форм див. в розділі Створення продуктивних основних форм у модельних програмах.

Важливо також, щоб користувачі використовували рекомендовані та підтримувані пристроями з мінімальними обов’язковими характеристиками. Додаткові відомості: Підтримувані браузери та мобільні пристрої

Робота з даними та вкладками

У цьому розділі описано, як елементи керування, що відображають дані та вкладки, впливають на продуктивність форми.

Значення вкладки за замовчуванням

Вкладка за замовчуванням — це перша розгорнута вкладка форми. Вона відіграє особливу роль у завантаженні сторінки форми. За задумом, елементи керування вкладки за замовчуванням завжди відображаються під час відкриття запису. Зокрема, логіка ініціалізації елементів керування, наприклад, отримання даних, викликається для кожного елемента керування на вкладці.

На відміну від неї додаткова вкладка не виконує цю ініціалізацію для своїх елементів керування під час початкового завантаження форми. Натомість ініціалізація елементів керування відбувається під час відкриття додаткової вкладки через інтерфейс користувача або виклику методу API клієнта setFocus. Це дає змогу захистити початкове завантаження форми від надмірної обробки елементів керування за допомогою розміщення певних елементів керування на додаткових вкладках, а не на вкладці за замовчуванням. Отже, стратегія розміщення елементів керування може значно впливати на адаптивність початкового завантаження форми. Більш адаптивна вкладка за замовчуванням забезпечує кращий загальний інтерфейс змінення важливих полів, взаємодії з панеллю команд, а також перегляду інших вкладок і розділів.

Завжди розміщуйте елементи керування, які використовуються найбільше, у верхній частині вкладки за замовчуванням. Структура макета та інформації не лише важлива для ефективності, але й для підвищення продуктивності під час взаємодії користувачів із даними у формі. Додаткові відомості: Створення продуктивних основних форм у модельних програмах

Елементи керування на основі даних

Елементи керування, які потребують додаткових даних поза основним записом, максимально навантажують швидкодію форми та швидкість завантаження. Ці елементи керування отримують дані через мережу, і часто передбачають період очікування (який відображається як показники перебігу), оскільки передавання даних може зайняти певний час.

Деякі елементи керування на основі даних включають такі елементи:

Залиште на вкладці за замовчуванням лише елементи керування, що використовуються найчастіше. Решта елементів керування на основі даних слід розподілити на додаткових вкладках, щоб дозволити вкладці за замовчуванням швидко завантажуватися. Крім того, ця стратегія створення макета зменшує ймовірність отримання даних, які в результаті не використовуються.

Існують інші елементи керування, менш впливові, ніж елементи керування на основі даних, але вони також можуть брати участь у вищезгаданій стратегії створення макета, щоб досягти найкращої ефективності. До цих елементів керування входять:

Браузер

У цьому розділі описано рекомендації для використання з веб-браузерами.

Не відкривайте нові вікна

Метод API клієнта openForm дає змогу параметру відображати форму в новому вікні. Не використовуйте цей параметр і не встановлюйте для нього значення False. Якщо встановити для нього параметр False, метод openForm виконуватиме поведінку за замовчуванням, відображаючи форму за допомогою наявного вікна. Також можливо безпосередньо викликати функцію JavaScript window.open з настроюваного сценарію або іншої програми, але цього також слід уникати. Відкриття нового вікна означає, що всі ресурси сторінки потрібно отримати та завантажити з нуля, оскільки сторінка не може використовувати можливості кешування даних у пам’яті між попередньо завантаженою формою та формою в новому вікні. У якості альтернативи відкриттю вікон спробуйте використовувати багатосеансову взаємодію, яка дозволяє відкривати записи на кількох вкладках, підвищуючи переваги ефективності кешування клієнту.

Використання сучасних браузерів

Використання найновішого браузера — це ключ забезпечення максимально швидкої роботи вашої модельної програми. Причиною цього є те, що багато покращень продуктивності можна використовувати лише в нових сучасних браузерах.

Наприклад, якщо організація має старі версії 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.

Завантаження коду лише за необхідності

Завантажуйте стільки коду, скільки потрібно для подій у певній формі. Якщо ви маєте код, призначений лише для Форми A та Форми B, його не слід включати в бібліотеку, що завантажується для форми C. Він має бути у власній бібліотеці.

Уникайте завантаження бібліотек у подію OnLoad, якщо вони використовуються лише для подій OnChange або OnSave. Натомість завантажте їх у ці події. Таким чином платформа зможе відкласти їхнє завантаження, доки не завантажиться форма. Додаткові відомості: Оптимізація продуктивності форми

Видалення використання API консолі у виробничому коді

Не використовуйте методи API консолі, наприклад console.log у виробничому коді. Журналювання даних до консолі може значно збільшити попит на пам’ять і запобігти очищенню даних у пам’яті. Це може призвести до того, що програма з часом працює повільніше й зрештою аварійно завершує роботу.

Уникнення витоків пам’яті

Витоки пам’яті в коді можуть призвести до зниження продуктивності з часом і зрештою спричинити аварійне завершення роботи програми. Витоки пам’яті трапляються, коли програмі не вдається звільнити пам’ять, якщо вона більше не потрібна. Для всіх настроювань і компонентів коду у формі слід виконати наведені нижче дії.

  • Ретельно продумайте й протестуйте сценарії всього, що відповідає за очищення пам’яті, як-от класи, відповідальні за керування життєвим циклом об’єктів.
  • Очистіть усіх прослуховувачів подій і підписки, особливо якщо вони стосуються об’єкта window.
  • Очистіть усі таймери, як-от setInterval.
  • Скасуйте, обмежте та очистіть посилання на глобальні або статичні об’єкти.

Для настроюваних компонентів керування очищення можна виконати за допомогою методу знищення.

Щоб отримати додаткові відомості про виправлення проблем пам’яті, перейдіть до документації для розробників Edge.

Засоби, які допомагають підвищити продуктивність програм

У цьому розділі описано засоби, які допоможуть розібратися з проблемами продуктивності, та пропоную рекомендації щодо оптимізації налаштувань у модельних програмах.

Аналітичні огляди ефективності

Аналітичні огляди продуктивності — це інструмент для самостійного використання для розробників корпоративних програм, який аналізує дані телеметрії середовища виконання та надає пріоритетний список рекомендацій, які допомагають підвищити продуктивність модельних програм. Ця функція надає щоденний набір аналітичних оглядів, пов’язаних з ефективністю модельної програми Power Apps або програмою для взаємодії з клієнтами, як-от Dynamics 365 Sales або Dynamics 365 Service, а також рекомендації та елементи для виконання. Розробники корпоративних програм можуть переглядати докладні аналітичні огляди продуктивності на рівні програми в Power Apps. Додаткові відомості: Що таке аналітичні огляди продуктивності? (підготовча версія)

Перевірка рішень

Засіб перевірки рішень — це потужний засіб, який може аналізувати налаштування клієнтів і серверів на наявність помилок продуктивності та надійності. Він може аналізувати JavaScript на стороні клієнта, XML-код форми та компоненти plug-in .NET на стороні сервера та надавати цільові аналітичні огляди про те, що може сповільнювати роботу кінцевих користувачів. Засіб перевірки рішень рекомендовано запускати щоразу під час публікації змін у середовищі розробки, щоб усі проблеми продуктивності було видно перш, ніж вони будуть опубліковані для кінцевих користувачів. Більше відомостей: Використання перевірки рішень для перевірки ваших програм на основі моделі в Power Apps

Деякі приклади проблем із продуктивністю, виявлених за допомогою засобу перевірки рішень:

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

Засіб перевірки об’єктів

Засіб перевірки об'єктів виконує діагностику об'єктів компонентів у рішенні в режимі реального часу. Якщо знаходяться проблеми, надаються рекомендації із відповідними способами усунення. Додаткові відомості: Використання засобу перевірки об’єктів для діагностики компонента рішення (підготовча версія)

Наступні кроки

Розробка ефективних основних форм у модельних програмах