重點摘要:Extensions API 已更新,可支援往返快取,預先載入導覽。詳情如下。
Chrome 不斷在加快瀏覽速度。即時導覽技術 (例如往返快取 (在 Chrome 96 的電腦上已推出) 和推測規則 (在 Chrome 103 中已推出) 等) 可改善前往和返回的體驗。本文將探討我們為因應這些新工作流程而對瀏覽器擴充功能 API 所做的更新。
瞭解頁面類型
在引入往返快取和預先算繪之前,個別分頁只會有一個有效頁面。這一直是顯示的內容。如果使用者返回上一頁,系統會刪除目前的網頁 (網頁 B),並完全重建歷史記錄中的上一頁 (網頁 A)。因此擴充功能不必擔心生命週期頁面位於哪個部分,因為分頁只有一個 (啟用/可見狀態)。
透過往返快取和預先算繪,分頁和頁面之間不再是單一關係。如今,每個分頁實際上都會儲存多個頁面,並在狀態之間進行頁面轉換,而非遭到銷毀和重建。
舉例來說,網頁一開始可能會以預先算繪 (不可見) 的形式存在,然後在使用者點選連結時轉換為有效 (可見) 的網頁,再在使用者瀏覽其他網頁時儲存在返回/前進快取 (不可見) 中,而這一切都不會導致網頁遭到刪除。在本文稍後的部分,我們將探討公開的新屬性,協助擴充功能瞭解網頁的狀態。
請注意,分頁可以有一系列預先算繪的網頁 (不只一個)、單一有效 (可見) 網頁,以及一系列快取的「返回」/「前進」網頁。
這對擴充功能開發人員有何影響?
FrameId == 0
在 Chromium 中,最上層/主要頁框稱為最外層。
假設最外層框架的 frameId 為 0 (先前的最佳做法) 的擴充功能作者,可能會發生問題。由於分頁現在可以有多個最外層框架 (預先算繪和快取的網頁),因此假設分頁只有一個最外層框架的假設是不正確的。frameId == 0
仍會繼續代表有效頁面的最外層框架,但同一個分頁中其他頁面的最外層框架會設為非零值。我們已新增「frameType」欄位來修正這個問題。請參閱本篇文章的「如何判斷某個影格是否為最外層影格?」一節。
影格和文件的生命週期
另一個與擴充功能相關的問題是影格生命週期。框架會代管文件 (與已提交的網址相關聯)。文件可能會變更 (例如透過導覽),但 frameId 不會變更,因此很難只透過 frameId 連結特定文件中的事件。我們將推出 documentId 的概念,這是每份文件的唯一識別碼。如果導覽框架並開啟新文件,ID 就會變更。這個欄位可用於判斷網頁何時變更生命週期狀態 (在預先算繪/有效/快取之間),因為它會保持不變。
網頁導覽事件
根據生命週期,chrome.webNavigation
命名空間中的事件可以在同一個網頁上觸發多次。請參閱「如何判斷網頁處於哪個生命週期?」和「如何判斷網頁轉換的時間?」兩節。
如何判斷網頁處於哪個生命週期?
DocumentLifecycle
類型已新增至先前提供 frameId
的多個擴充功能 API。如果事件中包含 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
,並判斷影格是否為使用中的最外層影格。例如: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 群組中提出。