Builder.io的又一力作partytown?三方脚本都该移除?

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

Builder.io的又一力作partytown?三方脚本都该移除?

前端进阶

1.什么是Partytown?

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

Builder.io的又一力作partytown?三方脚本都该移除?

使用Partytown vs. 不Partytown的代码执行方式对比

如上图所示,在不使用Partytown的场景下项目代码和三方脚本都在主线程执行,而使用Partytown后主线程可以专注核心项目代码执行,而将三方脚本转移到web worker执行。

2.Partytown大火?

下图是Partytown在NPM上的*载下**数据。

Builder.io的又一力作partytown?三方脚本都该移除?

PartytownNPM周*载下**量稳定在235,151,同时呈现出稳步上升趋势。在Github上也已经有10.8k的star以及>300的分支,确实有一定的热度。

不过,目前 Partytown还处于Beta阶段。根据Builder.io官方数据,通过 Partytown + Qwik 的结合,将所有代码执行从主线程转移到web worker,显著提高了其主页性能。

3.为什么Partytown如此关心第三方脚本

第三方脚本(third-party scripts) 是指那些嵌入到目标网站,但不直接受控于网站的代码。 例如,埋点分析,广告追踪脚本,A/B测试,*踪器追**等等。 在做性能优化的时候,通常能够根据页面的资源量来推断如何去做优化,但第三方脚本确实特例。

Builder.io的又一力作partytown?三方脚本都该移除?

图1:三方脚本影响页面性能

三方脚本对于目标站点来说有以下显著的问题:

  • 向多个服务器发出过多的网络请求,网页加载所需的时间就越长
  • 过多的 JavaScript 会使主线程忙碌、阻塞 DOM 构建,延迟页面渲染的速度
  • CPU 密集型脚本解析和执行会延迟用户交互并导致电池耗尽
  • 不小心加载的第三方脚本可能会导致单点故障 (SPOF)
  • HTTP 缓存不足,迫使资源经常从网络中获取。
  • 过多的 DOM 元素或昂贵的 CSS 选择器。
  • 第三方脚本也经常使用可以阻止 window.onload执行,即使嵌入使用的是异步或延迟。

这也是为什么Partytown将关注点放在三方脚本的主要原因。

4.Partytown 的目标

以上详细说明了三方脚本对于页面性能存在的显著问题,那么就需要采用相应的解法。Partytown主要围绕以下几个点来展开:

Builder.io的又一力作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/