Speculation Rules API, the next generation prerender
prerender
Introduction
用過 link[rel=prerender] 的朋友都知道它的好,透過簡單的 link 設置,驅動瀏覽器背景進行 render,待使用者點擊到該連結後,便能如同閃電般地將頁面進行呈現。開發者僅需要做的就只有設定相關 HTML 便能立即為使用者體驗帶來立竿見影的卓越成長,輕輕鬆鬆營造出如此驚豔的輕薄的假象。
Google 搜尋結果頁更加此項技術進一步發揚光大,透過使用著行為收集,他很清楚 ranking 的前幾名一定會是使用著最常點擊的連結,所以在頁面進來的當下,便 prerender 了這些頁面,這也就是為什麼點擊這些搜尋結果的連結便可以立即看到對應的頁面,除此之外,它亦透過 JavaScript 來制定一些 prender 策略,比方說摸到連結一段時間後就進行 prerender 之類~
簡單的設置一直都是開發者的最愛,但是過於簡單便會需要開發者自己去補完對應的機制,如此一來就會帶來些許困擾,這也就是 Speculation Rules API 推出的主要契機。
Speculation Rules API
簡單的說 Speculation Rules API 就是新生代的 prerender,針對 link[rel=prerender] 做出的最大改善不外乎就是以下兩點:
- 類似 JSON-LD 以 JSON format 的形式進行宣告,搭配 href_matches、selector_matches 來快速圈選候選連結進行 background prerender 的行為。另外也可以搭配 not 來做反向選取的動作。所以可以一次圈出多筆連結出來,再也不需要一個一個 link 進行設置了。
- 新增 eagerness 來擬定策略。可以設置要立即或者滿足特定條件才會進行 background prerender,非常適合在不同的情境下使用,亦可避免資源上的損耗。
設置的方法非常簡單,只要在 HTML 裡頭塞入 script[type=speculationrules] 即可,內容則置入對應的物件。開發者也可以透過 Chrome > DevTools > Application panel 中的 Speculative loads 選項中觀察當前頁面 prerender 的規則以及讀取的狀態。
來看看該如何設置 Speculation Rules API 吧!
如上面範例所,prerender 是一個陣列,裡頭每一個子元素則是不同的宣告規則。也就是說當前的 code 目前宣告了兩種 rule。
- Line 4~5:直接針對特定網址進行宣告,這種宣告法就和 link[rel=prerender] 一樣,只要是符合 CORS,瀏覽器便會嘗試進行背景讀取與渲染。它的 eagerness 採取 immediate 的設置,也就是說會立即讀取 next.html 以及 next2.html 的頁面內容。由於是 immediate 的設置,所以有會受到最大頁面數量 10 的制約。
- Line 7~18:這裡的宣告就很靈活了,透過 where 來設定條件,然後使用 and、not 運算子來靈活搭配。這裡先透過 href_matches 把 / 下面所有的連結掃出來,然後排除 /wp-admin 以及 searchParams 隱含 add-to-cart 參數的的網址。最後搭配 selector_matches 把 class 隱含 do-not-prerender 以及 attribute 隱含 rel=nofollow 的連結 filter 掉。
- Line 17:這裡就是針對上述規則進行策略設置。我個人偏好 moderate,當使用者在連結上停留 200ms 或者發生 pointerdown 事件時(取較快發生的一個)才會進行背景渲染。
eagerness
目前共支援了 immediate、eager、moderate 以及 conservative 這四種值。可以依照當前頁面以及模組的屬性來做不同的搭配。
immediate
:用於盡快推測,亦即發現推測規則時就開始推測。eager
:這與immediate
設定的運作方式相同,但我們之後會在immediate
和moderate
間增加這個程度的設定。moderate
:如果您將游標懸停在連結上 200 毫秒 (或發生pointerdown
事件,以較快者為準,在行動裝置上沒有hover
事件),就會執行推測。conservative
:在點下游標或觸碰時推測。
為了避免資源的損耗,所以不同策略其實都會有最大量的限制。immediate / eager 最大數量就是 10 個,和宣告順序沒有正相關,控制權在瀏覽器上。moderate / converative 最大數量則只有 2 個,採 FIFO(先進先出)機制。
除了透過 script[type=speculationrules] 這種 inline script 的宣告方式外(目前不支援 external 去拿取 rules),也可以透過 JavaScript 來做動態注入。
如上面範例所示,開發者可以透過 HTMLScriptElement.supports 這個 method 來判斷當前瀏覽器是否支援 Speculation Rules API 然後再進行對應設置。
- Line 3:透過 HTMLScriptElement.supports 這個 method 來判斷當前瀏覽器是否支援 Speculation Rules API。
- Line 4:生成一個 script element。
- Line 5~25:設置規則物件。這裏我們先把 msc-sidebar nav 下的所有連結拿出並採取 moderate 策略。讓使用者摸到 200ms 後才會進行背景選染。另一組規則則是掃出隱含「webComponent_msc-ai-」的連結進行立即背景渲染。
- Line 27~29:最後再設置 script type 以及內容後,才把該 script element 黏貼到 document body 中。這裡有個不成文的規定要注意。就是僅能透過 textContent 來設置規則內容。如果採用 innerHTML 的方式注入則不會正常驅動它進行規則註冊。
以上為 Speculation Rules API 目前所支援的兩種設置方式。開發者可以依照自身的開發以及部署環境選取最適宜的方式來進行註冊。
FAQ
Question 1:Shadow DOM 裡頭的連結可以順利的挑選出來嗎?
Answer:可以。瀏覽器內部有個機制會圈選出當前頁面 light / shadow DOM 中的所有連結並依照開發者設置的規則進行 filter,所以即使在 shadom DOM 中的連結依然可以透過 href_match 或者 selector_matches 透將其圈選出來。
Question 2:不同 domain 下的網址可以背景渲染嗎?
Answer:不可以。原則上 Speculation Rules API 還是遵循 CORS 的設置。也就是說 https://a.sample.com 和 https://b.sample.com 屬於不同 domain,所以即使規則有進行設置,但依舊無法進行背景渲染。
Question 3:我可以把頁面上所有連結都強制瀏覽器進行背景選染嗎?
Answer:不可以。為了避免資源的損耗,所以不同策略其實都會有最大量的限制。immediate / eager 最大數量就是 10 個,和宣告順序沒有正相關,控制權在瀏覽器上。moderate / converative 最大數量則只有 2 個,採 FIFO(先進先出)機制。
Question 4:prerender 的頁面 pageview 會被 count 到嗎?
Answer:會。因為背景渲染就如同瀏覽器開了一個新的 tab 進行瀏覽,自然原本頁面的 i13n 均會完整運作。如果不想被 count,那麼可以搭配document.prerendering 來進行判斷。
Question 5:為什麼元件呼叫 requestFullscreen() 時無法正常顯示?
Answer:在 Chrome VER. 131.0.6778.265 下有個 issue,當背景渲染成功時,則呼叫 element.requestFullscreen() 就會出現這詭異的 render,像是一層黑色的 overlay 壓在最上頭。目前只能採用避開的消極做法,即知道頁面元件有用到 fullscreen 功能的話,就不要設定 Speculation Rules API。剩下的就看看 Chrome 是否要認列且進行修復了。
Conclusion
以上便是 Speculation Rules API 基本的使用與設置方法,筆者目前已在 TW Yahoo Auction 上實裝上去,個人相當蠻滿意所來的呈現與效益。簡單的設置便能立即為使用者體驗帶來立竿見影的卓越成長,何樂而不為呢?推薦給每位一同在這領域奮鬥的朋友們~