我正在使用 index.js
中的以下引导启动我的 UI5:
sap.ui.define([
"sap/m/Shell",
"sap/ui/core/ComponentContainer"
], (Core, Shell, ComponentContainer) => {
"use strict";
new Shell("", {
app: new ComponentContainer("", {
height: "100%",
name: "webapp"
}),
appWidthLimited: false
}).placeAt("content");
});
Static dependencies are loaded in the dependency declaration array of the
sap.ui.define
call. These dependencies are always loaded in advance before executing the defined module.
我是否正确理解,在这种情况下,模块将始终以同步方式加载,并且没有真正的方法来避免«主线程上的同步 XMLHttpRequest» 警告? p>
也许我可以用 async
/await
包装 new sap.m.Shell(sId?, mSettings?)
吗?
更新#1:
我已经使用 ?sap-ui-xx-nosync=warn
检查加载并得到以下结果:
出于某种原因,i18n/i18n_en.properties
被同步加载。我访问 i18n
的唯一地方是:
const oBundle = myI18nModel.getResourceBundle();
但是按照文档,我无法理解为什么 myI18nModel.getResourceBundle()
会导致同步加载。
更新#2:
经过深入探索no sync XHR示例,我找到了 sync XHR
警告的原因。那是 manifest.json
中的 "description": "{{appDescription}}"
和 "title": "{{appTitle}}"
明确指出:
"title": "Here the i18n bundles can't be loaded with 'async: true' yet!",
"description": "Same here. Hence, no 'i18n' in this 'sap.app' section!"
将其替换为静态值后,警告消失。
最佳答案
UI5 的早期开发主要基于 synchronous XHRs .遗留应用程序或一些过时的文档主题可能仍然引用默认禁用异步选项或根本没有异步选项的 API,例如:sap.ui .controller
, sap.ui.component
, sap.ui.*fragment
, sap.ui.*view
, >jQuery.sap.require
, sap.ui.requireSync
, jQuery.sap.sjax
, ComponentContainer
的构造函数> 如问题中所述。
为了减少同步 XHR 调用的次数:
遵循记录的指南:
特别是在引导时,使用
data-sap-ui-async="true"
选项,如果应用程序有Component.js
,use the declarativesap/ui/core/ComponentSupport
module indata-sap-ui-oninit
而不是手动实例化sap.ui.core.ComponentContainer
。例如:<head> <!-- ... --> <script id="sap-ui-bootstrap" ... data-sap-ui-async="true" <strong>data-sap-ui-oninit="module:sap/ui/core/ComponentSupport"</strong> ></script> </head> <body id="content" class="sapUiBody"> <div data-sap-ui-component data-id="rootComponentContainer" data-name="demo" data-settings='{ "id": "rootComponent" }' ... ></div> </body>
这会自动创建一个
ComponentContainer
,将其推送到 DOM,并异步加载Component.js
和manifest.json
同时避免内联脚本或单独的引导脚本。
使用
xx-nosync
bootstrap option 运行应用程序.例如,在 URL 中:https://<host>/my/awesome/app/?<strong>sap-ui-xx-nosync=warn</strong>
然后 UI5 将在浏览器控制台中为同步获取的每个文件记录“正在加载...使用同步 XHR”(忽略其他 [nosync] 消息)。例如:
- 如果应用程序使用
v2.ODataModel
,它可能会提示模块sap/ui/thirdparty/datajs
是同步加载的。在这种情况下,将以下内容添加到 Bootstrap 配置中:<script id="sap-ui-bootstrap" ... data-sap-ui-async="true" data-sap-ui-oninit="module:sap/ui/core/ComponentSupport" <strong>data-sap-ui-modules="sap/ui/thirdparty/datajs"</strong> ></script>
- 如果
ResourceModel
在 JS 中手动创建,确保在那里启用async
标志:const i18nModel = new ResourceModel({ // required by "sap/ui/model/resource/ResourceModel" bundleName: "demo.i18n.i18n", supportedLocales: [""], fallbackLocale: "", <strong>async: true</strong>, // <-- }); i18nModel.getResourceBundle().then(resourceBundle => { this.getOwnerComponent().setModel(i18nModel, "i18n"); resourceBundle.getText(/*...*/); // See sap/base/i18n/ResourceBundle });
检查报告的 API 的 API 引用。大多数时候,它们要么被弃用,要么带有默认设置为
false
的async
标志。- 如果应用程序使用
仍然有一些 API 尚未没有异步替换,例如:
- CLDR file在实例化
sap/ui/core/LocaleData
时使用同步 XHR 获取(例如用于日历或 DatePicker。参见 Issue #2345)。 - 在解析
manifest.json
中的 i18n Handlebar-like"{{...}}"
语法时
不过,有了最新稳定版的UI5,大部分的同步请求都可以去掉了。
这是一个没有同步 XHR 的示例:https://embed.plnkr.co/7txzTsNwOBDbyi87
要回答这个问题:sap.ui.define
和 sap.ui.require
会异步加载依赖项 if data -sap-ui-async
配置设置为 true
(Replaces data-sap-ui-preload="async"
) .还要确保 add dependent libs to the manifest.json
以防止出现主要的性能瓶颈。
用 async-await
/Promise
包装一个同步内容请求很遗憾没有帮助。最好寻找异步替代方案。例如,ComponentContainer
在构造函数设置中有一个 async
标志,如果启用,它会异步获取 Component.js
和 manifest.json
文件:
new ComponentContainer({
height: "100%",
name: "webapp",
<strong>async: true, // or
manifest: true, // sets the `async` option automatically to true</strong>
})
关于javascript - 如何避免 UI5 中的 "Synchronous XMLHttpRequest on the main thread"警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64404429/