輸入工具即將傳送至合成器
這是網誌系列文章的最後 4 部分,這是最後介紹 Chrome 的成果。並調查 程式碼顯示網站在前一篇文章中,我們介紹了轉譯程序,並瞭解合成器。這篇文章 ,瞭解合成器如何在使用者輸入內容時流暢地進行互動。
瀏覽器視角的輸入事件
聽到「輸入事件」時您可能只想到文字方塊或點擊滑鼠中的字 瀏覽器的視角;輸入是指使用者做出的任何手勢。將滑鼠滾輪的捲動設為輸入項目 也會視為輸入事件。
當使用者以手勢 (例如輕觸螢幕) 出現時,瀏覽器程序就是接收
手勢。不過,瀏覽器程序只能知道手勢於何處執行
分頁中的內容會由轉譯器程序處理因此瀏覽器程序會將事件
類型 (例如 touchstart
) 及其座標至轉譯器程序。轉譯器程序會處理
正確事件事件。
![輸入事件](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/input-event-265a73164e715.png?authuser=19&hl=zh-tw)
合成器收到輸入事件
在前一篇文章中,我們探討合成器如何透過合成過程順暢地處理捲動作業 光柵化層如果頁面沒有附加輸入事件監聽器,合成器執行緒可以 會建立新的複合式頁框,完全獨立於主執行緒。但如果某些事件 是否與網頁附加了監聽器?合成器執行緒如何得知事件需求 資料處理?
瞭解無法快速捲動的區域
由於執行 JavaScript 是主執行緒的工作,因此網頁合成時,合成器執行緒 標示在網頁上的區域,將事件處理常式附加為「Non-Fast Scrollable Region」。變更者: 只要有這項資訊,合成器執行緒就能確保將輸入事件傳送至主執行緒 指定事件的發生時間如果輸入事件來自這個區域之外, 合成器執行緒會承載新影格,而無需等待主執行緒。
![有限的非快速捲動區域](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/limited-non-fast-scrollab-376be5ee2cd6b.png?authuser=19&hl=zh-tw)
編寫事件處理常式時請注意這一點
事件委派是網頁開發中的常見事件處理模式。既然如此 可以在最頂端的元素附加一個事件處理常式,並根據事件目標委派工作。個人中心 您可能看過或編寫類似下方的程式碼。
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault();
}
});
由於您只需要為所有元素編寫一個事件處理常式,因此這個事件的人體工學 而且委派模式很有吸引力不過,如果您是透過瀏覽器的時間點查看這個程式碼 檢視畫面,現在整個網頁會標示為不可快速捲動的區域。也就是說 相較於網頁中特定部分的輸入內容,合成器執行緒必須 與主執行緒通訊,並在每次輸入事件發生時等待該執行緒。因此, 揭開合成器的流暢捲動功能。
![整頁無法快速捲動的區域](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/full-page-non-fast-scroll-dd3010cc3ee0f.png?authuser=19&hl=zh-tw)
如要避免這種情況發生,您可以在事件中傳遞 passive: true
個選項
接聽程式。您仍想讓瀏覽器監聽主執行緒中的事件。
但合成器也可以繼續建構新的影格
document.body.addEventListener('touchstart', event => {
if (event.target === area) {
event.preventDefault()
}
}, {passive: true});
確認活動是否可取消
![頁面捲動](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/page-scroll-2cf8d804f8587.png?authuser=19&hl=zh-tw)
假設網頁中有一個方塊,規定捲動方向範圍僅限水平捲動。
在指標事件中使用 passive: true
選項表示頁面捲動可以順暢運作,
垂直捲動的啟動時間可能在您希望preventDefault
的時候才開始,這樣才能
可以往反方向移動您可以使用 event.cancelable
方法檢查此狀態。
document.body.addEventListener('pointermove', event => {
if (event.cancelable) {
event.preventDefault(); // block the native scroll
/*
* do what you want the application to do here
*/
}
}, {passive: true});
或者,您也可以使用 CSS 規則 (例如 touch-action
),徹底刪除事件處理常式。
#area {
touch-action: pan-x;
}
尋找事件目標
![點擊測試](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/hit-test-39f1d20855064.png?authuser=19&hl=zh-tw)
當合成器執行緒將輸入事件傳送至主要執行緒時,首先要執行的就是命中 測試以找出事件目標。命中測試會使用算繪期間產生的繪製記錄資料 程序,找出事件發生時的點座標底下。
盡量減少將事件分派到主要執行緒
在前一篇文章中,我們提到了一般螢幕每秒重新整理 60 次畫面 我們要如何跟上節奏,讓動畫更流暢一般觸控螢幕 裝置每秒傳遞觸控事件 60 至 120 次,一般滑鼠傳送事件 100 次 第二。輸入事件的保真度高於畫面重新整理的保真度。
如果 touchmove
等連續事件每秒傳送至主執行緒 120 次,
可能觸發過多命中測試和 JavaScript 執行速度 (與
螢幕可以重新整理。
![未篩選的事件](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/unfiltered-events-5c569da8f6466.png?authuser=19&hl=zh-tw)
為了盡量減少主執行緒呼叫的次數過多,Chrome 會合併連續事件 (例如
wheel
、mousewheel
、mousemove
、pointermove
、touchmove
) 且延遲派至
就在下一個 requestAnimationFrame
之前
![聯合事件](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/coalesced-events-42fbb3813612d.png?authuser=19&hl=zh-tw)
任何離散事件,例如 keydown
、keyup
、mouseup
、mousedown
、touchstart
和 touchend
工作,
使用 getCoalescedEvents
取得影格內事件
對大部分的網頁應用程式來說,聯合事件應足以提供良好的使用者體驗。
不過,若您正在建構應用程式
touchmove
座標時,座標之間可能會遺失,導致繪製平滑的線條。在此情況下
您可以在指標事件中使用 getCoalescedEvents
方法,取得這些
並產生聯合事件。
![getCoalescedEvents](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/getcoalescedevents-ab59c1cb92e1b.png?authuser=19&hl=zh-tw)
window.addEventListener('pointermove', event => {
const events = event.getCoalescedEvents();
for (let event of events) {
const x = event.pageX;
const y = event.pageY;
// draw a line using x and y coordinates.
}
});
後續步驟
本系列文章已說明網路瀏覽器的內部運作方式。如果從未想過
開發人員工具建議在事件處理常式中加入 {passive: true}
,或是撰寫 async
的原因
屬性加入指令碼,希望本系列介紹為什麼瀏覽器需要這些屬性
資訊,提供更迅速流暢的網路體驗。
使用 Lighthouse
如果您想製作適合瀏覽器的程式碼,但不知道從何著手, Lighthouse 這項工具能執行任何網站的稽核,並給予一個 說明哪些地方做得不錯,以及哪些部分需要改善。詳閱稽核清單 也能讓您瞭解瀏覽器重視哪些事情。
瞭解如何評估成效
成效調整可能因網站而異,因此務必評估成效 並決定最適合您網站的方式Chrome 開發人員工具團隊提供了一些教學課程 評估網站成效的方法。
為網站新增功能政策
如要採取額外步驟,我們推出了新的功能政策
網路平台功能。這項功能是您在建構專案時面臨的保護。啟用中
功能政策可以保證應用程式的特定行為,避免出錯。
舉例來說,如要確保應用程式一律不會封鎖剖析作業,您可以
同步指令碼政策。啟用 sync-script: 'none'
後,會受限於剖析器的 JavaScript
就無法執行這可避免任何程式碼封鎖剖析器,以及
也不用擔心暫停剖析器的問題
總結
![謝謝](https://developer.chrome.google.cn/static/blog/inside-browser-part4/image/thank-you-cae9a20f3c237.png?authuser=19&hl=zh-tw)
開始架設網站時,我幾乎只關心程式碼撰寫方式, 提升工作效率。這些事項很重要,但我們也應該思考 套用我們撰寫的程式碼新世代瀏覽器不斷向心力, 讓使用者享有更優質的網路體驗。妥善整理程式碼,善待瀏覽器 進而改善使用者體驗。誠摯希望您和我一起努力,為瀏覽器提供協助!
非常感謝大家看過這系列影片初期草稿 (包括但不限於) ):Alex Russell、 Paul Ireland, Megin Kearney、 Eric Bidelman Mathias Bynens, Addy Osmani, Kinuko Yasuda、 Nasko Oskov、 和 Charlie Reis
你喜歡這個系列叢書嗎?如果你對日後貼文有任何疑問或建議, 請在下方留言區或 @kosamari 提供你的回覆。 。