今天有啥理由不使用 <script defer> 吗?
Posted
技术标签:
【中文标题】今天有啥理由不使用 <script defer> 吗?【英文标题】:Any good reason not to use <script defer> TODAY?今天有什么理由不使用 <script defer> 吗? 【发布时间】:2017-07-21 11:43:46 【问题描述】:曾几何时,<script>
在<head>
或<body>
上有很多激烈的争论。
许多 SO 帖子已经指出 最佳实践 / 经验法则 是将 <script>
放在 <body>
末尾之前,以免阻塞 html 解析器,从而为客户端带来更快的首屏绘制和更快的 DOM 访问,从而获得更好的用户体验。
这一定是重复的╰(‵□′)╯
等等……<script>
现在可以变成deferred
,实际上还有一段时间!
旧帖说
延迟脚本可能会导致 JS 依赖问题
不,不会。当 DOM 被解析时,它会立即保留执行顺序。
它不能跨供应商工作
是的,曾经是,但今天几乎所有主要浏览器供应商都支持它:http://caniuse.com/#search=defer,此外,正如 cmets 指出的那样,IE
然而,它提供的好处似乎是显而易见的,至少对我而言,因为它在更早的时间(在开始解析 DOM 之前)并行下载脚本,因此无需稍后请求脚本并缩短所需的时间带来整个页面互动。
简而言之,这个问题类似于:任何不使用的充分理由
<head>
...
<script src='cdn/to/jquery' defer>
<script src='cdn/to/bootstrap' defer>
<script src='script/depends/on/jqueryandbootstrap' defer>
</head>
改用这个:
<body>
...
<script src='cdn/to/jquery'>
<script src='cdn/to/bootstrap'>
<script src='script/depends/on/jqueryandbootstrap'>
</body>
注意:这可能是一个有很多讨论的“古老”话题。然而,随着 Web 技术的快速发展,浏览器供应商与新的 Web 规范更好地保持一致,许多旧的 *** 答案可能无法保持最新。
【问题讨论】:
caniuse 中有一条说明 IE defer 的好理由:p Here is some good reading. 和放在head
的头部没有defer
一样
我差点忘了这个(defer
) 魔法属性; This is an interesting article I found on Mozilla Hack
defer
是否会消除对 $(document).ready() 的需求?
【参考方案1】:
是的,但这只是因为您使用的是 jQuery。
jQuery doesn't work with defer
因为它会在页面变为交互式时尝试触发。他们不能很快修复它(我在一年前提出了这个错误),因为改变准备行为以使用defer
将破坏许多依赖 jQuery 的准备事件触发交互的组件(即在延迟脚本之前)加载完毕)。
如果您使用的是更现代的框架(React、Angular 2、Polymer、Vue 或其他任何东西),那么就选择它 - 或者甚至进入下一步并在新浏览器中使用 <script type=module
和IE 中 <script nomodule defer...
中的旧包。
【讨论】:
要明确的是,即使我在项目中使用 jQuery,也可以使用defer
加载任何其他 JS 库,我只是不能使用 defer
加载 jQuery 库。对吗?
@dmikester1 你可以推迟任何你想要的东西,但你不能依赖 jQuery 已经加载或加载的事件。 jQuery 和所依赖的一切都必须是同步的。不仅仅是 jQuery - 任何试图挂钩 DOM 加载事件的库都可能有问题,从那个时期开始,尝试在库中跳转 DOM 加载事件有一点趋势。
作为一个具体的例子,我在这里关注谷歌的地图 API 示例:developers.google.com/maps/documentation/javascript/tutorial 他们使用async
和defer
,他们还将脚本标签放在底部。现在是最佳做法吗?
@dmikester1 不,Google 的地图 API 实际上有点糟糕——它在 2009 年非常棒,但对已弃用的 IE6 等充满了黑客攻击。它不适用于 SPA 中的影子 DOM 和内存泄漏。最佳做法是 type=module
与 nomodule
后备,或使用动态导入。
@dmikester1 但是,您完全可以在带有 jQuery 的页面上使用它,并按照该示例进行操作,它将起作用。只是不在 SPA 中。【参考方案2】:
如here 所述,您应该考虑浏览器支持,因为其中一些并不真正支持它。在某些版本中也存在一些众所周知的错误,例如 IE 中的this one
如果您的目标不是支持旧浏览器(查找完整的支持列表 here),那么今天没有理由不选择 defer。
【讨论】:
以上是关于今天有啥理由不使用 <script defer> 吗?的主要内容,如果未能解决你的问题,请参考以下文章