使用 Web Workers
背景
跳转到“背景”在一个浏览器进程中,JavaScript 代码的执行是单线程的,同一时刻内只能有一段代码在执行,所以我们必须对资源进行分类,立即必需的资源应该没有任何阻塞的执行。在主题中,它不仅需要加载主题自身的内容(组件JS资源、埋点等立即必需的资源),它还需要加载用户安装的插件、第三方脚本(非立即必需的资源)。
当非立即必需的脚本过多时,立即必需和非立即必需的脚本仅仅只能在同一个单线程内排队执行,这时会有一些非立即必需的脚本执行在立即必需脚本之前,这样会导致展示页面所必需的资源加载时间变长,页面性能以及用户体验变差,总阻塞时间(详情参考:TBT)指标数值变大。
为了提供良好的用户体验、改进 TBT 指标,需要减少 JavaScript 执行时间和第三方代码的影响以及最小化主要线程工作。因此,我们引入了 Web Worker 来另外提供了一个线程开加载非立即必需的资源。
工作原理
跳转到“工作原理”下面是加载脚本的工作流图示。
步骤说明
跳转到“步骤说明”- 首先,用户已经安装 App 或者自主引入第三方脚本到页面内
- 然后,在 seahorse 项目中会在页面中加入判断脚本是否需要放入 Web Worker 中执行的逻辑脚本
- 在页面中,找到符合以下条件的脚本:
- 带有
scope="worker"
属性的脚本标签 - 带有
src
且链接与在 Web Vitals Defender 插件中已安装加速的脚本的链接一致
脚本放入 Web Worker 中运行
跳转到“脚本放入 Web Worker 中运行”内部插件
跳转到“内部插件”符合以下三种形式之一的脚本会默认放入 Web Worker 中执行。
<!-- 第一种形式:带有 scope="worker" 属性,没有 type -->
<script scope="worker">
// ...
</script>
<!-- 第二种形式:带有 scope="worker" 和 type="application/javascript" 属性 -->
<script scope="worker" type="application/javascript">
// ...
</script>
<!-- 第三种形式:带有 scope="worker" 和 type="text/javascript" 属性 -->
<script scope="worker" type="text/javascript">
// ....
</script>
第三方脚本
跳转到“第三方脚本”当前第三方脚本需要在 Web Vitals Defender 插件中安装需要加速的脚本。
FAQ
跳转到“FAQ”- 在 worker 环境中是通过
postMessage
来与主线程通信的,所以在该环境里 JS 脚本是不能与主窗口进行通信。 - 在 worker 环境中不支持一些较新的API,例如:insertAdjacentHTML。参考已支持的 DOM API文档。
- 每个 spz-script 相当于一个隔离环境,他们之间不能互相通信。