【问题标题】:Why use defer with Google Maps Javascript?为什么要在 Google Maps Javascript 中使用 defer?
【发布时间】:2016-08-22 21:44:06
【问题描述】:

Google Maps javascript 做了一些繁重的 DOM 操作。尽管如此,the fine docs 还是建议用defer 标志加载它:

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>

为什么要为执行 DOM 操作的脚本建议 defer 标志? 我要求同时了解 defer 标志和 Google Maps API,因为我似乎对其中一个人在做什么有误解。

【问题讨论】:

    标签: javascript google-maps deferred


    【解决方案1】:

    通常,script 标签告诉浏览器停止解析 HTML,获取脚本,运行它,然后才继续解析 HTML。这是因为脚本代码可能会使用document.write 输出到 HTML 令牌流。

    async and defer 是两种机制,用于告诉浏览器可以继续解析 HTML 并同时下载脚本文件,稍后运行脚本文件,而不是立即运行。

    不过,它们略有不同;这张来自 HTML 规范的 WHAT-WG 版本的the script section 的图表对于设想差异很有用:

    以上链接规范中的完整详细信息,但简而言之,“经典”脚本(您习惯的那种;但模块脚本即将推出!):

    • asyncdefer 都允许继续解析 HTML,而无需等待脚本下载。
    • defer 将使浏览器等待执行脚本,直到解析完成。
    • async 只会让浏览器等待脚本下载完成,这意味着它可能会在解析完成之前或之后运行脚本,具体取决于下载完成的时间(记住它可能来自缓存)。
    • 如果浏览器存在并支持async,则它优先于defer
    • async 脚本可以按任何顺序运行,无论它们在 HTML 中出现的顺序如何。
    • defer 脚本将按照它们在 HTML 中出现的顺序运行,一旦解析完成。
    • asyncdefer 在半现代浏览器中得到很好的支持,但在 IE9 和更早版本中没有得到适当支持,请参阅 herehere

    为什么要为执行 DOM 操作的脚本建议 defer 标志?

    两个原因:

    1. 它允许在下载脚本时继续解析,并且
    2. 这意味着脚本在解析完成之前不会运行。

    如果您没有使用defer 并且您将script 标签放置在非最佳位置,则使用defer 通过让浏览器在脚本尝试操作它之前完成构建DOM 有助于API 脚本正常运行。

    很多人仍然将script 标签放在文档的head 部分,尽管这通常是放置它们的最糟糕的地方除非你使用defer(或@987654351 @)。在大多数情况下,最好的位置(除非您有理由做其他事情)是在非常 end,就在结束 &lt;/body&gt; 标记之前,这样 A) 您的网站可以快速呈现,无需等待脚本; B) 在您尝试操作之前,DOM 已完全构建。推荐 defer 可能会为他们省去人们在 HTML 中过早放置 script 标记的麻烦。

    【讨论】:

    • 我想我明白了。因此,我阅读以了解 defer 和 async 属性的 the article 似乎完全错误,甚至与规范相矛盾。可惜排名如此之高highly on Google
    • @dotancohen:不,它是正确的,只是当它说“...不包含任何 document.write 或 DOM 修改讨厌:”时有点模糊。它应该说的是“...不包含任何旨在与解析器内联运行的 document.write 或 DOM 修改”。 (因为您可以做其他事情,而不仅仅是document.write,这将依赖于等待您的脚本运行的解析器)。它不应该给人的印象是所有 DOM 修改都不在讨论范围内。
    【解决方案2】:

    谷歌地图示例同时使用asyncdefer 标志。

    • async 标志允许脚本与 DOM 并行加载 解析,并在 API 准备好后立即执行。
    • defer 标志允许脚本与 DOM 并行加载 解析,但保证脚本不会执行,直到 DOM 解析完毕。

    现代 HTML5 浏览器支持async,而对defer 的支持是通用的。当标签一起使用时,defer 只是旧浏览器的后备,如果支持async,则会被忽略

    在这些简单的示例中,asyncdefer 都可以使用,但两者都不是必需的。在这种情况下,它只是为了性能。

    参考:
    Speed up Google Maps(and everything else) with async & defer
    async vs defer attributes - Growing with the Web

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多