web頁面渲染性能-概述(谷歌開發(fā)規(guī)范)

作為一名web開發(fā),總是希望自己開發(fā)web頁面具有交互性并且運(yùn)行順暢,為了順暢運(yùn)行,滾動應(yīng)與手指的滑動一樣快,并且動畫和交互應(yīng)如絲綢般順滑

60fps與設(shè)備刷新率

目前大多數(shù)設(shè)備的屏幕刷新率為 60 次/秒芹血。因此,如果在頁面中有一個動畫或漸變效果,或者用戶正在滾動頁面祟牲,那么瀏覽器渲染動畫或頁面的每一幀的速率也需要跟設(shè)備屏幕的刷新率保持一致隙畜。
其中每個幀的預(yù)算時間僅比 16 毫秒多一點(diǎn) (1 秒/ 60 = 16.66 毫秒)。但實(shí)際上说贝,瀏覽器有整理工作要做议惰,因此您的所有工作需要在 10 毫秒內(nèi)完成。如果無法符合此預(yù)算乡恕,幀率將下降言询,并且內(nèi)容會在屏幕上抖動。 此現(xiàn)象通常稱為卡頓傲宜,會對用戶體驗(yàn)產(chǎn)生負(fù)面影響运杭。


性能圖片

像素管道

web頁面其實(shí)就是把html、css函卒、js中寫的邏輯辆憔,映射到屏幕上的像素,主要包括一下五個主要區(qū)域


像素合成過程
  • JavaScript报嵌。一般來說虱咧,我們會使用 JavaScript 來實(shí)現(xiàn)一些視覺變化的效果。比如用 jQuery 的 animate 函數(shù)做一個動畫锚国、對一個數(shù)據(jù)集進(jìn)行排序或者往頁面里添加一些 DOM 元素等腕巡。當(dāng)然,除了 JavaScript血筑,還有其他一些常用方法也可以實(shí)現(xiàn)視覺變化效果绘沉,比如:CSS Animations、Transitions 和 Web Animation API豺总。
  • 樣式計算车伞。此過程是根據(jù)匹配選擇器(例如 .headline 或 .nav > .nav__item)計算出哪些元素應(yīng)用哪些 CSS 規(guī)則的過程。從中知道規(guī)則之后喻喳,將應(yīng)用規(guī)則并計算每個元素的最終樣式另玖。
  • 布局。在知道對一個元素應(yīng)用哪些規(guī)則之后沸枯,瀏覽器即可開始計算它要占據(jù)的空間大小及其在屏幕的位置。網(wǎng)頁的布局模式意味著一個元素可能影響其他元素赂弓,例如 <body> 元素的寬度一般會影響其子元素的寬度以及樹中各處的節(jié)點(diǎn)绑榴,因此對于瀏覽器來說,布局過程是經(jīng)常發(fā)生的盈魁。
  • 繪制翔怎。繪制是填充像素的過程。它涉及繪出文本、顏色赤套、圖像飘痛、邊框和陰影,基本上包括元素的每個可視部分容握。繪制一般是在多個表面(通常稱為層)上完成的宣脉。
  • 合成。由于頁面的各部分可能被繪制到多層剔氏,由此它們需要按正確順序繪制到屏幕上塑猖,以便正確渲染頁面。對于與另一元素重疊的元素來說谈跛,這點(diǎn)特別重要羊苟,因?yàn)橐粋€錯誤可能使一個元素錯誤地出現(xiàn)在另一個元素的上層。

整個繪制過程中感憾,頁面都有機(jī)會產(chǎn)生卡頓蜡励,因?yàn)槲覀儽仨毐WC代碼觸發(fā)鏈路上的那部分邏輯
在網(wǎng)頁合成的過程中,也許聽過“柵格化”阻桅,這是因?yàn)槔L制過程中分為兩個步驟

  1. 創(chuàng)建繪圖調(diào)用的列表
  2. 填充像素(柵格化)

不一定每一幀都是會經(jīng)過這個管道的每一個部分凉倚,實(shí)際上不管是使用js,css鳍刷,還是網(wǎng)絡(luò)動畫占遥,在實(shí)現(xiàn)視覺變化時,管道針對指定幀運(yùn)行通常有三種方式

1. JS/CSS >樣式 > 布局 > 繪制 > 合成

