代碼和代碼管理工具的最佳做法

最佳化網站體驗核心指標的代碼和代碼管理工具。

Katie Hempenius
Katie Hempenius

代碼是插入網站上的第三方程式碼片段,通常是透過代碼管理工具插入。 代碼最常用於行銷和分析。

代碼和代碼管理工具的成效因網站而異。 代碼管理工具可以比較這些信封:代碼管理工具會提供手圍,但要填入的內容和使用方式,最取決於你本身。

本文將說明最佳化代碼和代碼管理工具,以提升效能及進行網站體驗指標的技巧。雖然本文介紹的是 Google 代碼管理工具,但討論中的許多概念也適用於其他代碼管理工具。

對網站體驗核心指標的影響

代碼管理工具通常會利用代碼管理工具快速載入網頁並保持回應速度,間接影響網站體驗核心指標。頻寬包括用來下載網站的代碼管理工具 JavaScript,或是在後續呼叫時產生的呼叫。主要執行緒的 CPU 作業時間可用來評估及執行代碼管理工具和代碼中的 JavaScript。

最大內容繪製 (LCP) 會在重要頁面載入時間期間產生頻寬爭用的安全漏洞。此外,封鎖主執行緒可能會延遲 LCP 轉譯時間

可能導致累計版面配置位移 (CLS) 受到影響,因為在首次轉譯前延遲載入重要資源,或是由代碼管理工具管理員將內容插入網頁。

與下一個繪製項目 (INP) 的互動很像主執行緒上的 CPU 爭用情形,而且我們發現代碼管理工具的大小和 INP 分數不佳,具有關聯性。

代碼類型

代碼對成效的影響會因代碼類型而異。一般來說,圖片標記 (「像素」) 效能最高,其次是自訂範本,最後是自訂 HTML 標記。廠商代碼會因其允許的功能而有所不同。

不過請注意,使用代碼的方式會大幅影響代碼的效能影響。「像素」在本質上非常優異,因為這種代碼類型的特性對使用方式設有嚴格限制。自訂 HTML 標記不一定可讓效能完全不佳,但由於使用者的自由程度高,所以很容易遭到濫用,以對效能造成負面影響。

考慮標記時,請留意規模:任何單一代碼對效能的影響可能微乎其微,但若在同一頁面上使用大量或數百個標記,則可能變得明顯。

並非所有指令碼都應使用代碼管理工具載入

代碼管理工具通常不適合用來載入資源,因為這會導致使用者體驗的直接視覺或功能層面 (例如 Cookie 通知、主頁橫幅或網站功能)。使用代碼管理工具載入這些資源通常會延遲提交。這不但會對使用者體驗造成負面影響,而且也會提升 LCP 和 CLS 等指標。此外,請注意,有些使用者會封鎖代碼管理工具。若使用代碼管理工具導入使用者體驗功能,可能會導致部分使用者的網站毀損。

謹慎使用自訂 HTML 代碼

自訂 HTML 標記推出至今已有多年,且大部分網站皆適用。自訂 HTML 標記可讓您輸入自己的程式碼,但會受到一些限制。儘管名稱,其主要用途是在網頁中加入自訂的 <script> 元素。

自訂 HTML 標記的使用方法有很多,而且對效能的影響各不相同。請注意,評估網站效能時,大多數的工具都會將自訂 HTML 標記的成效影響歸因給插入該標記的代碼管理工具,而非標記本身。

在 Google 代碼管理工具中建立自訂代碼的螢幕截圖

自訂 HTML 標記可在周圍網頁中插入元素。將元素插入頁面的原因可能是效能問題,在某些情況下,也可能會造成版面配置位移。

  • 在大多數情況下,如果在頁面中插入元素,瀏覽器必須重新計算頁面上每個項目的大小和位置,這個過程稱為「版面配置」。單一版面配置的效能影響極少,但發生過度時可能會成為效能問題的來源。這個現象對低階裝置和含有大量 DOM 元素的頁面產生的影響較大。
  • 如果在周圍區域轉譯後,將可見網頁元素插入 DOM,就可能導致版面配置位移。但這個情況並非專供代碼管理工具管理。不過,由於代碼通常會比網頁的其他部分晚一點載入,因此往往在周圍網頁轉譯完畢之後,才會插入 DOM。

考慮使用自訂範本

自訂範本支援部分與自訂 HTML 標記相同的作業,不過是以 JavaScript 沙箱版本為基礎建構而成,為常見用途 (例如指令碼插入和像素插入) 提供 API。顧名思義,他們允許進階使用者建立範本,而進階使用者能夠將效能納入考量。方便技術人員使用範本。這通常比提供完整的自訂 HTML 存取權更為安全。

由於自訂範本的限制更多,這些標記不太可能出現效能或安全性問題;然而,基於以上原因,自訂範本將不適用於所有用途。

在 Google 代碼管理工具中使用自訂範本的螢幕截圖

正確插入指令碼

使用代碼管理工具插入指令碼是很常見的用途,建議您使用自訂範本和 injectScript API。

如要瞭解如何使用 injectScript API 轉換現有的自訂 HTML 標記,請參閱「轉換現有代碼」一文。

如果一定要使用自訂 HTML 標記,請注意以下幾點:

  • 程式庫和大型第三方指令碼應透過下載外部檔案 (例如 <script src="external-scripts.js">) 的指令碼標記載入,而非直接將指令碼的內容貼到代碼中。雖然停止使用 <script> 標記可免除單獨往返下載指令碼內容,但這種做法會增加容器大小,並防止瀏覽器單獨快取指令碼。
  • 許多供應商建議將 <script> 標記放在 <head> 頂端。不過,如果是透過代碼管理工具載入的指令碼,則通常不需要這項建議:在大多數情況下,瀏覽器會在代碼管理工具執行前完成 <head> 剖析作業。

使用像素

在某些情況下,第三方指令碼可以替換為圖片或 iframe「像素」。與基於指令碼的對應項目相比,像素支援的功能可能較少,因此往往會被視為較不受歡迎的實作方式。不過,在代碼管理工具中使用時,像素可能更加動態,因為它們可能會在觸發條件觸發及傳遞不同的變數。它們是效能最佳且安全的代碼類型,因為代碼觸發後並不會執行 JavaScript。Pixel 的資源大小極小 (小於 1 KB),而且不會造成版面配置位移。

請洽詢第三方供應商,進一步瞭解對方對像素的支援。此外,您可以嘗試檢查程式碼的程式碼是否有 <noscript> 標記。如果供應商支援像素,通常會將這些像素納入 <noscript> 標記中。

Google 代碼管理工具中的自訂圖片代碼螢幕截圖

像素替代方案

以 Pixel 來說,在伺服器回應不相關的情況下 ( 例如將資料傳送至數據分析提供者) 時,Pixel 是價格最實惠且最可靠的方法之一。navigator.sendBeacon()fetch() keepalive API 就是為瞭解決相同的使用情境,但其可靠性比像素更高。

繼續使用像素是正常現象,因為像素受到妥善支援,效能也幾乎沒有影響。但如果您正在建構自己的信標,請考慮使用其中一個 API。

sendBeacon()

navigator.sendBeacon() API 的用途是在伺服器回應並不重要的情況下,將少量資料傳送至網路伺服器。

const url = "https://example.com/analytics";
const data = JSON.stringify({
    event: "checkout",
    time: performance.now()
});

navigator.sendBeacon(url, data);

sendBeacon() 的 API 有限,它只支援提出 POST 要求,且不支援設定自訂標頭。所有新版瀏覽器都支援這項功能。

fetch() keepalive

keepalive 是一個旗標,允許使用 Fetch API 提出非封鎖要求,例如事件回報與數據分析。這是透過在傳遞至 fetch() 的參數中加入 keepalive: true 來使用。

const url = "https://example.com/analytics";
const data = JSON.stringify({
  event: "checkout",
  time: performance.now()
});

fetch(url, {
    method: 'POST',
    body: data,
    keepalive: true
});

