摘要:如下圖所示渲染性能保證主動交互讓用戶感覺流暢一般超過認為是長任務會阻塞的運行如下是兩種解決方案。下面是另外一種使頁面流暢的方法時間分片。
流暢性
本篇是基于 FDCon2019 上《讓你的網頁更絲滑by劉博文》的復盤文。該課題也是博主感興趣的領域, 后續會結合 React 的 Schedule 與該文進行進一步整合, 個人博客
被動交互: animation
主動交互: 鼠標、鍵盤
被動交互當前市面上的設備頻率在 60 HZ 以上。
主動交互跑如下界面 https://code.h5jun.com/pojob
結合如下代碼塊, 可以看到 100ms 以下的點擊是順暢的, 而超過 100ms 的點擊就會有卡頓現象。
var observer = new PerformanceObserver(function(list) { var perfEntries = list.getEntries() console.log(perfEntries) }); observer.observe({entryTypes: ["longtask"]});讓用戶感覺到流暢
衡量一個網頁/App 是否流暢有個比較好用的 Rail 模型, 它大概有以下幾個評判標準值。
Response —— 100ms Animation —— 16.7ms Idle —— 50ms Load —— 1000ms像素管道
像素管道一般由 5 個部分組成。JavaScript、樣式、布局、繪制、合成。如下圖所示:
渲染性能保證主動交互讓用戶感覺流暢
function App() { useEffect(() => { setTimeout(_ => { const start = performance.now() while (performance.now() - start < 1000) { } console.log("done!") }, 5000) }) return ( ); }
一般超過 50 ms 認為是 long task(長任務), long task 會阻塞 main thread 的運行, 如下是兩種解決方案。
Web Workerapp.js 代碼如下:
import React, {useEffect} from "react" import WorkerCode from "./worker" function App() { useEffect(() => { const testWorker = new Worker(WorkerCode) setTimeout(() => { testWorker.postMessage({}) testWorker.onmessage = function(ev) { console.log(ev.data) } }, 5000) }) return ( ); }
worker.js 代碼如下:
const workerCode = () => { self.onmessage = function() { const start = performance.now() while (performance.now() - start < 1000) { } postMessage("done!") } }
此時在輸入框輸入時沒有卡頓的感覺。
Time Slicing下面是另外一種使頁面流暢的方法 —— Time Slicing(時間分片)。
觀察 Chrome 的 Performance, 火焰圖如下,
從火焰圖可以看出主線程被拆分為了多個時間分片, 所以不會造成卡頓。時間分片的代碼片段如下所示:
function timeSlicing(gen) { if (typeof gen === "function") gen = gen() if (!gen || typeof gen.next !== "function") return (function next() { const res = gen.next() // ① if (res.done) return // ⑤ setTimeout(next) // ③ })() } // 調用時間分片函數 timeSlicing(function* () { const start = performance.now() while (performance.now() - start < 1000) { console.log("執行邏輯") yield // ② } console.log("done") // ④ })
該函數雖然代碼量不長, 但卻不易理解。前置知識 Generator
下面對該函數進行分析:
往時間分片函數 timeSlicing 中傳入 generator 函數;
函數的執行順序 —— ①、②、③、① (此時有個競賽的關系, 如果 performance.now() - start < 1000 則繼續 ②、③, 如果 performance.now() - start >= 1000 則跳出循環執行 ④、⑤);
conclusion針對 long task 會阻塞 main thread 的運行的情形, 給出兩種解決方案:
Web Worker: 使用 Web Worker 提供的多線程環境來處理 long task;
Time Slicing: 將主線程上的 long task 進行時間分片;
保證被動交互讓用戶感覺流暢保證 16.7ms 有新的一幀傳輸到界面上。除去用戶的邏輯代碼, 一幀內留給瀏覽器整合的時間大概只有 6ms 左右, 回到像素管道上來, 我們可以從這幾方面進行優化:
避免 CSS 選擇器嵌套過深Style 這部分的優化在 css 樣式選擇器的使用, css 選擇器使用的層級越多, 耗費的時間越多。以下是測試 css 選擇器不同層級篩選相同元素的一次測試結果。
div.box:not(:empty):last-of-type span 2.25ms index.html:85 .box--last span 0.28ms index.html:85 .box:nth-last-child(-n+1) span 2.51ms避免布局重排
// 先修改值 el.style.witdh = "100px" // 后取值 const width = el.offsetWidth
這段代碼有什么問題呢?
可以看到它會造成布局重排。
應對的策略是調整它們的執行順序,
// 先取值 const width = el.offsetWidth // 后修改值 el.style.witdh = "100px"
可以看到經過調換順序后, 后執行的 el.style.width 會新開一個像素管道, 而不會在原先的像素管道進行重排。
此外不要在循環中執行如下的操作,
for (var i = 0; i < 1000; i++) { const newWidth = container.offsetWidth; // ① boxes[i].style.width = newWidth + "px"; // ② }
可以在火焰圖中看到它發生了重繪的警告,
執行順序是 ①②①②①②①..., 假若我們在第一個 ① 后面插入一條豎線后 ①|②①②①②①, 其就變成先修改值后取值的情景, 所以也就發生了重繪!
正確的使用姿勢應該如下:
const newWidth = container.offsetWidth; for (var i = 0; i < 1000; i++) { boxes[i].style.width = newWidth + "px"; }避免重繪
創建 Layers(圖層) 可以避免重繪,
{ transform: translateZ(0); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/109839.html
導語▼上篇講到產品的一致性是產品的金鑰匙,通過對一致性的設計可以使產品在品牌標識、用戶使用和開發效率等方面得到提升。交互設計對于產品有哪些價值呢?本質是站在多維角度挖掘,分析,梳理,提煉用戶更深層?的?需求和痛點?,利用交互理論方法,保證產品的設計完整性,產品用戶體驗的流暢性,產品商業價值的最大化。What|什么是交互設計?我們的日常生活中處處可見交互行為,從使用淘寶購物到掃場所碼向防疫人員展示核...
摘要:騰訊瀏覽服務是致力于優化移動端體驗的解決方案由瀏覽器團隊出品使用騰訊瀏覽服務內核和騰訊瀏覽服務云端服務解決移動端使用過程中出現的拖拽不流暢切換留白窗口閃爍等問題。 這是一個移動互聯的時代,這是一個屬于Android,屬于iOS的時代,在響應大眾創業萬眾創新的號召下,越來越多的開發者轉向了移動開發的領域。在Android,iOS剛剛興起的時候,對于開發者而言,要開發一整套完整的App是一...
摘要:如何挑選合適的導航結構導航設計是應用設計的關鍵,設計規范以下簡稱規范中將導航元素分為對等層次和歷史導航等幾類,例如表和透視表導航窗格是對等導航元素,中心大綱細節屬于分層導航元素,返回則屬于歷史導航元素。 此文已由作者楊凱明授權網易云社區發布。 歡迎訪問網易云社區,了解更多網易技術產品運營經驗。 繼Windows 10系統發布之后,很多Windows用戶更新了系統。win10系統的發布,...
摘要:那該如何是好原題給出思路是讓事件負責標記按鍵就好了,而方向鍵的事件處理使用設個周期比較小的定時器持續監聽,由于周期小,長按時就會立刻執行相應的事件處理,效果更加流暢。閃爍實現效果閃爍簡單的一個定時器應用,用或都可以實現。 0x1模擬select控件 實現效果:5-01模擬select控件 比較簡單的點擊事件處理,也就處理點擊選擇框展示菜單、點擊菜單選擇、點擊頁面任意角落隱藏菜單這三件事...
閱讀 3415·2021-11-24 09:38
閱讀 3193·2021-11-22 09:34
閱讀 2107·2021-09-22 16:03
閱讀 2367·2019-08-29 18:37
閱讀 379·2019-08-29 16:15
閱讀 1770·2019-08-26 13:56
閱讀 865·2019-08-26 12:21
閱讀 2207·2019-08-26 12:15