完整鏈路

如果您修改元素的“l(fā)ayout”屬性输瓜,也就是改變了元素的幾何屬性(例如寬度瓦胎、高度、左側(cè)或頂部位置等)尤揣,那么瀏覽器將必須檢查所有其他元素搔啊,然后“自動重排”頁面。任何受影響的部分都需要重新繪制北戏,而且最終繪制的元素需進(jìn)行合成负芋。

2. JS / CSS > 樣式 > 繪制 > 合成

重繪

如果您修改“paint only”屬性(例如背景圖片、文字顏色或陰影等)嗜愈,即不會影響頁面布局的屬性旧蛾,則瀏覽器會跳過布局,但仍將執(zhí)行繪制蠕嫁。

3. JS / CSS > 樣式 > 合成

直接合成

如果您更改一個既不要布局也不要繪制的屬性锨天,則瀏覽器將跳到只執(zhí)行合成。
這個最后的版本開銷最小剃毒,最適合于應(yīng)用生命周期中的高壓力點(diǎn)病袄,例如動畫或滾動搂赋。

性能在多數(shù)情況下,我們必須和瀏覽器配合益缠,也不是跟他對著干脑奠,值得注意的是,上面列出的各管道工作幅慌,在計算開銷上有所不同宋欺,一些任務(wù)比其他任務(wù)開銷要大的多。

接下來欠痴,持續(xù)分析渲染過程中每一部分

JS執(zhí)行優(yōu)化

JS會經(jīng)常觸發(fā)視覺變化迄靠,有時是直接通過樣式操作,有時是會產(chǎn)生視覺變化的計算喇辽,例如搜索數(shù)據(jù)或?qū)⑵渑判蛘浦浚瑫r機(jī)不當(dāng)或長時間運(yùn)行的JS可能導(dǎo)致性能問題的常見原因。

  • 對于動畫實(shí)現(xiàn)菩咨,避免使用setTimeout或setInterval吠式,請使用requestAnimateFrame
  • 將長時間運(yùn)行的javascript從主線程移動Web Worker
  • 請使用微任務(wù)來執(zhí)行對多個幀的DOM更改
  • 使用 chrome Devtools的Timeline 和javascript分析器來評估對Javascript的影響

使用 requestAnimationFrame 來實(shí)現(xiàn)視覺變化

使用 setTimeout 或 setInterval 來執(zhí)行動畫之類的視覺變化,但這種做法的問題是抽米,回調(diào)將在幀中的某個時點(diǎn)運(yùn)行特占,可能剛好在未尾,而這可能經(jīng)常會使我們丟失幀云茸,導(dǎo)致卡頓


示例圖片

requestAnimationFrame 的基本思想讓頁面重繪的頻率與這個刷新頻率保持同步是目,比如顯示器屏幕刷新率為 60Hz,使用requestAnimationFrame API标捺,那么回調(diào)函數(shù)就每1000ms / 60 ≈ 16.7ms執(zhí)行一次懊纳;如果顯示器屏幕的刷新率為 75Hz,那么回調(diào)函數(shù)就每1000ms / 75 ≈ 13.3ms執(zhí)行一次亡容。

降低復(fù)雜性或使用 Web Worker

JavaScript 在瀏覽器的主線程上運(yùn)行嗤疯,恰好與樣式計算、布局以及許多情況下的繪制一起運(yùn)行闺兢。如果 JavaScript 運(yùn)行時間過長茂缚,就會阻塞這些其他工作,可能導(dǎo)致幀丟失屋谭。

因此脚囊,您要妥善處理 JavaScript 何時運(yùn)行以及運(yùn)行多久。例如桐磁,如果在滾動之類的動畫中悔耘,最好是想辦法使 JavaScript 保持在 3-4 毫秒的范圍內(nèi)。超過此范圍所意,就可能要占用太多時間淮逊。如果在空閑期間,則可以不必那么斤斤計較所占的時間扶踊。

在許多情況下泄鹏,可以將純計算工作移到 Web Worker,例如秧耗,如果它不需要 DOM 訪問權(quán)限备籽。數(shù)據(jù)操作或遍歷(例如排序或搜索)往往很適合這種模型,加載和模型生成也是如此分井。

