重點摘要:Extension API 經過更新,可支援往返快取和預先載入瀏覽功能。詳情如下。
Chrome 不斷在加快瀏覽速度。使用即時導覽技術,例如返回/轉送快取 (適用於 Chrome 96 的電腦版推送) 和推測規則 (在 Chrome 103 版中推出) 可改善往返體驗。在本文中,我們將探索我們對瀏覽器擴充功能 API 所做的更新,以因應這些新的工作流程。
瞭解網頁類型
在引入往返快取和預先算繪之前,個別分頁只會有一個有效頁面。以前看到的都是如此。當使用者返回上一頁,系統就會刪除使用中的網頁 (網頁 B),並且完全重建記錄中的上一頁 (第 A 頁)。因此擴充功能不必擔心生命週期頁面位於哪個部分,因為分頁只有一個 (啟用/可見狀態)。
透過往返快取和預先算繪,分頁和頁面之間不再是單一關係。現在,每個分頁會實際儲存多個狀態在狀態之間轉換的多個頁面和頁面,而不會被刪除並重建。
舉例來說,頁面可能會以預先算繪 (未顯示) 的頁面開頭,在使用者點選連結時轉換為有效 (可見) 頁面,然後在使用者前往其他頁面時,儲存在往返快取 (不會顯示) 中,整個頁面也不會遭到刪除。本文稍後將介紹公開的新屬性,協助擴充功能瞭解頁面的狀態。
請注意,分頁標籤可以包含一系列預先轉譯頁面 (而不只是一個頁面)、單一「有效」 (可見) 頁面,以及一系列往返快取頁面。
本次異動對擴充功能開發人員有何影響?
FrameId == 0
在 Chromium 中,最上層/主要頁框稱為最外層。
假設最外框架的 frameId 為 0 (先前的最佳做法) 的擴充功能作者可能會發生問題。由於一個分頁現在可以有多個外部頁框 (預先轉譯和快取的頁面),因此系統會假設分頁有一個最外層的影格不正確。frameId == 0
會繼續呈現「使用中」頁面的最外影格,但同一個分頁中「其他」頁面最外層的影格數不會是零。為修正這個問題,我們已新增 frameType 欄位。請參閱本文的「如何判斷影格是否為最外層?」一節。
影格與文件的生命週期
擴充功能的另一個問題是影格的生命週期。頁框可代管文件 (與已修訂網址相關聯)。文件可以變更 (例如瀏覽),但 frameId 不會,因此很難將特定文件中發生的內容和只與 frameId 建立關聯。我們將推出 documentId 的概念,這是每份文件的唯一識別碼。如果使用者瀏覽頁框並開啟新文件,ID 就會變更。這個欄位可用來判斷頁面變更生命週期狀態 (在預先算繪/主動/快取之間) 的時間是否相同,因為這個欄位會保持不變。
網站導覽事件
視所屬生命週期而定,chrome.webNavigation
命名空間中的事件可能會在同一個頁面上多次觸發。請參閱「如何判斷網頁所屬的生命週期?」和「如何判斷網頁轉換的時機?」兩節。
如何判斷網頁所屬的生命週期?
針對先前可使用 frameId
的許多擴充功能 API,系統已新增 DocumentLifecycle
類型。如果事件有 DocumentLifecycle
類型 (例如 onCommitted
),其值就是產生事件的狀態。您隨時可以透過 WebNavigation
getFrame()
和 getAllFrames()
方法查詢資訊,但一律會建議使用事件中的值。若使用上述任一方法,請注意影格狀態可能會在事件產生後,到上述兩種方法所傳回的保證結果之間出現變化。
DocumentLifecycle
具有下列值:
"prerender
:目前未向使用者顯示,但準備向使用者顯示。"active"
:目前向使用者顯示。"cached"
:儲存在往返快取中。"pending_deletion"
:文件正在遭到刪除。
如何判斷影格是否為最外層的影格?
先前的擴充功能可能會檢查 frameId == 0
,判斷事件是否與最外的影格有關。如果分頁中有多個網頁,我們現在有多個外部影格,因此 frameId 的定義會有問題。您永遠不會收到與往返快取影格相關的事件。但是,如果是預先算繪影格,最外影格的 frameId
會是非零。因此,使用 frameId == 0
做為判斷最外層的影格是否有誤。
為達成此目標,我們導入了名為 FrameType
的新類型,現在可以輕鬆判斷影格是否確實位於最外側的影格。FrameType
具有下列值:
"outermost_frame"
:通常稱為頂層影格。請注意,這些容器包含多個項目。舉例來說,如果您有預先轉譯和快取的頁面,每個頁面都會有最外層的頁框可呼叫其最頂層頁框。"fenced_frame"
:保留供日後使用。"sub_frame"
:一般為 iframe。
我們可以結合 DocumentLifecycle
與 FrameType
,並判斷影格是否為使用中的最外層影格。例如:js
tab.documentLifecycle == “active” && frameType == “outermost_frame”
如何解決頁框的使用時間問題?
如前文所述,頁框代管文件,頁框可能會前往新文件,但 frameId
不會改變。如果收到只有 frameId
的事件,這會造成問題。如果您查詢影格的網址,這可能會與事件發生的時間不同,稱為「使用時間問題」。
為解決這個問題,我們推出了 documentId
(和 parentDocumentId
)。如果提供 documentId
,webNavigation.getFrame() 方法現在會將 frameId
變為選用。每次瀏覽影格時,documentId
都會變更。
如何判斷頁面轉換的時機?
可以透過明確信號判斷網頁在狀態之間轉換的時機。
現在來看看 WebNavigation
事件。
我們在瀏覽任何頁面時,會按照下方列出的順序顯示四個事件。請注意,當 DocumentLifecycle
狀態為 "prerender"
或 "active"
時,可能會發生這四個事件。
onBeforeNavigate
onCommitted
onDOMContentLoaded
onCompleted
如下圖所示,當預先算繪頁面變為使用中頁面時,documentId
會變更為 "xyz"
。
網頁從往返快取或預先轉譯轉換為有效狀態時,還會有三個事件 (但 DocumentLifecyle
為 "active"
)。
onBeforeNavigate
onCommitted
onCompleted
documentId
將與原始事件相同。當 documentId
== xyz 啟動時,如下圖所示。請注意,除了 onDOMContentLoaded
事件外,系統會觸發相同的導覽事件,因為頁面已載入。
如有任何意見或問題,歡迎透過 chromium-extensions 群組提問。