如果 fetch() keepalivesendBeacon() 看起來非常相似,那是因為兩者相似。事實上,在 Chromium 瀏覽器中,sendBeacon() 現在是以 fetch() keepalive 為基礎。

選擇 fetch() keepalivesendBeacon() 時,請務必考量所需的功能和瀏覽器支援。Retrie() API 的彈性更大,但 keepalive 的瀏覽器支援sendBeacon() 少。

取得說明

通常按照第三方供應商提供的指南建立代碼。 如果不清楚供應商的程式碼是什麼,不妨詢問知道供應商的程式碼。 取得第二意見有助於判斷標記是否可能產生效能或安全性問題。

我們也建議在代碼管理工具中加上擁有者標籤。很容易忘記標記擁有者,我們也非常樂意移除標記,以防萬一!

觸發條件

整體來說,最佳化標記觸發條件時,通常必須確保觸發代碼的次數不會超過所需,以及選擇能平衡業務需求與效能成本的觸發條件。

觸發條件本身是 JavaScript 程式碼,能增加代碼管理工具的大小和執行成本。雖然大多數觸發事件都很小,但累積效果卻可相加。例如加入多個點擊事件,或是計時器觸發條件,可能會大幅提高代碼管理工具的工作負載量。

選擇合適的觸發事件

代碼的效能影響並不固定:一般來說,代碼越早觸發,對效能的影響越大。資源通常會在初始網頁載入期間受限,因此資源載入或執行特定資源 (或標記) 時,佔用了其他資源。

雖然建議您為所有標記選擇適當的觸發條件,但對於載入大型資源或執行長指令碼的標記格外重要。

代碼可以透過網頁瀏覽 (通常是 Page load,在 DOM ReadyWindow Loaded) 上觸發,也可能根據自訂事件觸發。為了避免影響網頁載入,建議在 Window Loaded 後觸發非必要代碼。

使用自訂事件

自訂事件可讓您針對 Google 代碼管理工具內建觸發條件未涵蓋的網頁事件觸發觸發條件。舉例來說,許多代碼都使用網頁瀏覽觸發條件;不過,在許多網頁上,DOM ReadyWindow Loaded 之間的時間範圍可能很長,而這也可能會導致代碼觸發時難以微調。自訂事件可解決這個問題。

如要使用自訂事件,請先建立自訂事件觸發條件,並更新代碼來使用這個觸發條件。

Google 代碼管理工具中的自訂事件觸發條件螢幕截圖

如要啟動觸發條件,請將對應的事件推送至資料層。

// Custom event trigger that fires after 2 seconds
setTimeout(() => {
  dataLayer.push({
    'event' : 'my-custom-event'
  });
}, 2000);

使用特定觸發條件

使用特定觸發條件有助於避免不必要的代碼觸發。 運用這個概念的方法很多,但最簡單也最實用的做法之一,就是確保代碼只在確實使用網頁時觸發。

螢幕截圖:Google 代碼管理工具中的觸發條件

此外,內建變數也可以納入觸發條件中來限制代碼觸發。

不過請注意,如果觸發條件是複雜的觸發條件或例外狀況,處理時間本身會需要大量時間,因此請別讓這些條件過於複雜。

在適當的時機載入代碼管理工具

在代碼管理工具本身載入的時間點進行調整,可能會對成效產生重大影響。無論觸發條件的設定方式為何,觸發條件必須等到代碼管理工具載入後才能觸發。雖然為個別代碼選擇合適的觸發條件固然重要 (如上所述),但在載入代碼管理工具時,實驗的影響通常都相同或較大,因為這項決策會影響網頁上的所有代碼。

稍後載入代碼管理工具也會增添控制項,避免日後發生效能問題,以免代碼管理工具使用者過早載入代碼,卻無法察覺這個問題的影響。

變數

變數可讓系統讀取網頁中的資料。這些屬性對於觸發條件和代碼本身都很有用。

與觸發條件一樣,變數會導致 JavaScript 程式碼加進代碼管理工具,而可能造成效能問題。變數可以相對簡單地內建類型,例如讀取部分網址、Cookie、資料層或 DOM。也可以是自訂 JavaScript,當中幾乎沒有限制。

