【问题标题】:Challenge in Asynchronous Javascript Loading异步 Javascript 加载中的挑战
【发布时间】:2011-05-11 03:48:15
【问题描述】:

背景:我正在开发基于 GWT 的应用程序,该应用程序部署在 Google App Engine 上。我的应用程序使用一个自定义库,它需要预先加载 6-7 个大核心 javascript 文件(总大小约为 3 MB)。因此,即使加载我的应用程序的主页,也需要 20-40 秒,具体取决于带宽。最近我开始着手解决页面加载缓慢的问题。

我制作了一个纯 HTML 主页,没有任何 GWT 或自定义库的组件。该主页包含一个登录按钮和一个简单的基于 jQuery 的图像滑块。我正在使用基于 Google 帐户的身份验证。在主页上,我使用此处介绍的“异步有序”Javascript 加载技术:http://stevesouders.com/efws/loadscript.php?t=1303979716 来加载所有核心 .js 文件。因此,当用户查看主页或与图像滑块交互时,.js 文件会在后台悄悄下载。用户登录后,控件被重定向到 Main HTML 文件,该文件从缓存中检索 .js 文件并加载应用程序。这次应用程序的加载速度明显更快。因此,主页在 2-5 秒内加载完毕,主应用程序也加载得非常快。

这正是我需要的。但是有一个问题。

问题:如果用户点击登录按钮太快(即在所有异步 .js 文件下载完成之前),异步下载会中断。事实上,一旦用户离开主页(到 Google 帐户登录页面或任何其他页面),所有异步下载都会中断。现在,当显示主应用程序时,它会从缓存中检索部分下载的 .js 文件并报告“Unexpected end of line”错误。

我可以做一件事来解决这个问题 - 禁用登录按钮,直到异步下载完成。这比目前的情况稍微好一点,因为它至少允许用户看到主页并与图像滑块进行交互。但这并不理想。

理想情况下,我正在寻找一种方法来检查主 HTML 中 .js 文件的哈希(或文件大小),以查看它们是否正确。如果不匹配,请重新下载文件。但我无论如何都不是 Javascript 专家,甚至不确定这是否可能。所以,我在这里寻求专家的帮助。这可能是人们以其他方式解决的常见问题。所以,我也对其他选择持开放态度。

谢谢。

更新:

  1. 我有多个 (6-7) .js 文件要加载。
  2. .js 文件是独立的,需要按特定顺序加载。

【问题讨论】:

  • 查看 labjs labjs.com 它可以帮助您更快地加载脚本。而且,您的脚本只是 1 个大文件吗?或多个文件
  • @lbu - 感谢您提供信息。快速提问 - 当用户离开页面时,labjs 会解决异步下载中断的问题吗?我要加载 6-7 个不同的 .js 文件,它们需要按特定顺序加载。

标签: java javascript gwt


【解决方案1】:

3MB 的 Javascript 文件非常疯狂。你真的需要那么多吗?如果是这样,您应该考虑使用 jsmin 或 uglifyjs 连接/缩小它们。这将减少至少 50% 的大小。接下来,确保在托管这些文件的服务器上启用 gzipping。这应该会再减少 50% 的大小。

最后,您应该使用 expires 标头来确保此文件永久缓存客户端。取消缓存更新 src 上的查询参数:

<script src="compressed.js?v=1"></script>

至于检查文件大小的哈希值,虽然您可以检查是否存在您的库正在引入全局命名空间的某些变量,但这并不完全可能。例如:

jQueryLoaded = !!window.jQuery;

【讨论】:

  • 感谢您的回复。实际上我不想命名我正在使用的库,但它对于 GWT 来说是一个非常流行的库。 AFAIK,那些 .js 文件已经被缩小了。 GAE 会自动为我进行 gzip 压缩。我将 expires 标头设置为 1 个月,但会考虑根据您的建议进行更改。所以,是的,我在某种程度上研究了这些方面。现在提出您检查变量是否存在的建议,我可以这样做。但是,如果该变量不存在,我将如何再次“强制下载”文件?谢谢。
  • 可能使用 require.js (requirejs.org) 或 yepnope (requirejs.org) 之类的东西。
【解决方案2】:

在这种情况下,考虑到我们要加载大约 3 MB 的 javascript,我将构建一个带有进度条的加载页面,用于下载所有 javascript,并在显示实际站点之前显示进度。这不会在很大程度上限制用户体验,而是让您有机会在加载时显示更新、新闻(甚至提要)、帮助消息。在加载页面上也有一个计时器,以检测它是否花费了太长时间,并在加载时间过长时为他们提供执行其他操作的选项,例如在下载脚本之前显示禁用登录的登录页面。我找到了执行此操作的脚本 herehere

【讨论】:

  • 这些都是非常好的建议,我相信我会在当前和未来的项目中找到它们的用途。但是对于当前的问题,我正在寻找一种不同的方法。允许我检查缓存中的文件(通过哈希、大小等)并查看它是否完整的东西。如果没有,请再次强制下载文件。谢谢。
【解决方案3】:

您实际上可以压缩、包含版本、缩小和捆绑 js 文件,这将占用空间减少了 80% 以上。看看Yahoo's Coding horror。您可以使用jawr 完成所有这些操作

【讨论】:

    最近更新 更多