大家好,很高兴又见面了,我是" 前端进阶 ",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

前端进阶
1.什么是Partytown?
Partytown 是一个延迟加载的库,用于将资源密集型脚本移动到 web worker 中,并脱离主线程。 Partytown的目标是将主线程专用于核心代码执行,并将第三方脚本转交给web worker来提高站点性能。

使用Partytown vs. 不Partytown的代码执行方式对比
如上图所示,在不使用Partytown的场景下项目代码和三方脚本都在主线程执行,而使用Partytown后主线程可以专注核心项目代码执行,而将三方脚本转移到web worker执行。
2.Partytown大火?
下图是Partytown在NPM上的*载下**数据。

Partytown的NPM周*载下**量稳定在235,151,同时呈现出稳步上升趋势。在Github上也已经有10.8k的star以及>300的分支,确实有一定的热度。
不过,目前 Partytown还处于Beta阶段。根据Builder.io官方数据,通过 Partytown + Qwik 的结合,将所有代码执行从主线程转移到web worker,显著提高了其主页性能。
3.为什么Partytown如此关心第三方脚本
第三方脚本(third-party scripts) 是指那些嵌入到目标网站,但不直接受控于网站的代码。 例如,埋点分析,广告追踪脚本,A/B测试,*踪器追**等等。 在做性能优化的时候,通常能够根据页面的资源量来推断如何去做优化,但第三方脚本确实特例。

图1:三方脚本影响页面性能
三方脚本对于目标站点来说有以下显著的问题:
- 向多个服务器发出过多的网络请求,网页加载所需的时间就越长
- 过多的 JavaScript 会使主线程忙碌、阻塞 DOM 构建,延迟页面渲染的速度
- CPU 密集型脚本解析和执行会延迟用户交互并导致电池耗尽
- 不小心加载的第三方脚本可能会导致单点故障 (SPOF)
- HTTP 缓存不足,迫使资源经常从网络中获取。
- 过多的 DOM 元素或昂贵的 CSS 选择器。
- 第三方脚本也经常使用可以阻止 window.onload执行,即使嵌入使用的是异步或延迟。
这也是为什么Partytown将关注点放在三方脚本的主要原因。
4.Partytown 的目标
以上详细说明了三方脚本对于页面性能存在的显著问题,那么就需要采用相应的解法。Partytown主要围绕以下几个点来展开:

Partytown 的目标是释放主线程资源
- 释放主线程资源,使得主线程专注于Web 应用程序执行
- 为第三方脚本创建沙盒并允许或拒绝其访问主线程 API
- 在 Web worker线程中隔离长时间运行的任务
- 通过将 DOM setter/getter 批处理到组更新中来减少来自第三方脚本的布局抖动
- 限制第三方脚本对主线程的访问
- 允许第三方脚本完全按照编码方式运行,无需任何更改
- 从 web worker 中同步读取和写入主线程 DOM 操作,允许从 web worker 运行的脚本按预期执行
5.Partytown与三大框架集成
5.1 Partytown+React
Partytown NPM 包已经附带了一个 React 组件,它是 Partytown 片段的包装器。这个 React 组件可以在大多数 React/Preact 项目中直接使用。
npm install @builder.io/partytown
#or yarn add @builder.io/partytown
<Partytown/> 组件是从 @builder.io/partytown/react 子模块导入的。下面是将debug配置设置为 true 的示例,并为 Google 跟踪代码管理器转发配置。
import { Partytown } from '@builder.io/partytown/react';
export function Head() {
return (
<>
<Partytown debug={true} forward={['dataLayer.push']} />
</>
);
}
为每个应该从 web worker 运行的脚本添加 type="text/partytown" 属性。下面的示例使用 React 特定的方式,即dangerouslySetInnerHTML 内联脚本。
<script
type="text/partytown"
dangerouslySetInnerHTML={{
__html: '/* Inlined Third-Party Script */',
}}
/>
5.2 Partytown+Angular
将 Partytown JS 文件的路径添加到 angular.json 文件中的assets数组中:
"projects": {
...
"{project-name}": {
...
"architect": {
...
"build": {
...
"options": {
"assets": [...,
{
"glob": "**/*",
"input": "node_modules/@builder.io/partytown/lib",
"output": "/~partytown"
}
]
}
}
}
}
}
下面的代码片段展示了如何在 index.html 文件中设置 Partytown 脚本。 第一个脚本标签设置Partytown 配置。 第二个脚本标签引用 Partytown JS 文件,第三个标签将第三方脚本加载到 web-worker 上。
<head>
/* Partytown 配置属性*/
<script>
partytown = {
...
};
</script>
/* 内联Partytown脚本 */
<script src="/~partytown/debug/partytown.js"></script>
<script type="text/partytown">
/* 三方脚本 */
</script>
</head>
Partytown与Astro、Gatsby、HTML、Next.js、Nuxt、Remix、Shopify、SvelteKit的更多集成方式可以参考文末资料。
6.本文总结
本文主要和大家介绍Builder.io的又一力作partytown。因为笔者也没有在生产项目中使用、部署过partytown,所以只是做了一个简短的介绍,但是文末的参考资料提供了大量优秀文档以供学习,如果有兴趣可以自行阅读。如果大家有什么疑问欢迎在评论区留言。
参考资料
https://github.com/BuilderIO/partytown
https://www.builder.io/blog/partytown-is-now-in-beta
https://partytown.builder.io/angular
图片版权
图1:SEO Mythbusting - Page Speed (Core Web Vitals) is Not A Big Ranking Factor
其他:https://www.builder.io/