【问题标题】:Why do inline scripts block rendering when put at the bottom of a page?为什么将内联脚本放在页面底部时会阻止渲染?
【发布时间】:2013-08-20 00:29:35
【问题描述】:

我阅读了High Performance Web Sites: Essential Knowledge for Front-End Engineers,其中作者建议应将所有 JavaScript 代码外部化并放在页面底部而不是放在头部。

这在this example 中有说明。 external 脚本标记会阻止页面的下载渐进式呈现,因此解决方案是将其放在页面底部。

然而,在他的第二本书Even Faster Web Sites: Performance Best Practices for Web Developers 中,他谈到了内联 JavaScript 标签。

内联脚本还会阻止页面的下载和呈现,因此他建议将它们也移到页面底部。但是,此行为仍会完全阻止页面的呈现,如 this example 所示

为什么将外部脚本移动到页面底部可以让页面逐步呈现,而移动内联脚本会完全阻止呈现,直到脚本执行?


PS:

问题不在于为什么要将 JavaScript 添加到页面底部而不是放在头部。这就是为什么底部内联脚本会阻止渲染而底部外部脚本不会。

【问题讨论】:

    标签: javascript html performance browser rendering


    【解决方案1】:

    在内联脚本中,运行脚本会占用时间,这可能会改变 DOM。试图在 DOM 发生变异时渲染它会造成混乱。所以渲染只发生在 JS 停止的时候,因此 DOM 是稳定的。

    在等待外部脚本下载时,脚本的运行会停止,因此可以安全地渲染 DOM。下载的 JS 在渲染完成之前不会运行。

    【讨论】:

    • 很有趣,所以如果我有一个外部脚本,然后是一个内联脚本,并且两者都放在正文的底部,那么内联脚本将等待外部脚本首先下载并执行。这样在两个脚本都执行之前页面不会呈现,对吗?
    • 没有。浏览器在等待外部脚本下载时可能会渲染 DOM。到那时,它甚至(逻辑上)都不会意识到标记中存在内联脚本,因为解析器还没有到达它。请注意,外部脚本可能包含一个 document.write() 调用,该调用可能会阻止内联脚本被解释为脚本。
    • 我测试了你所说的,这是真的,但以防外部文件没有被缓存。页面渲染并且在我第一次打开它时没有等待内联脚本,但是在后续请求中,外部文件已经被缓存,因此渲染停止,直到内联脚本完成。顺便说一句,我正在使用自定义内联脚本,需要 6 分钟才能完成测试。
    • 我很确定,如果您将脚本标签动态添加到页面,IE(而不是 chrome)会执行异步操作,这与您在 head 标签中加载脚本标签时的行为相反,很明显。
    猜你喜欢
    • 1970-01-01
    • 2021-02-23
    • 2021-05-08
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多