天天看點

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?三方腳本都該移除?

Partytown的NPM周下載下傳量穩定在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/

繼續閱讀