Javascript 将脚本置于底部的两种不同方式-有什么区别?

Javascript 将脚本置于底部的两种不同方式-有什么区别?,javascript,html,asynchronous-javascript,Javascript,Html,Asynchronous Javascript,以下两种解决方案的区别是什么? 特别是,是否有充分的理由支持2胜过1。(注意:请假定要加载的脚本的名称是已知的。问题只是在给定情况下创建最小脚本来加载脚本是否有价值) 1-底部的脚本 <html> <body> ... ... <script src='myScript.js'></script> </body> </html> ... ... 2-底部的脚本加载外部脚本 <html> <body&g

以下两种解决方案的区别是什么? 特别是,是否有充分的理由支持2胜过1。(注意:请假定要加载的脚本的名称是已知的。问题只是在给定情况下创建最小脚本来加载脚本是否有价值)

1-底部的脚本

<html>
<body>
...
...
<script src='myScript.js'></script>
</body>
</html>

...
...
2-底部的脚本加载外部脚本

<html>
<body>
...
...
<script>
    // minimal script to load another script
    var script = document.createElement('script');
    script.src = 'myScript.js'
    document.body.appendChild(script);
</script>
</body>
</html>

...
...
//加载另一个脚本的最小脚本
var script=document.createElement('script');
script.src='myScript.js'
document.body.appendChild(脚本);

这两种初始化脚本的方法基本相同,但如果可以直接输入结果,则没有理由使用第二种方法。但是,您可以将第二个示例包装在一个
$(document).ready()
方法中,例如,这将导致某种延迟加载效果。这基本上意味着页面将首先加载,在页面加载完成后,它将加载脚本。当然,您也可以创建一个方法,以这种方式初始化某个脚本。当您有一个只在某些情况下使用的大型脚本时,它非常有用。这将阻止加载它,除非您需要它,从而减少总体加载时间。

第一种方法意味着脚本标记是硬编码的。第二种方法使用JavaScript将脚本标记动态添加到页面底部。第二种方法的好处是,如果需要修改脚本标记,可以添加额外的逻辑。也许您需要根据区域性、浏览器或JavaScript中可以确定的其他因素加载不同的脚本文件。第二种方法还会导致加载JavaScript文件,而不会阻止加载web页面的其余部分。在方法一中,当页面到达脚本标记时,页面将停止加载,加载JavaScript文件,然后完成页面其余部分的加载。因为这个标签位于页面底部,所以没有太大区别


如果您使用JavaScript创建Windows应用商店应用程序,则建议使用第一种方法,因为这将允许应用程序以字节码缓存JavaScript文件,从而加快加载速度。

第二种方法的一个重要功能是允许浏览器立即完成页面解析,无需等待脚本加载。这是因为第一个示例允许脚本使用
document.write
来更改
标记周围的解析状态,而第二个示例则不允许

现在,我们知道它位于页面底部,因此没有任何重要的内容需要解析,但这仍然是一个重要的区别。直到解析完成,浏览器才会触发流行的
DOMContentLoaded
事件。在方法1中,事件在脚本加载并执行后激发。在方法2中,事件在脚本开始加载之前激发

这里有一些例子。在这些演示中,一个
DOMContentLoaded
侦听器将背景颜色更改为黄色。我们尝试加载一个需要3秒钟加载的脚本

  • (编辑:也许JSFIDLE不是这些演示的最佳宿主。在加载缓慢的脚本之前,它不会显示结果。请确保在加载后再次单击“运行”,以查看发生了什么。)


    选择最适合您的应用程序的方法。如果您知道需要在加载
    DOMContentLoaded
    之前运行脚本,请使用方法1。否则,方法2在大多数情况下都很好。

    这并不是对您的问题的直接回答,但不管怎样,最好知道

    第二种方法有时用作库回退
    例如,从GoogleCDN加载jQuery。但是,如果由于任何原因失败,请从您自己的本地副本加载jQuery

    下面是流行的HTML5样板文件如何建议这样做:

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
        <script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.0.min.js"><\/script>')</script>
    
    
    window.jQuery | | document.write(“”)
    
    1。底部的脚本

    <html>
    <body>
    ...
    ...
    <script src='myScript.js'></script>
    </body>
    </html>
    
    使用“同步”脚本标记时,它将阻止浏览器呈现页面,直到加载并执行脚本。此方法具有以下效果:

    • 无论将脚本标记放在何处,浏览器都无法启动,直到下载并执行脚本

    • 在底部放置这样的脚本标记只能确保浏览器在被脚本阻止之前呈现了所有内容

    2。底部的脚本加载外部脚本

    <html>
    <body>
    ...
    ...
    <script>
        // minimal script to load another script
        var script = document.createElement('script');
        script.src = 'myScript.js'
        document.body.appendChild(script);
    </script>
    </body>
    </html>
    
    当您使用JavaScript注入脚本标记时,它将创建一个不会阻塞浏览器的“异步”脚本标记。此方法具有以下效果:

    • 无论您将生成脚本标记的JavaScript代码放在何处,浏览器都会在它可用时立即执行它,而不会阻塞页面。装载的DOMContentLoaded在应该的时候开火;无论脚本是否已下载/执行
    第二种方法具有以下优点:

    • 注入脚本标记的脚本可以放在任何地方,包括文档头
    • 脚本不会阻止渲染
    • DOMContentLoaded事件不等待脚本
    第二种方法有以下缺点:

    • 您不能使用
      文档。请在此类脚本中编写
      。如果这样做,这样的语句可能会清除文档
    • 异步执行并不意味着浏览器已完成对页面的解析。记住脚本一可用就立即执行
    • 不保证执行顺序。示例:如果使用注入的脚本标记加载“library.js”和“use library.js”,则“use library.js”可能在“library.js”之前加载和执行