變數應保持簡潔有力,因為變數需要持續評估變數。移除不再使用的舊變數,藉此縮減代碼管理工具指令碼的大小和使用的處理時間。

標記管理

有效率地使用代碼有助於降低成效問題的風險。

使用資料層

資料層「包含您要傳送至 Google 代碼管理工具的所有資訊」。更明確地說,這個物件是包含頁面相關資訊的 JavaScript 陣列。也可用來觸發代碼。

// Contents of the data layer
window.dataLayer = [{
    'pageCategory': 'signup',
    'visitorType': 'high-value'
  }];

// Pushing a variable to the data layer
window.dataLayer.push({'variable_name': 'variable_value'});

// Pushing an event to the data layer
window.dataLayer.push({'event': 'event_name'});

雖然可以在沒有資料層的情況下使用 Google 代碼管理工具,但還是強烈建議您使用。您可以利用資料層,將第三方指令碼存取的資料整合到單一位置,讓您更清楚掌握其使用情況。此外,這有助於減少不必要的變數計算和指令碼執行。使用資料層也能控管標記存取的資料,而非授予完整的 JavaScript 變數或 DOM 存取權。

移除重複和未使用的標記

如果網頁 HTML 標記內含的標記除了透過代碼管理工具插入以外,就可能會重複加入標記。

您應暫停或移除未使用的標記,而非使用觸發事件例外狀況來加以封鎖。暫停或移除標記會從容器中移除程式碼,但封鎖功能不會。

移除未使用的代碼時,也應該檢查觸發條件和變數,確認只有這些代碼會用到觸發條件和變數可以將其移除。

使用允許和拒絕清單

允許和拒絕清單可讓您針對網頁允許的代碼、觸發條件和變數設定非常精細的限制。這可用於協助強制執行最佳做法和其他政策。

允許和拒絕清單是透過資料層設定。

window.dataLayer = [{
  'gtm.allowlist': ['<id>', '<id>', ...],
  'gtm.blocklist': ['customScripts']
}];

舉例來說,系統不允許任何自訂 HTML 標記、JavaScript 變數或直接 DOM 存取。這表示只有像素和預先定義標記,才能與資料層的資料搭配使用。雖然限制嚴格規定,但代碼管理工具導入程序可能會更加有效,而且更加安全。

考慮使用伺服器端代碼

改用伺服器端代碼是一項簡單的工作,但還是值得考慮;尤其適合想進一步控管資料的大型網站使用。伺服器端代碼會從用戶端移除供應商程式碼,但有了這項功能,用戶端就能將處理工作卸載至伺服器。

舉例來說,使用用戶端標記時,將資料傳送至多個數據分析帳戶時,用戶端會針對每個端點分別發出要求。相較之下,使用伺服器端代碼時,用戶端只會將單一要求傳送至伺服器端容器,接著這項資料會轉送至不同的數據分析帳戶。

請注意,伺服器端代碼僅適用於部分代碼,代碼相容性因供應商而異。

詳情請參閱「伺服器端代碼簡介」一文。

容器

代碼管理工具通常會允許設定內含多個執行個體或「容器」。這樣一來,一個代碼管理員帳戶內就能控管多個容器。

每個網頁僅使用一個容器

在單一頁面上使用多個containers可能會造成重大的效能問題,因為該容器會產生額外的負荷和指令碼執行。至少會複製核心標記程式碼本身,因為這個程式碼是做為容器 JavaScript 的一部分提供,無法在容器之間重複使用。

使用多個容器的情況很少見。然而,也有人可能會使用例項,如果受到妥善控管,包括:

  • 使用較淺的「早期載入」容器和較重的「稍後載入」容器,而非一個大型容器。
  • 具備受限制的容器,由技術較低的使用者使用、限制較少但更嚴格控管的容器,適用於無法在受限制容器中使用的標記。

如果必須在一個網頁上使用多個容器,請按照 Google 代碼管理工具指南設定多個容器

