幹擾 document.write()

您最近在 Play 管理中心裡看到一則警告,如下所示: Chrome 不知道那是什麼?

(index):34 A Parser-blocking, cross-origin script,
https://paul.kinlan.me/ad-inject.js, is invoked via document.write().
This may be blocked by the browser if the device has poor network connectivity.

可組合項是網路的一大優勢, 整合第三方打造的服務,打造出超棒的新產品!一 可組合函式的缺點是其中存在著共同的責任 使用者體驗如果整合功能無法達到最佳效果, 避免受到負面影響

效能不佳的其中一個已知原因就是在網頁中使用 document.write()。 具體來說,就是該插入指令碼的用途外觀如下 可能會導致使用者遇到實際問題

document.write('<script src="https://example.com/ad-inject.js"></script>');

瀏覽器在轉譯網頁前,必須先剖析 HTML 標記來建立 DOM 樹狀結構。 每當剖析器遇到指令碼時,必須先停止並執行該指令碼才能繼續 剖析 HTML。如果指令碼動態插入其他指令碼,則系統會強制剖析器等待剖析 時間越長,資源下載作業可能會因此產生一或多項網路來回行程 延遲初次轉譯網頁所需的時間

針對連線速度較慢 (例如使用 2G) 的使用者,動態顯示外部指令碼 插入 document.write() 可能會導致系統延遲顯示主要網頁內容 或是導致網頁無法載入或耗時過長 使用者就放棄了根據 Chrome 的檢測功能,我們發現 含有透過 document.write() 插入的第三方指令碼的網頁是 使用 2G 時,載入速度通常是其他網頁的兩倍。

我們透過 28 天實際測試,針對 1% 的 Chrome 收集資料 穩定使用者,僅限使用 2G 連線的使用者。我們發現,網頁載入的 7.6% 是在 2G 環境中,至少含有一個會封鎖 透過 document.write() 插入頂層文件。為封鎖 我們發現這些指令碼的載入經過以下改善:

  • 網頁載入量增加 10% 首次顯示內容所需時間 (使用者可透過視覺化方式確認網頁正在有效載入), 網頁載入時間增加 25% 到完全剖析狀態,重新載入次數則減少 10% 表示使用者不滿
  • 平均時間縮短 21% (快超過 1 秒),直到 首次顯示內容所需時間
  • 可減少 38% 的倍數,代表剖析網頁所需的平均時間。 大幅縮短了 6 秒 要顯示對使用者而言重要的資料

瞭解這些資料後,Chrome 自 55 版起 intervenes 當使用者透過變更 document.write() 的 在 Chrome 中的處理方式 (請參閱 Chrome 狀態)。 具體來說,Chrome 不會執行透過指令插入的 <script> 元素 符合下列「所有」條件時,document.write()

  1. 使用者的連線速度緩慢,尤其是使用 2G 網路時。(以 日後連線速度較慢的其他使用者也可能會受到影響 例如 3G 或速度緩慢的 Wi-Fi)。
  2. document.write() 位於頂層文件中。不過,介入措施並未 不會封鎖 iframe 中的 document.write 指令碼 主網頁的顯示。
  3. document.write() 中的指令碼會阻擋剖析器。指令碼: 「async」 或「defer」 屬性仍會執行
  4. 指令碼並非由同一個網站代管。也就是說,Chrome 會 無法幹擾具有相符 eTLD+1 的指令碼 (例如由 js.example.org 中插入 www.example.org)。
  5. 瀏覽器 HTTP 快取中尚未包含指令碼。快取中的指令碼 不會發生網路延遲,而且仍然執行
  6. 網頁要求並未重新載入。Chrome 無法介入 使用者觸發重新載入並照常執行網頁。

第三方程式碼片段有時會使用 document.write() 載入指令碼。 幸好,大多數第三方 非同步載入替代方案 允許第三方指令碼載入,而不會妨礙顯示其餘部分 網頁上的內容

該如何解決這個問題?

這個簡單答案並不是使用 document.write() 插入指令碼。三 維持一組支援非同步載入器的已知服務。 建議您持續查看

如果您的供應商不在清單中,而且支援非同步指令碼載入 然後告訴我們,我們可以更新網頁,以協助所有使用者。

如果您的供應商不支援非同步載入指令碼的功能 聯絡網頁中,建議您與他們聯絡 請提供給我們和他們 對他們的影響

如果供應商提供包含 document.write() 的程式碼片段, 您可以為指令碼元素新增 async 屬性,或者 可讓您使用 DOM API (例如 document.appendChild()) 新增指令碼元素 或 parentNode.insertBefore()

如何偵測網站何時受到影響

系統在判定是否強制執行限制時,有許多條件 那麼該怎麼知道自己是否受到影響?

偵測使用者是否已連上 2G

為了瞭解這項異動可能帶來的影響,您必須先瞭解 有多少使用者會使用 2G 網路。您可以偵測使用者目前的網路類型 Network Information API 適用於 Chrome,然後抬頭查看您的分析或實際使用者指標 (RUM) 系統。

if(navigator.connection &&
    navigator.connection.type === 'cellular' &&
    navigator.connection.downlinkMax <= 0.115) {
    // Notify your service to indicate that you might be affected by this restriction.
}

偵測 Chrome 開發人員工具中的警告

自 Chrome 53 起,開發人員工具問題:document.write() 有問題 聲明。具體來說,如果 document.write() 要求符合條件 2 到 5 (Chrome 會在傳送這則警告時忽略連線條件), 如下所示:

文件寫入警告。

Chrome 開發人員工具中的警告畫面很好,但該如何偵測? 規模?您可以檢查在 就會產生幹擾

檢查指令碼資源上的 HTTP 標頭

當透過 document.write 插入的指令碼遭到封鎖時,Chrome 會向 將下列標頭新增至要求的資源:

Intervention: <https://shorturl/relevant/spec>;

如果系統找到透過 document.write 插入的指令碼,且指令碼可能在以下位置遭到封鎖: 不同的情況,Chrome 可能會傳送:

Intervention: <https://shorturl/relevant/spec>; level="warning"

系統會在指令碼的 GET 要求中傳送介入措施標頭 (在實際介入時以非同步方式)。

未來掌握了什麼?

初步計畫是在偵測到條件時 以及會遇到哪些問題我們開始在 Play 管理中心顯示 Chrome 53 版,顯示一則警告。 (Beta 版已於 2016 年 7 月推出,我們預期 2016 年 9 月)。

我們將介入封鎖 2G 使用者註入的指令碼 Chrome 54 預計將提供穩定版,對 2016 年 10 月中旬。查看 Chrome 狀態項目 即可掌握最新消息

我們正努力找出使用者連線速度較慢時 (即 執行速度較慢的 3G 或 Wi-Fi)。追蹤這個 Chrome 狀態項目

想瞭解詳情嗎?

如要進一步瞭解,請參閱下列其他資源: