gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1384
阅读:3117回复:1

【js基础】替代document.write()

楼主#
更多 发布于:2022-12-01 10:53
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>js赋值</title>
</head>
<body>
 
<script type="text/javascript">
  //直接输出:
  //document.write('不惧风雪,我中华儿女流血不流泪。');
  //改为:
 window.onload = function () {
   document.getElementById("ctinfo").innerHTML = "不惧风雪,我中华儿女流血不流泪。";

 }
</script>
 
<span id="ctinfo"></span>
<!--
如果没有:<span id="ctinfo"></span>
或设计不合理,
会报:Uncaught TypeError: Cannot set properties of null (setting ‘innerHTML‘)
-->
</body>
</html>
gogogo
管理员
管理员
  • UID25
  • 粉丝0
  • 关注0
  • 发帖数1384
沙发#
发布于:2022-12-01 11:08

为什么要避免使用document.write,尤其是脚本注入


Web 性能测试工具比如 Google Page Speed 或者 Dareboost 已经指出:使用 document.write 注入一段脚本会引起严重的网站加载耗时问题。让我们再次讨论这个话题,因为 Chrome 的下次更新将不再允许这样的脚本注入方式。你将面临什么问题?有什么替代方案?


Chrome 将不再执行通过 document.write 注入的脚本

9月初 Paul Kinlan 在 developers.google.com 网站 上宣布:Chrome 将很快干预 document.write 指令,并因此禁止通过该指令注入脚本。确实,随着 Chrome 54 的发布,这个改变会在10月中旬发生。相关网站在 Chrome 53 的开发者控制台可以看到一些警告。
确切的说是哪种阻塞?
幸运的是,对大部分网站来说,阻塞的情况是非常有限的,只有在同时满足以下条件时才会:
  • 用户的网络连接非常糟糕,
  • 脚本是阻塞解析器的(既没有 async 也没有 defer 属性)并且不在浏览器缓存里,
  • 该指令被加在顶级的 document 里(也就是说 iframe 不受影响),
如果这些条件全都满足,脚本压根就不会被加载。因此如果你的网页集成了第三方服务,要注意。即使你自己不使用该指令,你的网站可能会有这样的依赖,导致部分用户很快无法使用。
即使这个变化会导致一些网站不能运行,Chrome 的策略却很有意思,它是为了排挤(非常)不好的实践。正如以下列出的,document.write 确实会带来严重的性能问题。


document.write 引发的问题

当你用下面的 JavaScript 命令注入一段脚本时:

document.write('<script src="https://example.com/script.js"></script>');

浏览器无法继续解析HTML。web 浏览器被强制等待资源加载后才执行。情况可能会变得更糟,因为如果第一段脚本还注入其他脚本的话,浏览器会停止工作!考虑到你在网页里可能用到的所有第三方服务, 这种情况并不罕见。作为证明,在这次的更新通知中 Chrome 公布了他们自己的测试结果:7.6% 的网页与此相关!
顺便提一下,我们也可以了解到 document.write 指令是多么厉害的性能杀手。我们来看看 Chrome 的测试结果,其中 1% 的用户使用的是 2G 网络: 解析页面的平均时间减少了 38%, 近 6 秒的优势!
使用 document.write 的另外一个问题(不仅仅是注入的脚本的案例):如果 DOM 已经创建好了,使用 document.write 会强制浏览器再创建一次…… 可惜了性能!(document.write 会写入文档流,在已经加载完毕的文档里调用 document.write 会重置当前的文档。)


如何避免 document.write

通常来说,你应该避免使用阻塞的 JavaScript。“Defer” 和 “async” 属性会让你异步地调用外部脚本。然而要小心脚本的执行顺序,因为在异步加载的情况下不能保证它们的顺序!
如果 document.write 涉及到第三方服务,你需要看看你的提供商是否能提供异步加载的版本。如果没有,考虑替代方案。
最后,为了在网页里插入内容,考虑使用 DOM 操作而不是 document.write。这里有个脚本示例:

_
var sNew = document.createElement("script");
sNew.async = true; sNew.src = "https://example.com/script.min.js";
var s0 = document.getElementsByTagName('script')[0];
 s0.parentNode.insertBefore(sNew, s0);
_

结论是,请注意,根据这次更新,我们的 网站测试工具 很快会加大对使用 document.write 的处罚,特别是对移动端环境下的分析结果。
游客


返回顶部