Разработка форм для повышения производительности в приложениях на основе моделей

Создание интерфейса, позволяющего быстро и эффективно выполнять задачи, имеет решающее значение для удовлетворения пользователей. Приложения на основе модели можно настраивать для создания интерфейсов, соответствующего потребностям ваших пользователей, но важно знать, как эффективно кодировать, собирать и запускать приложения на основе модели, которые быстро загружаются, когда пользователь открывает ваше приложение и перемещается по нему при работе над повседневными задачами. Было показано, что производительность является ключевым фактором неудовлетворенности приложением, когда оно не оптимизировано для производительности.

Интеллектуальные настройки и эффективные формы являются важными аспектами создания высокоэффективных и продуктивных форм. Также важно убедиться, что вы создаете высокопроизводительные формы с использованием лучших практик в дизайне и макете пользовательского интерфейса. Для получения информации о разработке форм для повышения эффективности и производительности см. раздел Разработка продуктивных основных форм в приложениях на основе моделей.

Также важно убедиться, что пользователи используют рекомендованные и поддерживаемые устройства и имеют минимальные требуемые характеристики. Дополнительные сведения: Поддерживаемые браузеры и мобильные устройства

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

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

Важность вкладки по умолчанию

Вкладка по умолчанию — это первая развернутая вкладка в форме. Он играет особую роль при загрузке страницы формы. Как предусмотрено разработкой, элементы управления вкладки по умолчанию всегда отображаются при открытии записи. В частности, логика инициализации элемента управления, такая как извлечение данных, вызывается для каждого элемента управления на вкладке.

Напротив, дополнительная вкладка не выполняет эту инициализацию своих элементов управления при первоначальной загрузке формы. Вместо этого инициализация элемента управления происходит во время открытия дополнительной вкладки либо посредством взаимодействия с пользователем, либо путем вызова метода setFocus клиентского API. Это дает возможность защитить первоначальную загрузку формы от чрезмерной обработки элементов управления, поместив определенные элементы управления на дополнительные вкладки вместо вкладки по умолчанию. Таким образом, стратегия размещения элементов управления может существенно повлиять на скорость отклика начальной загрузки формы. Более отзывчивая вкладка по умолчанию обеспечивает лучший общий опыт для изменения важных полей, взаимодействия с панелью команд и изучения других вкладок и разделов.

Всегда помещайте наиболее часто используемые элементы управления вверху вкладки по умолчанию. Макет и информационная архитектура важны не только для производительности, но и для повышения производительности при взаимодействии пользователей с данными в форме. Больше информации: Разработка продуктивных основных форм в приложениях на основе моделей

Элементы управления на основе данных

Элементы управления, требующие дополнительных данных помимо основной записи, создают наибольшую нагрузку на отзывчивость формы и скорость загрузки. Эти элементы управления извлекают данные по сети и часто включают период ожидания (который виден как индикаторы выполнения), поскольку для передачи данных может потребоваться время.

Некоторые из элементов управления на основе данных включают в себя:

Оставьте на вкладке по умолчанию только наиболее часто используемые из этих элементов управления. Остальные элементы управления на основе данных следует распределить по дополнительным вкладкам, чтобы вкладка по умолчанию загружалась быстро. Кроме того, эта стратегия компоновки снижает вероятность получения данных, которые в конечном итоге не используются.

Существуют и другие элементы управления, которые менее эффективны, чем элементы управления, управляемые данными, но все же могут участвовать в указанной выше стратегии макета для достижения максимальной производительности. Эти элементы управления включают:

Веб-браузер

В этом разделе описаны передовые методы работы с веб-браузерами.

Не открывайте новые окна

Метод openForm клиентского API предоставляет параметр для отображения формы в новом окне. Не используйте этот параметр или устанавливайте для него значение 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.

Загружайте код только тогда, когда это необходимо

Загрузите столько кода, сколько необходимо для событий определенной формы. Если у вас есть код, предназначенный только для формы А и формы B, его не следует включать в библиотеку, загружаемую для формы C. Он должен быть в собственной библиотеке.

Избегайте загрузки библиотек в событии OnLoad, если они используются только для событий OnChange или OnSave. Вместо этого загрузите их при наступлении этих событий. Таким образом, платформа может отложить их загрузку до тех пор, пока не загрузится форма. Больше информации: Оптимизация производительности формы

Убрать использование консольных API в производственном коде

Не используйте методы консольного API, такие как console.log, в производственном коде. Ведение журнала данных в консоли может значительно увеличить потребность в памяти и помешать очистке данных в памяти. Это может привести к замедлению работы приложения со временем и, в конечном итоге, к сбою.

Избегайте утечек памяти

Утечки памяти в вашем коде могут со временем привести к снижению производительности и, в конечном итоге, к сбою вашего приложения. Утечки памяти происходят, когда приложение не может освободить память, когда она больше не нужна. Со всеми настройками и компонентами кода в вашей форме вы должны:

  • Тщательно продумайте и протестируйте сценарии для всего, что отвечает за очистку памяти, например, для классов, отвечающих за управление жизненным циклом объектов.
  • Очистите все прослушиватели событий и подписки, особенно если они в объекте window.
  • Очистите все таймеры, такие как setInterval.
  • Избегайте, ограничивайте и очищайте ссылки на глобальные или статические объекты.

Для пользовательских компонентов управления очистку можно выполнить в методе разрушить.

Дополнительные сведения об устранении проблем с памятью см. в этой документации разработчика Microsoft Edge.

Инструменты, которые можно использовать для повышения производительности приложений

В этом разделе описываются инструменты, которые могут помочь вам понять проблемы с производительностью, и предлагаются рекомендации по оптимизации ваших настроек в приложениях на основе модели.

Анализ производительности

Анализ производительности — это инструмент самообслуживания для создателей корпоративных приложений, который анализирует данные телеметрии во время выполнения и предоставляет список рекомендаций по приоритетам, которые помогают повысить производительность приложений на основе моделей. Эта функция предоставляет ежедневный набор аналитических сведений, связанных с производительностью приложения на основе модели Power Apps или взаимодействия с клиентами, такого как Dynamics 365 Sales или Dynamics 365 Service, с рекомендациями и вариантами действий. Создатели корпоративных приложений могут просматривать подробную информацию о производительности на уровне приложения в Power Apps. Больше информации: Что такое анализ производительности? (предварительная версия)

Проверка решения

Средство проверки решений — это мощный инструмент, который может анализировать настройки клиента и сервера на предмет проблем с производительностью или надежностью. Он может анализировать клиентский JavaScript, код XML в формах и серверные подключаемые модули .NET и давать целевую информацию о том, что может замедлить работу конечных пользователей. Мы рекомендуем запускать проверку решений каждый раз, когда вы публикуете изменения в среде разработки, чтобы любые проблемы с производительностью обнаруживались до того, как они возникнут у конечных пользователей. Дополнительные сведения: Использование средства проверки решений для проверки приложений на основе модели в Power Apps

Некоторые примеры проблем, связанных с производительностью, обнаруживаемых с помощью средства проверки решений:

Проверка объекта

Средство проверки объектов выполняет диагностику в реальном времени объектов компонентов в вашем решении. При обнаружении проблем возвращается рекомендация, в которой описывается, как решить проблему. Больше информации: Использование средства проверки объектов для диагностики компонента решения (предварительная версия)

Следующие шаги

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