如果你在控制台看到了以下信息,那么这篇文章对你而言应该会有帮忙:
(index):34 A Parser-blocking, cross-origin script,https://paul.kinlan.me/ad-inject.js, is invoked via document.write().This may be blocked by the browser if the device has poor network connectivity.
对于当初的web的开发者而言,document.write
应该是入门级的DOM API,但理论我的项目开发中,却很少应用。如果面试官问你为什么不去应用它,你会怎么答复?
很多人可能会说这个性能低,那么为什么低呢?先看个例子:
document.write('<script src="https://paul.kinlan.me/ad-inject.js"></script>');
在浏览器渲染页面之前,会去依据HTML标签解析DOM树。如果解析器遇到了 <script>
标签,则会进行DOM的解析,优先执行脚本。如果这个脚本动静插入了另一个脚本,则解析器会期待另一个脚本下载实现到执行实现,延后了页面渲染的工夫。
对于网络环境差的,比方 2G
的用户,通过 document.write
写入的新的脚本,可能会导致页面渲染的工夫延后数十秒,用户可能就因而放弃了持续期待。基于Chrome的数据报告显示,那些通过 document.write
插入第三方脚本的页面在2G网络下比个别页面慢2倍。
Chrome从55版本开始就开始选择性的干涉这类写法,当同时满足以下条件的时候,会禁止脚本执行:
- 用户处于低速网络下,比方2G(今后可能会把该条件扩大成3G以及低速wifi)
document.write
位于最高层级的document上(如果位于iframe中,因为不会阻止主页面渲染,所以不会干涉)document.write
中的脚本是解析阻塞型的(如果带了async
或者defer
属性,则不会干涉)- 脚本与页面不在同一个站点下,Chrome不会干涉eTLD+1级别的脚本,如: js.example.com 和 www.example.com
- 脚本不在HTTP Cache中,如果在缓存中,仍然会执行,因为不会收回HTTP申请
- 页面的申请不是重载。如果用户手动从新重载,Chrome还是会执行脚本
个别第三方库会用这种写法来加载脚本,不过庆幸的是,大部分第三方库都反对async加载,这样就不会阻塞残余内容的展示了。
如何修复这类问题?
禁用 document.write
插入新的脚本即可,没有比这更好的计划,如果必须应用,则加上 async
属性。
当你的站点受影响之后,如何检测?
有6条之多的规定须要查看,对你来说可能太过简单,有没有更好的办法去检测?
检测用户是不是2G网络
想要晓得多少用户受影响,只须要看看多少用户是2G网络,能够应用 Network Information API 来检测,而后将检测后果发到统计零碎或者RUM收集零碎:
if(navigator.connection && navigator.connection.type === 'cellular' && navigator.connection.downlinkMax <= 0.115) { // Notify your service to indicate that you might be affected by this restriction.}
捕捉开发者工具中的提醒
如果在应用 document.write
的时候,只满足了2-5的条件,你会看到上面这种提醒:
在开发者工具中看到这个你能够立即发现问题,但怎么去检测这个影响范畴有多广呢?你能够检测发往你服务器申请的HTTP Headers
你可能会尝试着模仿2G网络来强制干涉,但其实没必要,能够间接开启这项性能,应用 chrome://flags/#disallow-doc-written-script-loads
查看你的资源申请的HTTP headers
如果通过 document.write
的形式插入的脚本被阻止了,浏览器会携带这样的申请头去申请资源:
Intervention: <https://shorturl/relevant/spec>;
如果只是warning,会携带以下申请头:
Intervention: <https://shorturl/relevant/spec>; level="warning"
这些申请头会携带在对资源的GET申请中(在理论干涉的状况下异步申请)
总结
对于古代开发者而言是侥幸的,因为大部分第三方库的编写者曾经不再应用 document.write
的形式插入脚本了,我的项目开发中咱们只有略微留个心就好,一些远古的第三方库可能还会存在这样的问题。
参考
- https://developers.google.com...
- https://web.dev/no-document-w...
- https://developers.google.com...