javascript - 如何避免 UI5 中的 "Synchronous XMLHttpRequest on the main thread"警告?

标签 javascript asynchronous async-await xmlhttprequest sapui5

我正在使用 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");
});

根据UI5 documentation :

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 检查加载并得到以下结果:

enter image description here

出于某种原因,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 调用的次数:

  1. 遵循记录的指南:

    特别是在引导时,使用 data-sap-ui-async="true" 选项,如果应用程序有 Component.jsuse the declarative sap/ui/core/ComponentSupport module in data-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.jsmanifest.json 同时避免内联脚本或单独的引导脚本。

  1. 使用 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 引用。大多数时候,它们要么被弃用,要么带有默认设置为 falseasync 标志。

仍然有一些 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.definesap.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.jsmanifest.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/

相关文章:

c# - Log4net LogicalThreadContext 未按预期工作

javascript - 订阅后对象内的数组未定义

java - 动态变量和异步

c# - 使用 async/await 设置 Thread.CurrentPrincipal

javascript - 价格滑动过滤器 - 隐藏父属性元素

ios - swift iOS : Closure will not run in background when Remote Notification received

c# - vstest.console.exe 的并行选项无法按预期工作

javascript - 当输入长字符串时,如何在输入中保留像 justify 这样的文本

javascript - Brightcove HTML5 Player 全屏事件

javascript - 显示部分图像(图像条中的子图像)而不压缩它?