»

大家尽量不要在网页中使用document.write()

    WordPress  
数据库网站优化wordpress缓存前端IIS查询Wp Super CacheWP Rocket伪静态爬虫防盗链CLB插件重定向浏览器htaccess腾讯云加速网络安全网站镜像web.config建站身份认证访客WordPress插件

网站采用了自适应模板,前一阵子开了 CDN,发现百度联盟的广告不能【自适应】移动端和 PC 端了(这点上谷歌的广告做得不错),很是烦恼。

出现这样的状况主要是 CDN 把动态网页变成了静态网页存储,导致后端的问题前端化,所以只能采用 js 代码判断用户浏览网页时使用的是移动端还是 PC 端。

因此,采用了 document.write() 函数 输出联盟代码,这样就不用担心 CDN 的问题了(参考我前一篇文章《利用Write()和userAgent解决自适应网站 CDN 后不能识别移动端的问题》)。看似问题解决了。但一个大问题随着谷歌 Chrome 的升级而凸显了:从 Chrome 53,也就是目前的稳定版开始,开发者工具的控制台中会出现下面这样的警告(即便脚本已经被缓存或者页面是通过刷新操作打开的,也会出现这个警告):

A Parser-blocking, cross site (i.e. different eTLD+1) script, http://pos.baidu.com/xxxxxxx, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message.See https://www.chromestatus.com/feature/5718547946799104 for more details.

从 Chrome 55 开始,除了上面的警告,这个被警告的脚本的 HTTP 请求会被添加一个额外的请求头,方便该脚本的维护者提前知道自己的脚本在未来会被屏蔽:

Intervention:<https://www.XXX.com/xxx/57145454954544>; level="warning"

打开控制台后看到这样的显示也很走心啊!

 

为什么会这样?

因为在 2G、3G 或速度比较慢的 wifi 环境中,使用 document.write() 动态加载资源会让页面的展现慢 10 秒以上。每当解析器遇到脚本时,它必须停止并执行它,然后才能继续解析 HTML。如果脚本动态地注入另一个脚本,解析器将被迫等待更长时间才能下载资源,这可能会导致一个或多个网络往返并延迟首次渲染页面的时间,导致页面无法加载或花费的时间长于用户放弃。通过第三方脚本插入的 document.write() 页面的速度通常比 2G 的其他页面载入速度慢两倍!

本文禁止住转载。任何形式转载请联系作者(时光在路上 www.timezls.com)。时光在路上保留所有权利

如果Chrome 把这些加载脚本拦截,可以改善网页打开速度:

  1. 页面加载到达first contentful paint (视觉上让用户感觉正在加载的状态) 的状态的数量增加 10%,达到完全解析状态的页面数量增加25%,减少 10% 由于需要刷新页面带来的用户失望;
  2. 到达first contentful paint的时间减少了21% (加快速度大于1秒);
  3. 解析页面所需的时间减少了 38%,差不多加快了 6秒,大大减少了向用户展示内容的时间。

 

针对以上的测试数据,Chrome 从 55版本开始,chrome 浏览器对用户使用的 document.write() 进行干预,如果符合以下所有的情况,页面 <script> 标签中的 document.write() 将不会被执行:

本文禁止住转载。任何形式转载请联系作者(时光在路上 www.timezls.com)。时光在路上保留所有权利

  • 用户处于缓慢的连接状态,特别是用户在 2G 时。(将来可能会延伸到慢速连接的其他用户,例如慢速 3G 或慢速 WiFi);
  • document.write() 在一个顶级的文件中,不适用于 iframe 中的 document.write 脚本,因为它们不会阻止主页面的呈现;
  • document.write() 中加载的脚本是会阻断解析的,如果脚本中有 async 或者是 defer 属性,那么它们还是会被解析执行;
  • document.write() 中加载的脚本和页面地址不是同个主域的,换句话说,chrome 浏览器不会阻止 script 标签符合 eTLD+1 规则的加载;
  • document.write() 中加载的脚本尚未在浏览器 HTTP 缓存中。缓存中的脚本不会导致网络延迟,并且仍然会执行。

 

如果还在使用 document.write() 函数加载代码的朋友,是不是该考虑修改一下了,毕竟速度变差影响用户体验!

时光在路上扫码阅读、分享
  • 版权声明:该文章由 时光在路上 发表,共 1796字。除非特别标注来源,否则为原创。详见《版权声明》部分。
  • 转载请注明:文章标题和文章链接 - 时光在路上 - 也可直接“复制本文链接” 或 使用右边二维码分享本文 →