視需要使用個別容器

如果您為多個資源 (例如網頁應用程式和行動應用程式) 使用代碼管理工具,採用的容器數量或許有助於或降低工作流程的效率。也可能會影響效能。

一般來說,如果網站的使用方式和結構類似,一個容器就能有效用於多個網站。舉例來說,雖然品牌的行動版和網頁應用程式可能提供類似的功能,但應用程式的結構也可能不同,因此更有效率地透過個別容器管理。

嘗試重複使用單一容器時,通常不會因為強制採用複雜的邏輯來管理標記和觸發條件,而這麼做的複雜度和規模會大增。

留意容器大小

容器的大小取決於其代碼、觸發條件和變數。雖然小型容器仍可能對網頁效能造成負面影響,但大型容器幾乎可以確定。

最佳化標記使用方式時,容器大小不應非您的重點指標;然而,大型容器大小通常代表容器並未妥善維護,且可能遭到濫用。

Google 代碼管理工具會將容器大小限制為 200 KB,而且會從 140 KB 開始發出警告。不過,大多數網站都應盡量將容器保持小於這個值。因此,網站容器的中位數約為 50 KB。

如要判斷容器的大小,請查看 https://www.googletagmanager.com/gtag/js?id=YOUR_ID 傳回的回應大小。這個回應包含 Google 代碼管理工具程式庫和容器內容。Google 代碼管理工具程式庫的壓縮大小約為 33 KB。

為容器版本命名

容器版本是容器在特定時間點的快照,使用有意義的名稱,並且附上有意義的異動簡短說明,可以大幅提高日後的效能問題偵錯效率。

標記工作流程

管理標記變更非常重要,可確保標記對網頁效能不會造成負面影響。

部署前先測試標記

在部署之前測試標記有助於在發布前找出問題 (效能及其他問題)。

測試代碼時的注意事項包括:

  • 代碼是否正常運作?
  • 標記是否會導致版面配置位移?
  • 代碼是否會載入任何資源?這些資源有多大?
  • 代碼是否會觸發長時間執行的指令碼?

預覽模式

預覽模式可讓您在實際網站上測試代碼變更,而不必先對外部署。預覽模式包含偵錯控制台,可提供標記相關資訊。

在預覽模式下執行時,Google 代碼管理工具的執行時間會有所不同 (略慢),這是因為在偵錯主控台中顯示資訊需要額外負擔。因此,我們不建議將預覽模式收集到的網站體驗指標評估結果與在實際工作環境中收集的資料進行比較。然而,這項差異應該不會影響標記本身的執行行為。

獨立測試

測試標記的另一種方法是設定空白頁面,其中包含具有單一標記 (您要測試的標記) 的容器。這項測試設定較不切實際,因此不會發現某些問題 (例如標記是否會導致版面配置改變),但能夠更輕鬆地分隔及評估代碼對指令碼執行等事物的影響。瞭解 Telegraph 如何運用這種隔離方法改善第三方程式碼的效能

監控代碼成效

Google 代碼管理工具 Monitoring API 可用來收集特定標記執行時間的相關資訊。這項資訊會回報至您選擇的端點。

詳情請參閱「如何建構 Google 代碼管理工具監控器」一文。

需要核准才能變更容器

第一方程式碼通常會在部署前通過審查和測試,以同樣的方式處理代碼。加入兩步驟驗證,是需要管理員核准才能變更容器的方式。或者,如果您不想執行兩步驟驗證,但仍想密切留意變更,則可設定容器通知,以接收關於所選容器事件的電子郵件快訊。

定期稽核標記使用情形

使用標記的其中一個挑戰是,這些標記通常會隨著時間累積:新增標記,但很少被移除。定期稽核標記是反轉這種趨勢的其中一種方式。建議確認的頻率取決於網站代碼的更新頻率。

為每個標記加上標籤,以便識別其回應者,並判斷該標記是否仍需要回應。

稽核代碼時,請務必一併清除觸發條件和變數。也容易造成效能問題。

詳情請參閱控管第三方指令碼