#javascript #xmlhttprequest #sapui5
#javascript #xmlhttprequest #sapui5
Вопрос:
Я создаю пользовательское приложение SAPUI5, которое состоит из семи диаграмм ( sap.viz.ui5.controls.VizFrame
) в содержимом заголовка страницы (вложенных внутри sap.suite.ui.commons.ChartContainer
) и таблицы сетки ( sap.ui.table.Table
) в основной области содержимого. Данные для диаграмм и таблицы предоставляются службой OData V2, и приложение работает автономно в последней версии (1.81.0).
Проблема заключается в длительном времени загрузки приложения. Это занимает от 7 до 20 секунд. Является ли это обычным для «более сложного» приложения? Я пытался найти узкое место, но все выглядит нормально. Многие сетевые запросы кэшируются (они занимают 0 мс), однако между ними есть небольшая задержка, и я не понимаю, почему. Кроме того, в консоли отображается следующее предупреждение, хотя я использую data-sap-async="true"
в своем index.html
файле:
[Устаревание] Синхронный запрос XMLHttpRequest в основном потоке устарел из-за его пагубных последствий для работы конечного пользователя. Для получения дополнительной помощи проверьте https://xhr.spec.whatwg.org /. [syncXHRFix-dbg.js:211:15]
Фрагменты кода моего index.html и manifest.json
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Loading - Customer Fact Sheet</title>
<script id="sap-ui-bootstrap"
src="resources/sap-ui-core.js"
data-sap-ui-theme="sap_fiori_3"
data-sap-ui-resourceroots='{"com.schott.fiori.customerfactsheet.customerfactsheet-fiori3": "./"}'
data-sap-ui-compatVersion="edge"
data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"
data-sap-ui-async="true"
data-sap-ui-frameOptions="trusted">
</script>
<link href="https://www.schott.com/static/assets/gfx/favicon/SCHOTT_16.png" rel="shortcut icon" type="image/png" />
</head>
<body class="sapUiBody">
<div data-sap-ui-component data-name="com.schott.fiori.customerfactsheet.customerfactsheet-fiori3" data-id="container" data-settings='{"id" : "customerfactsheet-fiori3"}'></div>
</body>
</html>
{
"_version": "1.12.0",
"sap.app": {
"id": "com.schott.fiori.customerfactsheet.customerfactsheet-fiori3",
"type": "application",
"i18n": "i18n/i18n.properties",
"applicationVersion": {
"version": "1.0.0"
},
"title": "{{appTitle}}",
"description": "{{appDescription}}",
"sourceTemplate": {
"id": "servicecatalog.connectivityComponentForManifest",
"version": "0.0.0"
},
"dataSources": {
"YODATA_SD_CFS_MATRIX_SRV": {
"uri": "/sap/opu/odata/sap/YODATA_SD_CFS_MATRIX_SRV/",
"type": "OData",
"settings": {
"localUri": "localService/metadata.xml"
}
}
}
},
"sap.ui": {
"technology": "UI5",
"icons": {
"icon": "",
"favIcon": "",
"phone": "",
"phone@2": "",
"tablet": "",
"tablet@2": ""
},
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": true
}
},
"sap.ui5": {
"flexEnabled": false,
"rootView": {
"viewName": "com.schott.fiori.customerfactsheet.customerfactsheet-fiori3.view.Main",
"type": "XML",
"async": true,
"id": "Main"
},
"dependencies": {
"minUI5Version": "1.65.6",
"libs": {
"sap.ui.layout": {},
"sap.ui.core": {},
"sap.m": {}
}
},
"contentDensities": {
"compact": true,
"cozy": false
},
"models": {
"i18n": {
"type": "sap.ui.model.resource.ResourceModel",
"settings": {
"bundleName": "com.schott.fiori.customerfactsheet.customerfactsheet-fiori3.i18n.i18n"
}
},
"": {
"type": "sap.ui.model.odata.v2.ODataModel",
"settings": {
"defaultOperationMode": "Client",
"defaultBindingMode": "OneWay",
"defaultCountMode": "Request"
},
"dataSource": "YODATA_SD_CFS_MATRIX_SRV",
"preload": true
}
},
"resources": {
"css": [{
"uri": "css/style.css"
}]
},
"routing": {
"config": {
"routerClass": "sap.m.routing.Router",
"viewType": "XML",
"async": true,
"viewPath": "com.schott.fiori.customerfactsheet.customerfactsheet-fiori3.view",
"controlAggregation": "pages",
"controlId": "app",
"clearControlAggregation": false
},
"routes": [{
"name": "RouteMain",
"pattern": "RouteMain",
"target": ["TargetMain"]
}],
"targets": {
"TargetMain": {
"viewType": "XML",
"transition": "slide",
"clearControlAggregation": false,
"viewId": "Main",
"viewName": "Main"
}
}
}
},
"sap.platform.hcp": {
"uri": "webapp",
"_version": "1.1.0"
}
}
Скриншоты вкладки «Моя сеть»
Ответ №1:
Как видно на вкладке Сеть, существует множество модулей, загружающихся последовательно один за другим, и многие из них даже через sync XHR. Самая важная задача — максимально сократить временные интервалы синхронизации.
-
Я вижу в
manifest.json
, что объявлено только небольшое количество библиотек. Однако, согласно вкладке Сеть, приложение использует элементы управления из других библиотек, которые не объявлены вdependencies
.
Так и должно быть:"sap.ui5": { "dependencies": { "libs": { "sap.ui.core": {}, "sap.m": {}, "sap.ui.table": {}, "sap.f": {}, "sap.ui.unified": {}, "sap.ui.layout": {}, "sap.viz": {}, "sap.suite.ui.commons": {} },
Некоторые библиотеки требуются другим библиотекам транзитивно (например,
sap.ui.table
требуетсяsap.ui.unified
).src затем вы можете добавить"sap.ui.unified": { lazy: true }
, если эта библиотека не используется напрямую. -
Предварительно асинхронно загружайте сторонние модули, которые обычно загружаются через
loadSyncXHR
.Если вы проверите столбец Инициатор на вкладке Сеть, вы можете обнаружить больше модулей, которые загружаются через sync XHR. Добавление этих модулей в
data-sap-ui-modules
должно избежать этого:<script id="sap-ui-bootstrap" data-sap-ui-modules="sap/ui/thirdparty/datajs,sap/ui/thirdparty/require" ...>
sap/ui/thirdparty/datajs
Требуетсяv2.ODataModel
.sap/ui/thirdparty/require
Модуль отsap.viz
библиотеки. Оба модуля обычно извлекаются черезloadSyncXHR
. Приведенный выше фрагмент исправляет это. Возможно, вы найдете больше таких модулей.
В целом, вышеуказанные пункты уже должны заметно улучшить время начальной загрузки. Для получения дополнительных рекомендаций по производительности ознакомьтесь с контрольным списком производительности.
Другие вещи, которые следует учитывать
I18n
Чтобы уменьшить количество запросов, рассмотрите возможность полного отказа от поддержки i18n, если приложение предназначено только для определенной группы людей, говорящих на одном языке. Множественные запросы для текстовых пакетов i18n не только дорого обходятся по размеру, но и блокируют другие запросы во время загрузки, поскольку они также загружаются через sync XHRS по умолчанию. Есть способ загружать их асинхронно, а также указывать, какие локали поддерживает приложение, но это для другой темы.
Модель OData
Подумайте о том, чтобы установить режим подсчета на, None
если это не требуется, поскольку $count
вычисления, как правило, являются дорогостоящими в серверной части. Также режим работы Client
извлекает все объекты. Подумайте о том, чтобы вместо этого загружать их лениво.
Для всех привязок агрегации
"": {
"dataSource": "MyV2Source",
"settings": {
"defaultOperationMode": "Default",
"defaultCountMode": "None",
"defaultBindingMode": "TwoWay",
"preliminaryContext": true
},
"preload": true
},
О preliminaryContext
: смотрите раздел Оптимизация зависимых привязок.
Для одной привязки агрегации
items: { // e.g.
path: '/MySet',
parameters: {
countMode: 'None',
operationMode: 'Client' | 'Default' | 'Server' (see API ref)
}
}
Ссылка на API:https://openui5.hana.ondemand.com/api/sap.ui.model.odata.v2.ODataListBinding
Инструментарий UI5
Перед развертыванием приложения создание приложения с помощью следующей команды должно значительно уменьшить размер приложения:
ui5 build self-contained -a
От https://github.com/SAP/openui5-sample-app#option-2-self-contained-build
В настоящее время это применимо только к автономным приложениям.
Комментарии:
1. очень интересно, я лично никогда не рассматривал возможность исключения countMode для моих привязок агрегации.
2. Хороший подробный ответ, собираюсь добавить его в закладки для дальнейшего использования.