Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript “延迟”没有更快地加载页面_Javascript_Deferred Loading - Fatal编程技术网

Javascript “延迟”没有更快地加载页面

Javascript “延迟”没有更快地加载页面,javascript,deferred-loading,Javascript,Deferred Loading,我试图用一个简单的例子来理解defer。我有下面的JS代码,需要5秒钟才能运行 home.js function wait(ms){ var start = new Date().getTime(); var end = start; while(end < start + ms) { end = new Date().getTime(); } } wait(5000); document.addEventListener("DOMCon

我试图用一个简单的例子来理解defer。我有下面的JS代码,需要5秒钟才能运行

home.js

function wait(ms){
    var start = new Date().getTime();
    var end = start;
    while(end < start + ms) {
      end = new Date().getTime();
   }

 }

 wait(5000);
document.addEventListener("DOMContentLoaded", function(event) {
    console.log("[4]: 'DOMContentLoaded' event fired!");
});

function wait(ms){
    console.log("[2]: 'wait' started!");
    var start = new Date().getTime();
    var end = start;
    while(end < start + ms) {
        end = new Date().getTime();
    }
    console.log("[3]: 'wait' finished!");
}

wait(5000);
函数等待(毫秒){
var start=new Date().getTime();
var结束=开始;
同时(结束<开始+毫秒){
end=新日期().getTime();
}
}
等待(5000);
我在home.html中使用它,如下所示:

<html>
    <head>
        <script defer src="home.js"></script>
    </head>
<body>
    <h1>Hello World!</h1>
</body>
</html>

你好,世界!

我发现如果使用defer或将我的脚本放在body标记的末尾(在我的理解中,两者都是等效的),helloworld只在5秒后出现。但是,如果我使用asnyc,“helloworld”会立即出现。这是为什么?

要回答您的直接问题,有关MDN的文档将有所帮助

推迟:

带有defer属性的脚本将阻止加载DOMContentLoaded 事件,直到脚本加载并完成计算

异步:

这是一个布尔属性,指示浏览器应 如果可能,异步加载脚本

异步脚本不会阻止触发DOMContentLoaded事件

有几种更好的方法可以使dom内容在延迟后显示,而不会像您现在这样阻塞UI线程;这是一种非常糟糕的做法

摘自:

同步JavaScript暂停对DOM的解析。如果你想要DOM 在用户请求 页面中,您可以使JavaScript异步

通常的做法是在加载文档后追加dom内容。您仍然可以在超时的情况下执行此操作,但通常附加的dom内容会在收到响应之后加载

以下是延迟后追加dom内容的示例:

函数等待(毫秒){
setTimeout(函数(){
var元素=document.createElement(“h1”)
element.innerText=“你好,世界!”
document.body.appendChild(元素)
},ms)
}
等待(5000)

让我们看看这个(打开调试控制台查看输出):

test.js

function wait(ms){
    var start = new Date().getTime();
    var end = start;
    while(end < start + ms) {
      end = new Date().getTime();
   }

 }

 wait(5000);
document.addEventListener("DOMContentLoaded", function(event) {
    console.log("[4]: 'DOMContentLoaded' event fired!");
});

function wait(ms){
    console.log("[2]: 'wait' started!");
    var start = new Date().getTime();
    var end = start;
    while(end < start + ms) {
        end = new Date().getTime();
    }
    console.log("[3]: 'wait' finished!");
}

wait(5000);
document.addEventListener(“DOMContentLoaded”),函数(事件){
log(“[4]:'DOMContentLoaded'事件已激发!”);
});
函数等待(毫秒){
log(“[2]:'wait'已启动!”);
var start=new Date().getTime();
var结束=开始;
同时(结束<开始+毫秒){
end=新日期().getTime();
}
log(“[3]:'wait'finished!”);
}
等待(5000);
test.html

<html>
    <head>
        <script defer src="test.js"></script>
    </head>
<body>
    <h1>Hello World!</h1>
    <script>console.log('[1]: DOM is parsed!')</script>
</body>
</html>

你好,世界!
console.log('[1]:已分析DOM!')
控制台日志:

[1]: DOM is parsed! [2]: 'wait' started! [3]: 'wait' finished! [4]: 'DOMContentLoaded' event fired! [1] :DOM已解析! [2] :“等等”开始了! [3] :“等等”完成了! [4] :“DOMContentLoaded”事件已激发! 现在,您可以看到以下步骤:

  • 加载并解析DOM
  • 运行
    wait
    函数(因为它是
    deferred
    函数,在解析DOM之后但触发事件之前运行)
  • “延迟”脚本已完成
  • 事件被触发(仅在所有
    defer
    脚本按照HTML中的顺序执行之后)
  • HTML已呈现,但仍可以加载样式表和图像等资源 DOM呈现时间在不同的浏览器和应用程序中可能不同 托管HTML文件的方式:在Chrome中(如我的测试所示),在
    http://
    的情况下,DOM是 在运行
    defer
    脚本之前渲染,但在
    文件的情况下://
    DOM在运行
    defer
    脚本并完成同步代码后呈现

    总结(来自评论中的问题):

    [1]: DOM is parsed! [2]: 'wait' started! [3]: 'wait' finished! [4]: 'DOMContentLoaded' event fired!
    • defer
      async
      脚本是异步加载的
    • defer
      脚本将按照它们在HTML中的放置顺序执行
    • defer
      脚本将在加载和解析DOM之后,但在启动之前执行
    • async
      脚本可以在任何时间加载并以任何顺序运行(最有可能的顺序是加载时的顺序)。如果在解析DOM之前加载了这样一个脚本,那么您不能期望该脚本能够在HTML中找到一些元素。此外,在这种情况下,浏览器不会等待加载并执行脚本来触发
      DOMContentLoaded
      事件

      • @Sergey的回答很好,但没有真正解释。4.12.1下的示意图显示,当指定了
        defer
        时,浏览器会等待脚本执行的开始,直到整个HTML被解析。关键是解析没有呈现。渲染与延迟脚本的执行同时开始,但在这种特殊情况下,脚本在重循环中阻塞。如果
        wait()。但当脚本完成时,仍将激发DOMContentLoaded

        函数等待(毫秒){
        返回新承诺((解析,拒绝)=>{setTimeout(()=>resolve(),ms)});
        }
        等待(3000),然后(()=>console.log('done')
        
        
        你好,世界!
        
        我不同意你的观察结论<代码>延迟
        不会使页面变慢,如以下动画所示。请注意,页面在不等待DOM内容加载事件的情况下开始呈现:

        因此,您可以自由使用
        延迟
        异步

        然而,看起来Chrome在执行JavaScript之前或之后开始绘制页面,这取决于页面是通过网络还是从文件系统加载的:

        网络:

        文件系统:

        虽然我不知道为什么Chrome会选择这样做,但我还是会傻笑