动态加载 JavaScript 并监控下载进度

Posted

技术标签:

【中文标题】动态加载 JavaScript 并监控下载进度【英文标题】:Dynamically load JavaScript AND monitor download progress 【发布时间】:2015-11-22 19:38:11 【问题描述】:

高级视图:我正在使用 Emscripten 将各种遗留 C/C++ 代码库转换为优化的 javascript,以便基于浏览器的现代用户群可以轻松地使用它们的功能。到现在为止还挺好。然而,Emscripten 转译的 JS 可能有点笨重,即使在为网络交付压缩之后也是如此。

为了提高用户体验,我想在主页加载后下载这个巨大的 JS 块,并且我想监控下载进度以显示在页面 UI 中。我知道 2 种动态加载方法,但我都遇到了两种方法的缺点:

    第一种方法是创建脚本标签(嵌入在html页面中或由JS动态生成)。当文件下载并准备好运行时,onload 事件会触发。这种方法的问题是我找不到监控下载进度的方法。脚本对象确实有一个 onprogress 事件,但它似乎没有做任何事情(在 Chrome 中测试)。 使用 XMLHTTPRequest (XHR) 对象动态请求 JS 资源。这很好用并触发预期的下载进度事件。但是,对下载的数据运行 JS eval() 并没有正确的效果(预期的功能不会出现在 JS 命名空间中)。

执行eval() 的更简单的带有JS 的字符串有预期的结果,所以我想知道在Emscripten 编译的代码上运行eval() 是否有一些特殊的技巧。

相反,我实现了一个结合上述方法 1 和 2 的混合解决方案:XHR 执行初始加载并丢弃数据。然后,页面创建一个脚本元素来加载相同的 JS 文件,该文件现在位于浏览器的缓存中并立即加载。但这显然是一个 hack,我不禁认为必须有一个更清洁的解决方案。

【问题讨论】:

您可以使用第二种方法,但不是使用eval(),而是按照in this existing post 的说明将加载的文本作为脚本节点的内容。 【参考方案1】:

不要丢弃数据,而是将数据设置为脚本标签。

var xhr = new XMLHttpRequest;
var tag = document.createElement("script");
xhr.open("GET", "foo.js", true);
xhr.onload = function (e) 
  if (xhr.readyState === 4) 
    if (xhr.status === 200) 
      tag.text = xhr.response;
      document.head.appendChild(tag);
     else 
      alert("error");
      console.error(xhr.response);
    
  
;
xhr.onprogress = function (e) 
  Module.setStatus('Loading JavaScript: ' + (100 * e.loaded / + e.total) + '%');
;
xhr.send();

【讨论】:

有趣...对您何时可以执行此操作有任何限制吗?例如,CSP 是否将其视为eval Chrome、Firefox 和 Edge 将其视为内联脚本标签,因此需要 script-src 'unsafe-inline' 我终于有机会将它连接起来,效果很好。谢谢。赞成并接受。

以上是关于动态加载 JavaScript 并监控下载进度的主要内容,如果未能解决你的问题,请参考以下文章

ReactJS进度条使用状态动态更新?

关于js或jquery进度条实现?

JavaScript 从谷歌加载swfobject并动态嵌入

Canvas制作动态进度加载水球

Canvas制作动态进度加载水球

如何在js文件中动态加载另一个js文件?