如果在x时间之后没有到达document.ready,请刷新页面?

时间:2017-03-19 21:53:17

标签: javascript jquery css

我在远程客户端上远程运行一个网站作为显示板。有时当互联网非常糟糕时,永远不会达到初始页面加载,页面被部分加载(没有CSS,死图像等)

如果文档在几分钟内没有加载,是否有办法强制刷新或至少调用函数?一个处理这个问题的JavaScript函数作为第一件事加载,并且可能启动一个计时器并刷新如果文档就绪并没有在x秒内达到?

Chrome扩展程序可能是此选项。

1 个答案:

答案 0 :(得分:3)

如果问题是互联网真的很糟糕,刷新页面显然 不是一个好主意 ,因为当你刷新时互联网仍然会很糟糕你可能会只是丢失已经加载的少数元素,你将最终得到一个自我重置,永无止境的循环。

让我们分解页面加载时会发生什么:

    完全阅读
  • <head>,在javascript构建之前不执行CSSOM
  • CSSOM在读取/加载和解析所有CSS资源后构建
  • <body>被添加到DOM中,并行浏览器启动:
    • 按顺序执行javascript,从<head>中的脚本开始,然后是<body>中的脚本(如果有的话)
    • 阅读/构建DOM,排队所有外部资源以进行加载
  • 如果在任何时候遇到新的CSS资源(<style>代码),DOM构建停止,则会构建新的CSSOM,现有CSSOM已替换为新版本,已重新加入DOM的所有内容并重新启用DOM版本
  • DOM建筑物到达最终</body>标签时,document.ready被解雇
  • 当所有外部资源都已触发.load时,window.load被触发

鉴于上述情况,您有三个主要案例:

  • A。 .css中的一个或多个<head>资源无法解析。它们既不加载也不返回错误,它们只是停止(由于服务器或网络问题)。此行为会阻止任何javascript执行。
  • B。 CSSOM已构建,但出于各种原因DOM建筑物被中断/停止(通常由javascript错误或循环,严重的HTML验证错误(例如多个/嵌套的<body>标记等)导致DOM未完成。这可能会阻止document.ready触发,但所有javascript都会读取到错误被执行,因此您可以放置​​一个计时器并将其重置在document.ready上,如果在指定的时间窗口内没有被激活,则可以启动window.location.replace() - @nnnnnn在他的评论中提出的解决方案。
  • C。 一切都达到document.ready,但有些外部资源无法加载(媒体文件/脚本)。这里最好的方法是重新启动未加载的加载,而不会丢失已经加载的加载。这是possible solution - 未经测试。

从您的问题来看,我相信您会陷入 A 案例中。 B 可能会在您的控制台中丢失一些错误,并且很容易发现/修复。

对于 A 我正在考虑可能的黑客,但它很脏,至少乍一看。 我想你应该检查哪些样式表通常会停止加载并将它们放在<body>的开头而不是<head>内。
我知道。这将自动触发 “没办法!” 对任何认真的开发人员的反应,但让我们看看为什么不推荐它。这是因为你想不惜一切代价避免FOUC 这就是在<style>中放置<body>代码时通常会发生的情况。构建新的CSSOM,替换旧的FOUC,重新绘制现有内容(导致DOM)并恢复<style>构建。但是,如果在javascript个标记之前没有放置任何内容,则不应重新绘制任何内容,并且在加载有问题的样式表之前,您将从CSS执行中受益。

您将<body>资源加载到<style>@import url();</style>的准确性应该是另一个问题的主题,但这里有一些可能的方法:

  • <link> - 不确定其是否有效且可能无效跨浏览器
  • 使用<head>
  • javascript代码添加到<link>
  • 经过一些研究后,我找到了this article,记录了<head>javascript标记不再阻止呈现或<body>执行的以下技巧(是的,你)不再需要将它们放在<link rel="stylesheet" href="css.css" media="none" onload="if(media!='all')media='all'"> 中使用这个):
javascript

CSS当前阻止您的网页完成加载之前,您选择了哪种技术FOUC启动计时器并不是那么重要。我们的想法是允许脚本评估一段时间后加载的内容,并决定是否重新加载页面,或者仅重新启动未解析资源的加载过程。

您仍然会遇到opacity:0;,可能最好的方法是将<body>放在CSS上,直到所有javascript加载并通过{{1}将其淡入在window.load上。

关于重新加载解决方案本身,您应该使用

location.replace(location.href);

...避免在浏览器的历史记录中创建新条目。

我希望你能找到一些有用的东西。问候。