并非所有工作都適合此模型:Web Worker 沒有 DOM 訪問權(quán)限车猬。如果您的工作必須在主線程上執(zhí)行,請考慮一種批量方法尺锚,將大型任務(wù)分割為微任務(wù)珠闰,每個微任務(wù)所占時間不超過幾毫秒,并且在每幀的 requestAnimationFrame 處理程序內(nèi)運(yùn)行瘫辩。

了解 JavaScript 的“幀稅”

在評估一個框架伏嗜、庫或您自己的代碼時,務(wù)必逐幀評估運(yùn)行 JavaScript 代碼的開銷伐厌。當(dāng)執(zhí)行性能關(guān)鍵的動畫工作(例如變換或滾動)時承绸,這點(diǎn)尤其重要。

測量 JavaScript 開銷和性能情況的最佳方法是使用 Chrome DevTools挣轨。通常军熏,您將獲得如下的簡單記錄:

image.png

如果發(fā)現(xiàn)有長時間運(yùn)行的 JavaScript,則可以在 DevTools 用戶界面的頂部啟用 JavaScript 分析器:


image.png

以這種方式分析 JavaScript 會產(chǎn)生開銷卷扮,因此一定只在想要更深入了解 JavaScript 運(yùn)行時特性時才啟用它荡澎。啟用此復(fù)選框后,現(xiàn)在可以執(zhí)行相同的操作画饥,您將獲得有關(guān) JavaScript 中調(diào)用了哪些函數(shù)的更多信息:


image.png

有了這些信息之后衔瓮,您可以評估 JavaScript 對應(yīng)用性能的影響,并開始找出和修正函數(shù)運(yùn)行時間過長的熱點(diǎn)抖甘。如前所述热鞍,應(yīng)當(dāng)設(shè)法移除長時間運(yùn)行的 JavaScript,或者若不能移除衔彻,則將其移到 Web Worker 中薇宠,騰出主線程繼續(xù)執(zhí)行其他任務(wù)。

避免微優(yōu)化 JavaScript

知道瀏覽器執(zhí)行一個函數(shù)版本比另一個函數(shù)要快 100 倍可能會很酷艰额,比如請求元素的offsetTop比計算getBoundingClientRect()要快澄港,但是,您在每幀調(diào)用這類函數(shù)的次數(shù)幾乎總是很少柄沮,因此回梧,把重點(diǎn)放在 JavaScript 性能的這個方面通常是白費(fèi)勁废岂。您一般只能節(jié)省零點(diǎn)幾毫秒的時間。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狱意,一起剝皮案震驚了整個濱河市湖苞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌详囤,老刑警劉巖财骨,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異藏姐,居然都是意外死亡隆箩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門羔杨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捌臊,“玉大人,你說我怎么就攤上這事兜材⊥奘簦” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵护姆,是天一觀的道長矾端。 經(jīng)常有香客問我,道長卵皂,這世上最難降的妖魔是什么秩铆? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮灯变,結(jié)果婚禮上殴玛,老公的妹妹穿的比我還像新娘。我一直安慰自己添祸,他們只是感情好滚粟,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布忆家。 她就那樣靜靜地躺著中燥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪橙喘。 梳的紋絲不亂的頭發(fā)上耙替,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天亚侠,我揣著相機(jī)與錄音,去河邊找鬼俗扇。 笑死硝烂,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铜幽。 我是一名探鬼主播滞谢,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼串稀,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狮杨?” 一聲冷哼從身側(cè)響起厨诸,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎禾酱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绘趋,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡颤陶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了陷遮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滓走。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖帽馋,靈堂內(nèi)的尸體忽然破棺而出搅方,到底是詐尸還是另有隱情,我是刑警寧澤绽族,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布姨涡,位于F島的核電站,受9級特大地震影響吧慢,放射性物質(zhì)發(fā)生泄漏涛漂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一检诗、第九天 我趴在偏房一處隱蔽的房頂上張望匈仗。 院中可真熱鬧,春花似錦逢慌、人聲如沸悠轩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽火架。三九已至,卻和暖如春忙菠,著一層夾襖步出監(jiān)牢的瞬間距潘,已是汗流浹背只搁。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工音比, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留氢惋,地道東北人稽犁。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像骚亿,于是被迫代替她去往敵國和親已亥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容