日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

浏览器性能优化实战

發布時間:2024/2/28 HTML 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浏览器性能优化实战 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:rosefang,騰訊 PCG 前端開發工程師

當我們在做性能優化的時候,我們究竟在優化什么?瀏覽器底層是一個什么架構?瀏覽器渲染的本質究竟是什么?哪些方面對用戶的體驗影響才是最大的?有沒有業內一些通用的標準或標桿參考?都 1202 年了,雅虎軍規還有沒有用?性能分析工具都有哪些?我們怎么進行打點分析才是合適的?

本文為你一一講解這些。了解了這些問題,可能你在做性能優化的時候才能更加得心應手。

1. 性能優化的本質

1.1 展示更快,響應更快

性能優化的目的,就是為了提供給用戶更好的體驗,這些體驗包含這幾個方面:展示更快、交互響應快、頁面無卡頓情況。

更詳細的說,就是指,在用戶輸入 url 到站點完整把整個頁面展示出來的過程中,通過各種優化策略和方法,讓頁面加載更快;在用戶使用過程中,讓用戶的操作響應更及時,有更好的用戶體驗。

對于前端工程師來說,要做好性能優化,需要理解瀏覽器加載和渲染的本質。理解了本質原理,才能更好的去做優化。所以我們先來看看瀏覽器架構是怎樣的。

1.2 理解瀏覽器多進程架構

從大的方面來說,瀏覽器是一個多進程架構。

它可以是一個進程包含多個線程,也可以是多個進程中,每個進程有多個線程,線程之間通過 IPC 通訊。每個瀏覽器有不同的實現細節,并沒有標準規定瀏覽器必須如何去實現。

這里我們只談論 chrome 架構。

下面這張圖是目前 chrome 的多進程架構圖。

圖片引自 Mariko Kosaka 的《Inside look at modern web browser》

我們來看看這些進程分別對應瀏覽器窗口中的哪一部分:

圖片引自 Mariko Kosaka 的《Inside look at modern web browser》

那么,怎么看瀏覽器對應啟動了什么進程呢?

chrome 中,我們可以通過更多->More Tools->Task Manager 看到啟動的進程。

從 chrome 官網和源碼,我們也可以得知,多進程架構中包含這些進程:

  • Browser 進程:打開瀏覽器后,始終只有一個。該進程有 UI 線程、Network 線程、Storage 線程等。用戶輸入 url 后,首先是 Browser 進程進行響應和請求服務器獲取數據。然后傳遞給 Renderer 進程。

  • Renderer 進程:每一個 tab 一個,負責 html、css、js 執行的整個過程。前端性能優化也與這個進程有關

  • Plugin 進程:與瀏覽器插件相關,例如 flash 等。

  • GPU 進程:瀏覽器共用一個。主要負責把 Renderer 進程中繪制好的 tile 位圖作為紋理上傳到 GPU,并調用 GPU 相關方法把紋理 draw 到屏幕上。

這里的話只是簡單介紹一下瀏覽器的多進程架構,讓大家對瀏覽器整體架構有個初步認識,其實背后的細節還有很多,這里就不一一展開。有興趣可以細看這一系列文章和chrome 官網介紹。

1.3 理解頁面渲染相關進程

1.3.1 Renderer Process & GPU Process

從以上的多架構,我們了解到,與前端渲染、性能優化相關的,其實主要是 Renderer 進程和 GPU 進程。那么,它們又是什么架構呢?

來看一下這張我們再熟悉不過的圖。

圖片引自 Paul 的《The Anatomy of a Frame》
  • Renderer 進程:包括 3 個線程。合成線程(Compositor Thread)、主線程(Main Thread)、Compositor Tile Worker。

  • GPU 進程:只有 GPU 線程,負責接收從 Renderer 進程中的 Compositor Thread 傳過來的紋理,顯示到屏幕上。

1.3.2 Renderer Process 詳解

Renderer 進程中 3 個線程的作用為:

  • Compositor Thread:首先接收 vsync 信號(vsync 信號是指操作系統指示瀏覽器去繪制新的幀),任何事件都會先到達 Compositor 線程。如果主線程沒有綁定事件,那么 Compositor 線程將避免進入主線程,并嘗試將輸入轉換為屏幕上的移動。它將更新的圖層位置信息作為幀通過 GPU 線程傳遞給 GPU 進行繪制。

當用戶在快速滑動過程中,如果主線程沒有綁定事件,Compositor 線程是可以快速響應并繪制的,這是瀏覽器做的一個優化。

  • Main Thread:主線程就是我們前端工程師熟知的線程,這里會執行解析 Html、樣式計算、布局、繪制、合成等動作。所以關于性能的問題,都發生在了這里。所以應該重點關注這里

  • Compositor Tile Worker:由合成線程產生一個或多個 worker 來處理光柵化的工作。

Service Workers 和 Web Workers 可以暫時理解也在 Renderer 進程中,這里不展開討論。

1.3.2.1 Main Thread
main-thread

主線程需要重點講下。因為這是我們的代碼真實存在的環境。

從上一小節 Render 進程和 GPU 進程的圖中,我們可以看到有個紅色的箭頭,從 Recal Styles 和 Layout 指向了 requestAnimationFrame,這意味著有 Forced Synchronous Layout (or Styles)(強制回流和重繪)發生,這一點在性能方面特別要注意。

在 Main Thread 中,有這幾個需要注意一下:

  • requestAnimationFrame:因為布局和樣式計算是在 rAF 之后,所以在 rAF 是進行元素變更的理想時機。如果在這里對一個元素變更 100 個類,不會進行 100 次計算,它們會分批以后處理。需要注意的是,不能在 rAF 中查詢任何計算樣式和布局的屬性(例如:el.style.backgroundImage 或 el.style.offsetWidth),因為這樣會導致重繪和回流。

  • Layout:布局的計算通常是針對整個文檔的,并且與 DOM 元素的大小成正比!(這點特別要注意,如果一個頁面 DOM 元素太多,也會導致性能問題)

主線程的順序始終都是:

Input?Event?Handler->requestAnimationFrame->ParseHtml->ReculateStyles->Layout-?>Update?Layer?Tree->Paint->Composite->commit->requestIdleCallback

只能從前往后,例如,必須先是 ReculateStyles,然后 Layout、然后 Paint。但是,如果它只需要做最后一步 Paint,那么這就是它全部要做的事情,不會再發生前面的 ReculateStyles 和 Layout。

這里其實給了我們一個啟示:如果要讓 fps 保持 60,即每幀的 js 執行時間少于 16.66ms,那么讓這個主線程執行的過程盡可能地少,是我們的性能優化目標

根據主線程的這些步驟,理想的情況下,我們只希望瀏覽器只發生最后一個步驟:Composite(合成)。

CSS 的屬性是我們需要關注一下的模塊。這里有描述了哪些CSS 屬性會引起重繪、回流和合成。例如,讓我們給一個元素進行移動位置時:transform和opacity可以直接觸發合成,但是left和top卻會觸發 Layout、Paint、Composite3 個動作。所以顯然用 transform 時更好的方案。

但這并不是說我們不應該用 left 和 top 這些可能引起重繪回流的屬性,而是應該關注每個屬性在瀏覽器性能中引起的效果

2. 看看經典:雅虎軍規

多年前雅虎的 Nicolas C. Zakas 提出 7 個類別 35 條軍規,至今為止很多前端優化準則都是圍繞著這個展開。如果嚴格按照這些規則去做,其實我們有很多優化工作可以做,只要認真踐行,性能提升不是問題。

我們來看看它 7 個分類都是圍繞哪些方面展開:

  • Server:與頁面發起請求的相關;

  • Cookie:與頁面發起請求相關;

  • Mobile:與頁面請求相關;

  • Content:與頁面渲染相關;

  • Image:與頁面渲染相關;

  • CSS:與頁面渲染相關;

  • Javascript:與頁面渲染和交互相關。

從上面的描述可以看到,其實雅虎軍規,是圍繞頁面發起請求那一刻,到頁面渲染完成,頁面開始交互這幾個方面來展開,提出的一些原則。

很多原則大家也都耳熟能詳,就不全部展開了,有興趣的同學可以去查看原文。這里主要想提一些忽略但是又值得注意的點:

減少 DOM 節點數量

為什么要減少 DOM 節點的數量?

當遍歷查詢 500 和 5000 個 DOM 節點,進行事件綁定時,會有所差別。

當一個頁面 DOM 節點過多,應該考慮使用無限滾動方案來使視窗節點可控。可以看看google 提的方案。

減少 cookie 大小

cookie 傳輸會造成帶寬浪費,影響響應時間,可以這樣做:

消除不必要的 cookies;

靜態資源不需要 cookie,可以采用其他的域名,不會主動帶上 cookie。

避免圖片 src 為空

圖片 src 為空時,不同瀏覽器會有不同的副作用,會重新發起一起請求。

3. 性能指標

3.1 什么樣的性能指標才能真正代表用戶體驗?

要衡量性能,我們必須有一些客觀的、可衡量的指標來進行監控。但是客觀且定量可衡量的指標不一定能反映用戶的真實體驗

以前,我們會用 load 事件的觸發來衡量一個頁面是否加載或顯示完成。但是設想會不會有這樣的情況:一個頁面的 load 事件已經被觸發,但是卻在 load 事件之后幾秒才開始加載內容和渲染頁面,所以這個時候,load 事件并不能真實反映用戶看到內容的時刻。

在過去幾年,google 團隊和W3C 性能工作組致力于提供標準的性能 API 來真正衡量用戶的體驗。主要是從這 4 個方面思考:

思考點詳細內容
Is it happening?導航是否成功,服務器是否響應了
Is it useful?是否已經渲染了足夠的內容,讓用戶可以開始參與其中
Is it usable?用戶是否可以與頁面交互,頁面是否處于繁忙狀態
Is it delightful?交互是否流暢、自然、沒有滯后反映或卡頓

通常有 2 種途徑來衡量性能。

  • 本地實驗衡量:本地模擬用戶的網絡、設備等情況進行測試。通常在開發新功能的時候,實驗測量是很重要的,因為我們不知道這個功能發布到線上會有什么性能問題,所以提前進行性能測試,可以進行預防。

  • 線上衡量:實驗測量固然可以反映一些問題,但無法反映在用戶那里真實的情況。同樣的,在用戶那里,性能問題會和用戶的設備、網絡情況有關,而且還跟用戶如何與頁面進行交互有關。

  • 有這幾個類型與用戶感知性能相關。

    • 頁面加載時間:頁面以多快的速度加載和渲染元素到頁面上。

    • 加載后響應時間:頁面加載和執行 js 代碼后多久能響應用戶交互。

    • 運行時響應:頁面加載完成后,對用戶的交互響應時間。

    • 視覺穩定性:頁面元素是否會以用戶不期望的方式移動,并干擾用戶的交互。

    • 流暢度:過渡和動畫是否以一致的幀率渲染,并從一種狀態流暢地過渡到另一種狀態。

    對應上面幾種分類,Google 和 W3C 性能工作組提供了對應這幾種性能指標:

    • First contentful paint (FCP): 測量頁面開始加載到某一塊內容顯示在頁面上的時間。

    • Largest contentful paint (LCP): 測量頁面開始加載到最大文本塊內容或圖片顯示在頁面中的時間。

    • First input delay (FID): 測量用戶首次與網站進行交互(例如點擊一個鏈接、按鈕、js 自定義控件)到瀏覽器真正進行響應的時間。

    • Time to Interactive (TTI): 測量從頁面加載到可視化呈現、頁面初始化腳本已經加載,并且可以可靠地快速響應用戶的時間。

    • Total blocking time (TBT): 測量從 FCP 到 TTI 之間的時間,這個時間內主線程被阻塞無法響應用戶輸入。

    • Cumulative layout shift (CLS): 測量從頁面開始加載到狀態變為隱藏過程中,發生不可預期的 layout shifts 的累積分數。

    這些指標能從一定程度上衡量頁面性能,但不一定都是有效的。舉個例子。LCP 指標主要用戶衡量頁面的主要內容是否完成加載,但會有這樣的情況,最大的元素并不是主要內容,那么這個時候 LCP 指標并不是那么重要。

    每個不同的站點有自己的特殊性,可以參考以上角度進行衡量,也需要因地制宜。

    3.2 Core Web Vitals

    在以上列出的指標中,Google 定義了 3 個最核心的指標,作為 Core Web Vitals。它們分別代表著:加載、交互、視覺穩定性。

    image-20210426192204425
    • Largest Contentful Paint (LCP): 測量加載性能。為了能提供較好的用戶體驗,LCP 指標建議頁面首次加載要在 2.5s 內完成。

    • First Input Delay (FID): 測量交互性能。為了提供較好用戶體驗,交互時間建議在 100ms 或以內。

    • Cumulative Layout Shift (CLS): 測量視覺穩定性。為了提供較好用戶體驗,頁面應該維持 CLS 在 0.1 或以內。

    當頁面訪問量有 75%的數據達到了以上以上 Good 的標準,則認為性能是不錯的了。

    Core Web Vitals 是作為核心性能指標,但是其他指標也同樣在重要,是做為核心指標的一個輔助。例如,TTFB 和 FCP 都可以用來衡量加載性能(服務器響應時間和渲染時間),它們作為 LCP 的一個問題手段輔助。同樣的,TBT 和 TTI 對于衡量交互性能也很重要,是 FID 的一個輔助,但是它們無法在線上進行測量,也無法反映以用戶為中心的結果。

    Google 官方提供了一個web-vitals庫,線上或本地都可以測量上面提到的 3 個指標:

    import?{getCLS,?getFID,?getLCP}?from?'web-vitals';function?sendToAnalytics(metric)?{const?body?=?JSON.stringify(metric);//?Use?`navigator.sendBeacon()`?if?available,?falling?back?to?`fetch()`.(navigator.sendBeacon?&&?navigator.sendBeacon('/analytics',?body))?||fetch('/analytics',?{body,?method:?'POST',?keepalive:?true}); }getCLS(sendToAnalytics); getFID(sendToAnalytics); getLCP(sendToAnalytics);

    下面,分別講講這 3 個指標定義的原因、如何測量、如何優化。

    3.2.1 Largest Contentful Paint (LCP)
    3.2.1.1 LCP 如何定義
    圖片來自LCP

    LCP 是指頁面開始加載到最大文本塊內容或圖片顯示在頁面中的時間。那么哪些元素可以被定義為最大元素呢?

    • <img>標簽

    • <image> 在 svg 中的 image 標簽

    • <video> video 標簽

    • CSS background url()加載的圖片

    • 包含內聯或文本的塊級元素

    3.2.1.2 如何測量 LCP

    線上測量工具

    • Chrome User Experience Report

    • PageSpeed Insights

    • Search Console (Core Web Vitals report)

    • web-vitals JavaScript library

    實驗室工具

    • Chrome DevTools

    • Lighthouse

    • WebPageTest

    原生的 JS API 測量

    LCP 還可以用 JS API 進行測量,主要使用 PerformanceObserver 接口,目前除了 IE 不支持,其他瀏覽器基本都支持了。

    new?PerformanceObserver((entryList)?=>?{for?(const?entry?of?entryList.getEntries())?{console.log('LCP?candidate:',?entry.startTime,?entry);} }).observe({type:?'largest-contentful-paint',?buffered:?true});

    我們看一下結果是怎樣的:

    LCP-example

    Google 官方 web-vitals 庫

    Google 官方也提供了一個web-vitals庫,底層還是使用這個 API,只是幫我們處理了一些需要測量和不需測量的場景、以及一些細節問題。

    3.2.1.3 如何優化 LCP

    LCP 可能被這四個因素影響:

    • 服務端響應時間

    • Javascript 和 CSS 引起的渲染卡頓

    • 資源加載時間

    • 客戶端渲染

    更加詳細的優化建議就不展開了,可以參考這里。

    3.2.2 First Input Delay (FID)
    3.2.2.1 FID 如何定義
    圖片來自FID

    我們都知道第一印象的重要性,比如初次遇到某人形成的印象,會在后續交往中起重要的影響。對于一個網站也是如此。

    網站以多快的速度加載完成是其中一項指標,加載后以多快的速度對用戶進行響應也同樣重要。FID 就是指后者。

    可以通過下面的圖來更詳細了解 FID 處于哪個位置:

    圖片來自FID

    從上圖可以看出,當主線程處于繁忙的時候,FID 是指從瀏覽器接收到了用戶輸入,到瀏覽器對用戶的輸入進行響應的延遲時間。

    通常,當我們在寫代碼的時候,會認為只要用戶輸入信息,我們的事件回調就會立刻響應,但實際上并不是這樣。這是主線程可能處于繁忙,瀏覽器正忙著解析和執行其他 js。如上圖所示的 FID 時間,主線程正在處理其他任務。

    當 FID 的時間為 100ms 或以內,則為 Good。

    上面的例子中,用戶剛好在主線程最繁忙的時刻進行了交互,但是如果用戶在主線程空閑的時候交互,那么瀏覽器可以立刻響應。所以 FID 的值需要重點查看它的分布情況。

    FID 實際上測量的是輸入事件被感知到到主線程空閑的這段時間。這意味著即使沒有輸入事件被注冊,FID 也可以測量。因為用戶的輸入相應并不一定需要事件被執行,但一定需要主線程是空閑的。例如,下面這些 HTML 元素都需要在交互響應之前等待主線程上的正在執行的任務完成:

    • 輸入框,例如<input>、<textarea>、<radio>、<checkbox>

    • 下拉框,例如<select>

    • 鏈接,例如<a>

    為什么要考慮測量第一次的輸入延遲?有如下原因:

    • 因為第一次輸入延遲是用戶對你的網站形成的第一個印象,網站是否有質量且可靠;

    • 在今天,web 中最大的交互問題第一次加載之后;

    • 對于網站應該如何解決較高的首次輸入延遲(例如代碼分割、減少 JavaScript 的預加載)的建議解決方案(TTI 是指衡量這一塊),不一定與在頁面加載后解決輸入延遲(FID 是指衡量這一塊)的解決方案相同。所以 FID 是在 TTI 的基礎上更精確的細分。

    為什么 FID 只是包含從用戶輸入到主線程開始相應的時間?而沒有包含事件處理到瀏覽器繪制 UI 的時間?

    盡管主線程處理和繪制的這段時間也很重要,但是如果 FID 把這段時間也包含進來,開發者可能會使用異步 API(例如setTimeout、requestAnimationFrame)來把這個 task 拆分到下一幀,以較少 FID 的時間,這樣不僅沒有提高用戶體驗,反而使用戶體驗降低。

    3.2.2.2 如何測量 FID

    FID 可以在實驗環境也可以在線上環境測量。

    線上測量工具

    • Chrome User Experience Report

    • PageSpeed Insights

    • Search Console (Core Web Vitals report)

    • web-vitals JavaScript library

    原生的 JS API 測量

    new?PerformanceObserver((entryList)?=>?{for?(const?entry?of?entryList.getEntries())?{const?delay?=?entry.processingStart?-?entry.startTime;console.log('FID?candidate:',?delay,?entry);} }).observe({type:?'first-input',?buffered:?true});

    PerformanceObserver 目前除了在 IE 上沒有兼容,其他瀏覽器基本都兼容了。

    我們看一下結果是怎樣的:

    FID-example

    Google 官方 web-vitals 庫

    Google 官方也提供了一個web-vitals庫,底層還是使用這個 API,只是幫我們處理了一些需要測量和不需測量的場景、以及一些細節問題。

    3.2.2.3 如何優化 FID

    FID 可能被這四個因素影響:

    • 減少第三方代碼的影響

    • 減少 Javascript 的執行時間

    • 最小化主線程工作

    • 減小請求數量和請求文件大小

    更加詳細的優化建議可以參考這里。

    3.2.3 Cumulative Layout Shift (CLS)
    3.2.3.1 CLS 如何定義
    圖片來自CLS

    CLS 是一個非常重要的、以用戶為中心的測量指標。它能衡量頁面是否排版穩定。

    頁面移動會經常發生在資源異步加載、或者 DOM 元素動態添加到已存在的頁面元素上面。這些元素有可能是圖片、視頻、第三方廣告或小圖標等。

    但是我們開發過程中可能不會察覺到這些問題,因為調試過程中刷新頁面,圖片都已經緩存在本地。調試接口的時候我們使用的是 mock 或者在局域網,接口速度都很快,這些延遲都可能被我們忽略。

    CLS 就是幫我們去發現這些真實發生在用戶端的問題的指標。

    CLS 是測量頁面生命周期中,每個發生意外布局移動的分數。當一個可視元素在下一幀移動到另外一個位置,就是指布局移動。

    CLS 的分數在 0.1 或以下,則為 Good。

    那么意外布局移動的分數如何計算?

    瀏覽器會監控兩楨之間發生移動的不穩定元素。布局移動分數由 2 個元素決定:impact fraction 和 distance fraction。

    layout?shift?score?=?impact?fraction?*?distance?fraction

    可視區域內,在前一幀到下一幀之間所有不穩定的元素的并集,會影響當前幀的布局移動分數。

    舉個例子,下面這張圖中,左邊是當前幀的一個元素,下一幀中,元素下移了可視區域內 25%的高度。紅色虛線框標出了兩楨中當前元素的并集,占適口的 75%,所以這個時候,impact faction 是 0.75。

    另外一個影響布局移動分數的是 distance fraction,指這個元素相對視口移動的距離。不管是橫向還是豎向,取最大值。

    下面例子中,豎向距離更大,該元素相對適口移動了 25%的距離,所以 distance fraction 是 0.25。所以布局移動分數是 0.75 * 0.25 = 0.1875.

    impact-fraction-example

    但是要注意的是,并不是所有的布局移動都是不好的,很多 web 網站都會改變元素的開始位置。只有當布局移動是非用戶預期的,才是不好的

    換句話說,當用戶點擊了按鈕,布局進行了改動,這是 ok 的,CLS 的 JS API 中有一個字段hadRecentInput,用來標識 500ms 內是否有用戶數據,視情況而定,可以忽略這個計算。

    3.2.3.2 如何測量 CLS

    線上測量工具

    • Chrome User Experience Report

    • PageSpeed Insights

    • Search Console (Core Web Vitals report)

    • web-vitals JavaScript library

    實驗室工具

    • Chrome DevTools

    • Lighthouse

    • WebPageTest

    原生的 JS API 測量

    let?cls?=?0;new?PerformanceObserver((entryList)?=>?{for?(const?entry?of?entryList.getEntries())?{if?(!entry.hadRecentInput)?{cls?+=?entry.value;console.log('Current?CLS?value:',?cls,?entry);}} }).observe({type:?'layout-shift',?buffered:?true});

    我們看一下結果是怎樣的:

    CLS-example

    Google 官方 web-vitals 庫

    Google 官方也提供了一個web-vitals庫,底層還是使用這個 API,只是幫我們處理了一些需要測量和不需測量的場景、以及一些細節問題。

    3.2.3.3 如何優化 CLS

    我們可以根據這些原則來避免非預期布局移動:

    • 圖片或視屏元素有大小屬性,或者給他們保留一個空間大小,設置 width、height,或者使用unsized-media feature policy。

    • 不要在一個已存在的元素上面插入內容,除了相應用戶輸入。

    • 使用 animation 或 transition 而不是直接觸發布局改變。

    更詳細的內容可以看這里。

    4. 性能工具:工欲善其事,必先利其器

    Google 開發的所有工具都支持 Core Web Vitals 的測量。工具如下:

    • Lighthouse

    • PageSpeed Insights

    • Chrome DevTools

    • Search Console

    • web.dev's 提供的測量工具

    • Web Vitals 擴展

    • Chrome UX Report API

    tools-all

    這些工具對 Core Web Vitals 的支持如下:

    tools

    4.1 Lighthouse

    打開 F12,就可以看到 Lighthouse,點擊 Generate Report,即可生成報告。當然也可以添加 chrome 插件使用。

    lighthouse

    Lighthhouse 是一個實驗室工具,本地模擬移動端和 PC 端對這幾個方面進行測試。同時 lighthouse 還會針對這幾個方面提出建議,在產品上線前值得一測。

    lighthouse-func

    Lighthouse 還提供了Lighthouse CI,把 Lighthouse 集成到 CI 流水線中。舉個例子,每次在上線之前,跑 50 次流水線對 Lighthouse 的各項指標進行測試取平均值,一旦發現異常,立刻進行排查。把性能問題排查提前到發布之前。這塊后面會細講。

    4.2 PageSpeed Insights

    PageSpeed Insights(PSI)是一個可以分析線上和實驗室數據的工具。它是根據線上環境用戶真實的數據(在 Chrome UX 報告中)和 Lighthouse 結合出一份報告。和 Lighthouse 類似,它也會給出一些分析建議,可以知道頁面的 Core Web Vitals 是否達標。

    PageSpeed-demo

    PageSpeed 只是提供對單個頁面的性能測試,而 Search Console 是正對整個網站的性能測試。

    PageSpeed Insights 也提供了API供我們使用。同樣的,我們也可以把它集成到 CI 中。

    4.3 CrUX

    Chrome UX Report (CrUX)是指匯聚了成千上萬條用戶體驗數據的數據報告集,它是經過用戶同意才進行上報的,目前存儲在 Google BigQuery 上,可以使用賬號登陸進行查詢。它測量了所有的 Core Web Vitals 指標。

    上面提到的 PageSpeed Insights 工具就是結合 CrUX 的數據進行分析給出的結論。

    當然 CrUX 現在也提供了 API 共我們進行查詢,可以查詢的數據包括:

    • Largest Contentful Paint

    • Cumulative Layout Shift

    • First Input Delay

    • First Contentful Paint

    原理如下:

    CrUX

    通過 API 的查詢的數據每日都更新,并匯集了過去 28 天的數據。

    具體的使用方式可以參考官方給出的demo。

    4.4 Chrome DevTools Performance 面板

    Performance 是我們最常用的本地性能分析工具。

    devtools-panel

    這里像提幾點可以關注下的功能:Frame、Timings、Main、Layers、FPS。下面一一講解。

    4.4.1 Frame

    點擊 Frame 展開后,會看到有一個一個紅色或綠色小塊,這些代表著每幀的消耗時間。目前大多數設備的屏幕刷新率為 60 次/秒,瀏覽器渲染頁面的每一幀的速率如果與設備屏幕的刷新率保持一致,即 60fps 時,我們是不會感知到頁面卡的情況的。

    我們把鼠標移上去看看:

    frame-58

    這種是體驗順暢的情況。

    再比如:

    frame-32

    提示這一幀耗時了 30.9ms,當前是 32fps 并且是掉幀狀態。

    4.4.2 Timings

    這里可以看到幾個關鍵指標的時間點。

    FP:First Paint;

    FCP:First Contentful Paint;

    LCP:Largest Contenful Paint;

    DCL:DOMContentLoaded Event

    L:OnLoad Event。

    timings
    4.4.3 Main

    Main 是 DevTools 中最常用也是最重要的功能。

    main

    通過 record,我們可以查看頁面上所有操作在主線程中的執行過程。也就是我們常說的流程:

    main-thread

    一旦有任何一個流程時間過長或頻繁發生,比如 Update Layer Tree 時間過長、頻繁出現 RecalcStyles、Layout(重繪回流),那么需要引起注意。后面會舉一個例子。

    4.4.4 Layers

    Layers 是瀏覽器在繪制過程中生成的一個層。因為瀏覽器底層渲染的本質是縱向分層、橫向分塊。這一塊的知識點是發生在 Renderer Process 進程中。后面會以一個例子展開講。

    這里想提 Layers 的原因是,Layer 的渲染也會影響性能問題,而且有時候還不容易被發現!

    Layers 面板一般不會默認展示出來,點擊更多->more tools->Layers 即可打開。

    點擊 Layers 面板,點擊左邊下三角展開按鈕,可以看見頁面最終生成的合成層。右邊左上角可以選擇不同緯度進行查看。

    layers-detail

    選中某個層,可以查看該層生成的原因。

    layer-reason

    Chrome 的 Blink 內核給出了 54 種會生成合成層的原因:

    constexpr?CompositingReasonStringMap?kCompositingReasonsStringMap[]?=?{{CompositingReason::k3DTransform,?"transform3D",?"Has?a?3d?transform"},{CompositingReason::kTrivial3DTransform,?"trivialTransform3D","Has?a?trivial?3d?transform"},{CompositingReason::kVideo,?"video",?"Is?an?accelerated?video"},{CompositingReason::kCanvas,?"canvas","Is?an?accelerated?canvas,?or?is?a?display?list?backed?canvas?that?was?""promoted?to?a?layer?based?on?a?performance?heuristic."},{CompositingReason::kPlugin,?"plugin",?"Is?an?accelerated?plugin"},{CompositingReason::kIFrame,?"iFrame",?"Is?an?accelerated?iFrame"},{CompositingReason::kSVGRoot,?"SVGRoot",?"Is?an?accelerated?SVG?root"},{CompositingReason::kBackfaceVisibilityHidden,?"backfaceVisibilityHidden","Has?backface-visibility:?hidden"},{CompositingReason::kActiveTransformAnimation,?"activeTransformAnimation","Has?an?active?accelerated?transform?animation?or?transition"},{CompositingReason::kActiveOpacityAnimation,?"activeOpacityAnimation","Has?an?active?accelerated?opacity?animation?or?transition"},{CompositingReason::kActiveFilterAnimation,?"activeFilterAnimation","Has?an?active?accelerated?filter?animation?or?transition"},{CompositingReason::kActiveBackdropFilterAnimation,"activeBackdropFilterAnimation","Has?an?active?accelerated?backdrop?filter?animation?or?transition"},{CompositingReason::kXrOverlay,?"xrOverlay","Is?DOM?overlay?for?WebXR?immersive-ar?mode"},{CompositingReason::kScrollDependentPosition,?"scrollDependentPosition","Is?fixed?or?sticky?position"},{CompositingReason::kOverflowScrolling,?"overflowScrolling","Is?a?scrollable?overflow?element"},{CompositingReason::kOverflowScrollingParent,?"overflowScrollingParent","Scroll?parent?is?not?an?ancestor"},{CompositingReason::kOutOfFlowClipping,?"outOfFlowClipping","Has?clipping?ancestor"},{CompositingReason::kVideoOverlay,?"videoOverlay","Is?overlay?controls?for?video"},{CompositingReason::kWillChangeTransform,?"willChangeTransform","Has?a?will-change:?transform?compositing?hint"},{CompositingReason::kWillChangeOpacity,?"willChangeOpacity","Has?a?will-change:?opacity?compositing?hint"},{CompositingReason::kWillChangeFilter,?"willChangeFilter","Has?a?will-change:?filter?compositing?hint"},{CompositingReason::kWillChangeBackdropFilter,?"willChangeBackdropFilter","Has?a?will-change:?backdrop-filter?compositing?hint"},{CompositingReason::kWillChangeOther,?"willChangeOther","Has?a?will-change?compositing?hint?other?than?transform?and?opacity"},{CompositingReason::kBackdropFilter,?"backdropFilter","Has?a?backdrop?filter"},{CompositingReason::kBackdropFilterMask,?"backdropFilterMask","Is?a?mask?for?backdrop?filter"},{CompositingReason::kRootScroller,?"rootScroller","Is?the?document.rootScroller"},{CompositingReason::kAssumedOverlap,?"assumedOverlap","Might?overlap?other?composited?content"},{CompositingReason::kOverlap,?"overlap","Overlaps?other?composited?content"},{CompositingReason::kNegativeZIndexChildren,?"negativeZIndexChildren","Parent?with?composited?negative?z-index?content"},{CompositingReason::kSquashingDisallowed,?"squashingDisallowed","Layer?was?separately?composited?because?it?could?not?be?squashed."},{CompositingReason::kOpacityWithCompositedDescendants,"opacityWithCompositedDescendants","Has?opacity?that?needs?to?be?applied?by?compositor?because?of?composited?""descendants"},{CompositingReason::kMaskWithCompositedDescendants,"maskWithCompositedDescendants","Has?a?mask?that?needs?to?be?known?by?compositor?because?of?composited?""descendants"},{CompositingReason::kReflectionWithCompositedDescendants,"reflectionWithCompositedDescendants","Has?a?reflection?that?needs?to?be?known?by?compositor?because?of?""composited?descendants"},{CompositingReason::kFilterWithCompositedDescendants,"filterWithCompositedDescendants","Has?a?filter?effect?that?needs?to?be?known?by?compositor?because?of?""composited?descendants"},{CompositingReason::kBlendingWithCompositedDescendants,"blendingWithCompositedDescendants","Has?a?blending?effect?that?needs?to?be?known?by?compositor?because?of?""composited?descendants"},{CompositingReason::kPerspectiveWith3DDescendants,"perspectiveWith3DDescendants","Has?a?perspective?transform?that?needs?to?be?known?by?compositor?because?""of?3d?descendants"},{CompositingReason::kPreserve3DWith3DDescendants,"preserve3DWith3DDescendants","Has?a?preserves-3d?property?that?needs?to?be?known?by?compositor?because?""of?3d?descendants"},{CompositingReason::kIsolateCompositedDescendants,"isolateCompositedDescendants","Should?isolate?descendants?to?apply?a?blend?effect"},{CompositingReason::kFullscreenVideoWithCompositedDescendants,"fullscreenVideoWithCompositedDescendants","Is?a?fullscreen?video?element?with?composited?descendants"},{CompositingReason::kRoot,?"root",?"Is?the?root?layer"},{CompositingReason::kLayerForHorizontalScrollbar,"layerForHorizontalScrollbar","Secondary?layer,?the?horizontal?scrollbar?layer"},{CompositingReason::kLayerForVerticalScrollbar,?"layerForVerticalScrollbar","Secondary?layer,?the?vertical?scrollbar?layer"},{CompositingReason::kLayerForScrollCorner,?"layerForScrollCorner","Secondary?layer,?the?scroll?corner?layer"},{CompositingReason::kLayerForScrollingContents,?"layerForScrollingContents","Secondary?layer,?to?house?contents?that?can?be?scrolled"},{CompositingReason::kLayerForSquashingContents,?"layerForSquashingContents","Secondary?layer,?home?for?a?group?of?squashable?content"},{CompositingReason::kLayerForForeground,?"layerForForeground","Secondary?layer,?to?contain?any?normal?flow?and?positive?z-index?""contents?on?top?of?a?negative?z-index?layer"},{CompositingReason::kLayerForMask,?"layerForMask","Secondary?layer,?to?contain?the?mask?contents"},{CompositingReason::kLayerForDecoration,?"layerForDecoration","Layer?painted?on?top?of?other?layers?as?decoration"},{CompositingReason::kLayerForOther,?"layerForOther","Layer?for?link?highlight,?frame?overlay,?etc."},{CompositingReason::kBackfaceInvisibility3DAncestor,"BackfaceInvisibility3DAncestor","Ancestor?in?same?3D?rendering?context?has?a?hidden?backface"}, };
    4.4.5 Rendering

    Rendering 面板也隱藏了很多好用的功能。

    4.4.5.1 Paint flashing

    勾選了 Paint flashing 后,我們就會看到頁面上有哪些內容被重繪了:

    paint-flashing
    4.4.5.2 Layout Shift6 Regions

    勾選了 Layout Shift Regions 后,進行交互,就可以看到哪些元素進行了布局移動:

    layout-shift-regions
    4.4.5.3 Frame Rendering Stats

    這個工具有一個小插曲。

    Frame Rendering Stats 的前身是 FPS meter,在 Google 版本85.0.4181.0改成了 Frame Rendering Stats,但是迫于用戶抱怨,在 90 版本的時候又改回來了。

    Frame Rendering Stats 主要顯示不掉幀率。而 FPS 側重于顯示每秒的刷新率 fps。

    Chrome 為什么要改成不掉幀率,是因為認為不掉幀率更能反映頁面的順暢度。而 FPS 顯示每一秒渲染的幀數雖然能一定程度反映頁面順暢度,但是在一些特殊情況例如沒有激活或空閑的頁面,fps 會比較低,這樣并不能反映真實情況。

    frame-vs-fps

    (圖片引自blink dev 論壇討論)

    4.4.6 Memory

    在大型項目中,內存問題也是有發生。DevTools 也提供了內存分析工具供我們使用。

    點擊 Memory 面板,點擊錄制按鈕。

    memory

    點擊錄制后,會看到當前狀態下內存的占用情況,根據大小排序,我們可以定位到內存占用過多的地方。

    memory-snapshot

    4.5 Search Console

    Google Search Console 其實就是監控和維護網站在 Google 搜索結果中的展示情況以及排查問題的平臺。數據來源是 CrUX。

    它會展示 3 個 Core Web Vitals metrics: LCP, FID, CLS。如果發現有問題,可以配合 PageSpeed 一起使用,分析問題。

    search-console

    (圖片引自 vital-tools)

    4.6 web.dev

    web.dev/measure是 google 官方提供的測量性能工具,也會提供類似 PageSpeed Insight 的指標,還會提供一些具體代碼更改建議。

    web-dev-1web-dev-2

    4.7 Web Vitals extension

    Google 也提供了擴展工具去測量 Core Web Vitals。可以從Store中進行安裝。

    web-vitals-extension

    4.8 工具:思考與總結

    當我們了解了這么多工具之后,琳瑯滿目,我們該如何選擇?如何使用好這些工具進行分析?

    • 首先我們可以使用 Lighthouse,在本地進行測量,根據報告給出的一些建議進行優化;

    • 發布之后,我們可以使用 PageSpeed Insights 去看下線上的性能情況;

    • 接著,我們可以使用 Chrome User Experience Report API 去撈取線上過去 28 天的數據;

    • 發現數據有異常,我們可以使用 DevTools 工具進行具體代碼定位分析;

    • 使用 Search Console's Core Web Vitals report 查看網站功能整體情況;

    • 使用 Web Vitals 擴展方便的看頁面核心指標情況;

    5. 談談監控

    最后一個章節想來談談監控。

    我們在做性能優化的時候,常常會通過各種線上打點,來收集用戶數據,進行性能分析。沒錯,這是一種監控手段,更精確的說,這是一種"事后"監控手段。

    "事后"監控固然重要,但我們也應該考慮"事前"監控,否則,每次發布一個需求后,去線上看數據。咦,發現數據下降了,然后我們去查代碼,去查數據,去查原因。這樣性能優化的同學永遠處于"追趕者"的角色,永遠跟在屁股后面查問題。

    舉個例子,我們可以這樣去做"事前"監控。

    建立流水線機制。流水線上如何做呢?

    • Lighthouse CI 或 PageSpeed Insights API:把 Lighthouse 或 PageSpeed Insights API 集成到 CI 流水線中,輸出報告分析。

    • Puppeteer 或 Playwright:使用 E2E 自動化測試工具集成到流水線模擬用戶操作,得到 Chrome Trace Files,也就是我們平常錄制 Performance 后,點擊左上角下載的文件。Puppeteer 和 Playwright 底層都是基于Chrome DevTools Protocol。

      perf-download
    • Chrome Trace Files:根據規則分析 Trace 文件,可以得到每個函數執行的時間。如果函數執行時間超過了一個臨界值,可以拋出異常。如果一個函數每次的執行時間都超過了臨界值,那么就值得注意了。但是還有一點需要思考的是:函數執行的時間是否超過臨界值固然重要,但更重要的是這是不是用戶的輸入響應函數,與用戶體驗是否有關。

      圖片來自Flo Sloot的Jank: You can measure what your users can feel.
    • 輸出報告。定義異常臨界值。如果異常過多,考慮是否卡發布流程。

    6. 總結

    我們來回顧一下前面的內容:

    第一部分,講了瀏覽器整體架構和渲染相關進程.為什么把這個章節也放到這篇性能優化的文章中?瀏覽器對于我們前端開發來說,是一個 sandbox 或者 darkbox。我們知道 js、html、css 結合起來就能實現我們的需求,但如果知道它是如何去渲染、執行、處理我們的代碼,不管是對做需求還是性能優化,都能更知其然和所以然。

    第二部分,雅虎軍規是多年前提出的非常經典的優化建議。至今對于我們異常有很強的指導作用。你會發現它是從頁面加載、頁面渲染、到頁面交互全面的一個指導建議。與今天 Chrome 和 W3c 提出的 Web Vitals 思路依然類似。

    第三部分,性能指標。參考標準與業內標桿的建議,能更好地指導我們進行優化。

    第四部分,性能工具。工欲善其事,必先利其器。這個道理大家都懂,運用好工具,才能讓我們更加事半功倍。

    第五部分,監控在性能優化中占很重要的部分,"事前"監控更重要,防患于未然。讓性能優化成為一個預防者而不是追趕者。

    羅里吧嗦說了很多,當然還有很多性能優化的細節沒有講到,如果有錯誤的地方歡迎指正。或者有什么好方法好建議也強烈歡迎私聊交流一下。

    沒有困難的工作

    參考文章:

    • https://web.dev/learn-web-vitals/

    • https://developers.google.com/web/updates/2018/09/inside-browser-part1

    • https://aerotwist.com/blog/the-anatomy-of-a-frame/

    • https://www.chromium.org/developers/how-tos/getting-around-the-chrome-source-code

    • https://medium.com/punching-performance/jank-you-can-measure-what-your-users-can-feel-e5713df2845f

    視頻號最新視頻

    總結

    以上是生活随笔為你收集整理的浏览器性能优化实战的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    亚洲伊人色 | 亚洲欧美日韩精品久久久 | 中文字幕在线影视资源 | 免费h漫在线观看 | 中文字幕在线观看完整版电影 | 91精品资源| 亚洲片在线资源 | 亚洲区色| 国产黄免费在线观看 | 日韩精品一区二区三区视频播放 | 中文字幕免费观看全部电影 | 日韩日韩日韩日韩 | 国产99一区视频免费 | 亚洲国产精品视频在线观看 | 亚洲天堂va | 91中文在线 | 久久美女高清视频 | 五月天色站 | 丝袜制服综合网 | 国产色在线,com | 色99色| 日韩一区在线播放 | 99精品国产亚洲 | 一区二区三区免费看 | 亚洲日本中文字幕在线观看 | 在线免费观看国产黄色 | 日韩精品电影在线播放 | 97精品国产97久久久久久粉红 | 在线你懂的视频 | 日本精油按摩3 | 国产第一福利 | 国产永久网站 | 日韩av图片 | 天天爱天天草 | 国产精品久久久久久久久久久免费 | 免费成人av在线 | 欧洲av在线 | 日韩性网站| 久久国产手机看片 | 精品一区二区三区久久久 | 婷婷色网视频在线播放 | 国产最新91 | www欧美日韩| 91视频啊啊啊 | 青青草在久久免费久久免费 | 欧美色图另类 | 伊人www22综合色 | 国产亚洲精品xxoo | 日韩在线观看网址 | 亚洲女裸体 | 91久久奴性调教 | 成人久久久电影 | 青青射| 日本一区二区高清不卡 | 日本中文字幕在线一区 | 91av在线视频免费观看 | 亚洲电影网站 | 亚洲91中文字幕无线码三区 | 99久免费精品视频在线观看 | 国产一区av在线 | 色天天综合久久久久综合片 | 丰满少妇一级片 | 亚洲精品免费在线 | 国产日本三级 | 日韩字幕在线观看 | 日韩在线高清免费视频 | 91在线观看视频 | av视屏在线| 91桃色国产在线播放 | 国产一级二级三级在线观看 | 国产午夜精品一区二区三区欧美 | 五月婷丁香网 | 成人黄性视频 | 日韩网站一区 | 欧美在线一二区 | 久在线| 日韩在线观看不卡 | 激情图片区 | 日韩中文字幕免费视频 | 在线影视 一区 二区 三区 | 国产美女免费观看 | 久久久影片 | 综合网中文字幕 | 午夜视频不卡 | 青青河边草观看完整版高清 | 丁香视频 | 亚洲,国产成人av | 色综合色综合久久综合频道88 | 久久精品亚洲综合专区 | www国产精品com | 香蕉视频4aa| 精品国产伦一区二区三区 | 国产又黄又硬又爽 | 久久久精品小视频 | 91插插插网站 | 欧美精品久久久久久久久老牛影院 | 免费高清在线观看电视网站 | 亚洲激情综合网 | 久久99久久99精品免视看婷婷 | 欧美精品久久久久久久 | 中文字幕国产在线 | 久久久免费毛片 | 国产精品男女视频 | 国产精品人成电影在线观看 | www最近高清中文国语在线观看 | av在线在线 | 懂色av一区二区三区蜜臀 | 国产精品九九热 | 国产又粗又猛又色又黄视频 | 国产一区二区精 | 91网页版免费观看 | 永久免费av在线播放 | 久久国产电影 | 丁香久久| 亚洲五月激情 | 深夜免费福利网站 | 91精品国产福利在线观看 | 国产理论一区二区三区 | 欧美日韩高清不卡 | 中文字幕在线日 | 看v片 | 成年人国产视频 | 欧美污污网站 | 在线黄色av电影 | 国产高清视频免费最新在线 | 国产永久免费高清在线观看视频 | 亚洲综合五月天 | 97网在线观看 | 国产精品午夜久久 | www.国产在线 | 91视频麻豆 | 国产精品第10页 | 亚洲欧美日本A∨在线观看 青青河边草观看完整版高清 | 日韩免费在线视频 | 亚洲综合视频在线 | 久久视频国产 | 日韩综合一区二区 | 麻豆免费视频网站 | 亚洲毛片视频 | 五月天激情视频 | 精品久久久久久亚洲综合网 | aaa毛片视频 | 在线性视频日韩欧美 | 亚洲午夜久久久久久久久电影网 | 五月激情丁香图片 | 久久视频在线观看 | www.久久久com | 91精品视频在线观看免费 | 国产精品一区二区三区视频免费 | 中文字幕成人av | 天天在线免费视频 | 激情久久网 | av电影 一区二区 | 97精品国产一二三产区 | 黄色免费观看网址 | 在线视频精品 | 久久av中文字幕片 | 亚洲人成网站精品片在线观看 | 欧美色就是色 | 久久国产精品99久久久久久丝袜 | 天天色天天综合 | 久久久国产日韩 | 国内精品久久久久影院一蜜桃 | 精品久久久久久久久久久久久久久久久久 | 国产精品原创 | 日韩a在线 | 日韩69视频 | 一区二区影院 | 国产伦精品一区二区三区高清 | 日韩天堂网 | www视频免费在线观看 | 中文字幕国语官网在线视频 | 亚洲视频免费在线观看 | 久久久久久免费 | 超碰97在线资源站 | 99精品欧美一区二区三区 | av中文字幕电影 | 色狠狠久久av五月综合 | www.色午夜| 国产麻豆精品在线观看 | 欧美国产大片 | 尤物97国产精品久久精品国产 | 久久99亚洲网美利坚合众国 | 欧洲精品码一区二区三区免费看 | 国产一区在线免费观看 | a电影在线观看 | 日韩乱码中文字幕 | 高清国产午夜精品久久久久久 | 久久免费黄色网址 | 99精品视频在线看 | 中文字幕乱码亚洲精品一区 | 成人在线观看av | 日日夜夜添 | 欧美精品久久久久久久久老牛影院 | 国产免费亚洲高清 | 日韩高清成人 | 狠狠干夜夜爽 | 韩国av电影在线观看 | 亚洲伦理一区二区 | 999国产精品视频 | 国产精品久久久区三区天天噜 | 综合网伊人 | 中文字幕乱码亚洲精品一区 | 日本丰满少妇免费一区 | 国产精品入口久久 | 亚洲日本一区二区在线 | 超碰在线色 | 日韩91精品 | 国产在线观看国语版免费 | av在线播放中文字幕 | 岛国av在线免费 | 在线电影av| 中文av字幕在线观看 | 不卡av电影在线 | 久久综合亚洲鲁鲁五月久久 | 成人av在线观 | 久久久精品网 | 五月婷婷丁香网 | 精品国产一区二区三区四区在线观看 | 久久只精品99品免费久23小说 | 亚洲国产大片 | 免费看一级一片 | 成人黄色短片 | 午夜影院一级 | 亚洲国产精品女人久久久 | 黄色小网站免费看 | 91大神一区二区三区 | 亚洲一区久久 | 亚洲专区免费观看 | 五月激情片 | 手机av电影在线 | 国产99久久久精品 | 99视频在线免费播放 | 亚洲欧美日韩一区二区三区在线观看 | 日本黄色免费网站 | 国产免费av一区二区三区 | 九九久久精品视频 | 一级黄色在线免费观看 | 欧美 日韩 性 | 天天插天天爱 | 日韩国产欧美在线视频 | 成人在线一区二区三区 | 免费视频久久久久久久 | 欧美另类高潮 | 久久黄色a级片 | 99视频久久| 久久久av电影 | 国产成人三级一区二区在线观看一 | 97超碰资源网 | 久久久久久久久久久综合 | 一区二三国产 | 国产精品免费不 | 日韩二区精品 | 国产精品mv在线观看 | 中文字幕一区二区三区在线视频 | 九九九在线观看视频 | 国产手机免费视频 | 激情五月在线视频 | 精品久久久久久久久久久久久 | 久99精品 | 久久久久久久久久免费 | 夜夜躁日日躁狠狠久久av | 免费日韩 精品中文字幕视频在线 | 国产成人精品午夜在线播放 | 成人动漫精品一区二区 | 久久在线精品视频 | 国产成人精品一区二区三区 | www.天堂av| 亚洲国产97在线精品一区 | 久久tv视频 | 97超碰国产精品 | 操久 | 成人av午夜| 国产精品黄色 | 中文字幕视频一区二区 | 国产理论在线 | 一区二区三区观看 | 中文字幕在线播放av | 亚洲美女精品视频 | 成全免费观看视频 | 天天综合区 | 色欲综合视频天天天 | 亚洲视频456| 国产精品观看在线亚洲人成网 | 色先锋资源网 | 日韩精品视频免费在线观看 | 欧美性色黄| 亚洲黄色影院 | 亚洲午夜不卡 | 久草.com| 在线播放视频一区 | 99久久精品网 | 成人精品999 | 91精品视频观看 | 四虎影视国产精品免费久久 | 国产精品久久在线 | 国产精品二区在线 | 国产精品成人自产拍在线观看 | 久久久国产网站 | 欧美激情精品久久久 | 99精品热视频只有精品10 | 夜夜夜影院 | 日韩一二三 | 99久久久成人国产精品 | 久久伊人色综合 | 日韩av片无码一区二区不卡电影 | 亚洲视频免费在线 | 在线看岛国av | 成人四虎 | 久久国产精品成人免费浪潮 | 99 色| 成人免费视频免费观看 | 99精彩视频在线观看免费 | 六月婷婷久香在线视频 | 五月天丁香视频 | 成人黄在线观看 | 在线免费91 | 国产视频一区在线 | 精品久久久久久久久中文字幕 | 2020天天干夜夜爽 | 懂色av懂色av粉嫩av分享吧 | 国产在线观看地址 | 国产精品一区二区你懂的 | 青青草国产精品视频 | 免费观看一区二区三区视频 | 欧美一区二区伦理片 | 黄色精品免费 | 日韩一三区 | 国产在线久久久 | 久久久www成人免费精品张筱雨 | 天天综合网久久 | 日韩天堂在线观看 | 有码视频在线观看 | 操综合| 免费av视屏 | 日本成人a | 69亚洲视频| 亚洲精品福利在线观看 | 国产精品av久久久久久无 | 天天天操天天天干 | 日韩精品一区二区三区免费观看 | 久久优 | 日韩三级.com| 国产精品成人a免费观看 | 91九色在线视频 | 欧美精品一区二区性色 | 中午字幕在线 | 开心激情五月网 | 亚洲精品看片 | 日韩欧美视频一区 | 日韩欧美在线不卡 | 欧美成人h版电影 | 91中文字幕 | 国产精品久久久久久久久久久久午夜片 | 亚洲精品福利视频 | 96av在线视频 | 国产91精品高清一区二区三区 | 国产视频精品网 | 正在播放国产一区 | 国产一区二区在线免费播放 | 国产免费一区二区三区最新6 | www久久com| 天堂久色 | 亚洲一级黄色片 | 亚洲一级二级 | 久久久伦理 | 91av短视频 | 免费观看91视频大全 | 在线免费观看欧美日韩 | 国产伦精品一区二区三区高清 | 国产乱码精品一区二区蜜臀 | 成人免费在线播放视频 | 91av大全 | 天天激情综合 | 久久中文网 | 天天操夜夜操夜夜操 | 国产高清免费av | 国产一级特黄电影 | 国产精品12345 | 2023年中文无字幕文字 | 免费观看国产精品视频 | 欧美韩国在线 | 五月婷婷操 | 成人在线观看你懂的 | 国产成人精品久久二区二区 | 欧美性精品 | 丁香六月五月婷婷 | 久久99久久99 | 91男人影院 | 日韩在线二区 | 国产污视频在线观看 | 亚洲91中文字幕无线码三区 | 国产激情小视频在线观看 | 国产黄色一级大片 | 成人中文字幕+乱码+中文字幕 | 久久 地址 | 亚洲男模gay裸体gay | 在线观看免费视频你懂的 | 日韩在线视频网站 | 久久免费av电影 | 日韩乱码中文字幕 | 日本三级全黄少妇三2023 | 热热热热热色 | 黄色小网站在线 | 一区二区不卡视频在线观看 | 福利区在线观看 | 中文字幕在线一区观看 | 69中文字幕| 成人久久久久久久久久 | 日韩在线免费电影 | 日韩有码在线观看视频 | 亚洲码国产日韩欧美高潮在线播放 | 久久婷婷开心 | 毛片无卡免费无播放器 | 欧美污在线观看 | 亚洲精品久久久久久中文传媒 | 国产麻豆精品久久一二三 | 亚洲成人精品国产 | 国产精品福利久久久 | 亚洲天天综合网 | 青青射 | 五月情婷婷 | 激情影院在线观看 | 欧美日韩一区二区免费在线观看 | 99re视频在线观看 | 国产精品va在线 | 久艹视频在线免费观看 | 久草免费电影 | 久久精品毛片 | www在线观看视频 | 色就是色综合 | 亚洲精品麻豆视频 | 西西444www高清大胆 | 成人免费视频视频在线观看 免费 | 狠狠久久伊人 | 欧美激情综合五月 | 中文字幕在线成人 | 五月天婷婷视频 | 国产一级性生活 | 91在线精品观看 | 久久尤物电影视频在线观看 | 日韩欧美高清视频在线观看 | 亚洲91精品在线观看 | 国产小视频在线免费观看视频 | 麻花豆传媒mv在线观看网站 | av在线免费播放网站 | 91精品国产自产在线观看 | 日韩系列 | 91看片麻豆 | 久久久久久久久久久高潮一区二区 | 午夜久久精品 | 日韩三区在线 | 国产成人精品日本亚洲999 | 亚洲天堂自拍视频 | 2018亚洲男人天堂 | 成片人卡1卡2卡3手机免费看 | 免费看黄视频 | 亚洲性少妇性猛交wwww乱大交 | 日韩在观看线 | 亚洲精品av中文字幕在线在线 | 精品在线视频播放 | 国内精品国产三级国产aⅴ久 | www国产亚洲精品久久网站 | 久久精品欧美视频 | 亚洲美女在线一区 | 91av原创 | 性色av一区二区三区在线观看 | 日韩特级片 | 91黄色小网站 | 日本中文字幕网站 | 91精品国产一区二区三区 | 亚洲精品www | 日韩精品第一区 | 五月情婷婷 | 99九九99九九九视频精品 | 爱情影院aqdy鲁丝片二区 | 91视频高清 | 久久亚洲精品国产亚洲老地址 | 日韩电影在线观看一区 | 亚洲成人精品在线 | 最新99热| www.夜夜操.com | 色资源二区在线视频 | 中文字幕资源网在线观看 | 日韩欧美视频免费看 | 操处女逼 | 久久久国产一区二区三区 | 日本女人逼 | 97品白浆高清久久久久久 | 国产精品久久久久久久久久了 | 西西大胆啪啪 | 成人免费在线视频观看 | 久久久精品小视频 | 国产三级在线播放 | 我要看黄色一级片 | 玖草影院| 91中文字幕在线 | 性日韩欧美在线视频 | 超碰在线cao | 亚洲国产三级在线观看 | 激情欧美一区二区三区免费看 | 国产精品久久久久久久久大全 | 波多野结衣亚洲一区二区 | 99精品国产在热久久 | 一区二区三区日韩在线 | av黄色在线播放 | 久久精品99国产精品酒店日本 | 人人爽人人舔 | 色综合久久久久 | 精品国产福利在线 | 国产一级二级三级视频 | 91麻豆精品国产91久久久久 | 天天天操操操 | 一区二区三区四区精品视频 | 欧美一级电影 | 久久99免费 | 亚洲永久精品国产 | 亚洲精品国产精品国自产观看浪潮 | 日韩欧美一区二区三区免费观看 | 伊人五月天综合 | 亚洲黄色在线 | 99久久精品免费看国产一区二区三区 | 免费观看福利视频 | 欧美日韩精品综合 | 国产精品色 | 在线观看黄色大片 | 久久国产精品99国产精 | 亚洲精品在线观看的 | 一区二精品 | 色婷婷在线观看视频 | 亚洲综合导航 | 国产在线2020 | 五月激情久久 | 亚洲国产精品一区二区久久,亚洲午夜 | 免费观看国产成人 | 国产日韩视频在线观看 | 国产精品视屏 | 一区 二区电影免费在线观看 | 久久综合桃花 | 久久久久五月天 | 91精品久久久久久久久久久久久 | 欧美日韩成人 | 亚洲一二三久久 | 亚洲国产色一区 | 91亚洲国产成人久久精品网站 | 亚洲情影院 | 精品91视频 | 特及黄色片 | 欧美国产一区在线 | 久久久久亚洲国产 | 99这里只有精品视频 | 欧美激情视频在线免费观看 | 九九九九九九精品任你躁 | 国产美女视频网站 | 伊人五月婷 | 91精品一区国产高清在线gif | 日本中文字幕久久 | 五月天综合色 | 久草在线免费资源 | 久草在线视频网站 | 在线观看日本高清mv视频 | 麻豆视频在线免费 | 99精品欧美一区二区三区黑人哦 | 色综合久久中文字幕综合网 | 国产成人三级在线播放 | 欧美一区免费观看 | 五月激情视频 | 国产成人在线综合 | 亚洲国产美女精品久久久久∴ | 国产手机在线视频 | 精品在线视频播放 | 天天射天天干天天操 | 午夜婷婷网 | 天天操综合网站 | 99精品乱码国产在线观看 | 亚洲精品毛片一级91精品 | 中文av一区二区 | 日韩成人高清在线 | 日韩av有码在线 | 日本成人黄色片 | 四虎在线观看视频 | 91精彩视频在线观看 | 在线 国产一区 | 国产日产精品久久久久快鸭 | 国产精品美女久久久免费 | 亚洲理论在线观看 | 高清av免费观看 | 91在线精品秘密一区二区 | 日韩av片在线 | 麻豆一二 | 午夜精品一区二区三区免费 | 午夜天天操 | 成人av网站在线播放 | 97视频免费在线观看 | 成人免费一区二区三区在线观看 | 久久精品伊人 | 国产精品欧美久久久久三级 | 2019中文字幕网站 | 91精品在线播放 | 国产美女视频免费 | 五月丁婷婷 | 亚洲一二视频 | 91av视频在线免费观看 | 亚洲精品久久久久www | 国产成人精品在线播放 | 国产精品麻豆三级一区视频 | 91麻豆精品久久久久久 | 国产精品高清免费在线观看 | 久久久免费看视频 | 久草网视频在线观看 | 婷婷丁香激情五月 | 国产无限资源在线观看 | 天天天干天天射天天天操 | 日韩一级成人av | 久久久久欠精品国产毛片国产毛生 | 欧美一级久久久久 | 在线成人免费电影 | 国产精品久久久久久吹潮天美传媒 | 欧美激情视频一二三区 | 东方av在线免费观看 | 亚洲视频1区2区 | 手机在线黄色网址 | 久久久久久高潮国产精品视 | 久av在线 | www.福利| 一区二区三区日韩在线 | 99产精品成人啪免费网站 | 免费在线电影网址大全 | 日本xxxxav| 欧美一级片免费 | av免费看在线 | 国产69精品久久99不卡的观看体验 | 国产色视频网站2 | 免费观看www视频 | 99久久久成人国产精品 | 人人澡人人添人人爽一区二区 | 在线日韩精品视频 | 可以免费观看的av片 | adc在线观看 | 中文字幕网站 | 成人黄在线 | 亚洲欧美精品一区 | 欧美日韩久久一区 | 91亚洲精品久久久中文字幕 | 国产精品视频你懂的 | 午夜成人免费影院 | 热久精品 | 亚洲狠狠丁香婷婷综合久久久 | 日韩在线电影观看 | 欧美日韩国产一区二 | 亚洲精选在线观看 | 精品久久久久久综合日本 | 国产精品无av码在线观看 | 色天堂在线视频 | 国产视频精品视频 | 色婷婷精品大在线视频 | 精品久久一级片 | 五月婷婷在线视频观看 | x99av成人免费 | 在线日本看片免费人成视久网 | 日日夜夜天天久久 | 69精品人人人人 | 欧美成人在线免费 | 欧美巨大荫蒂茸毛毛人妖 | 日本资源中文字幕在线 | 夜夜操狠狠干 | 国产精品久久久久永久免费观看 | 婷婷久久国产 | 婷婷久月 | 一区国产精品 | 麻豆国产电影 | 国产精品一区二区白浆 | 免费观看成人网 | 成人免费观看视频大全 | 色婷婷亚洲精品 | 在线亚洲欧美视频 | 93久久精品日日躁夜夜躁欧美 | 成人av一级片| 91精品国产乱码久久桃 | 亚洲日本激情 | 一区二区不卡视频在线观看 | 久草精品视频在线观看 | 国产成人精品一区二区三区福利 | 久久精品一区二区 | 日躁夜躁狠狠躁2001 | 日韩精品久久久久久中文字幕8 | 国产高清永久免费 | 婷婷六月天综合 | 夜夜夜夜夜夜操 | 在线观看完整版 | 日韩欧美网站 | 午夜色站 | 日韩欧美高清视频在线观看 | 国产一区在线免费观看 | 亚洲不卡123 | 久久少妇av| 色狠狠干| 九九综合九九 | 国产在线最新 | 视频在线观看91 | 中国一区二区视频 | 波多野结衣在线视频免费观看 | 国产午夜精品久久 | www日日夜夜 | 99视频在线观看免费 | 97视频亚洲 | 久久成人一区二区 | 国产福利一区二区三区视频 | 九九九毛片| av色一区| 久久久黄色免费网站 | 国产精品成人aaaaa网站 | 久久久免费精品视频 | av电影一区二区 | 在线a亚洲视频播放在线观看 | 96精品高清视频在线观看软件特色 | 日韩性久久 | 九九热在线视频 | av中文字幕第一页 | 亚洲综合爱 | 国产一级片免费播放 | 99精品在线免费观看 | 日韩高清免费无专码区 | 九九国产精品视频 | 在线观看久 | 国产日韩精品在线观看 | 久久九九久久精品 | 国产精品免费一区二区三区 | 国产一区二区三区黄 | 婷婷伊人五月 | 久久综合五月婷婷 | 久久免费激情视频 | 热久久国产 | 久久精品99久久 | 中文字幕免费不卡视频 | 国产成人精品一区二 | 国产不卡在线观看 | 一区在线观看 | 欧美性做爰猛烈叫床潮 | 日韩动漫免费观看高清完整版在线观看 | 中文字幕亚洲字幕 | 亚洲网站在线 | 国产美女精品视频 | 国内外激情视频 | 激情网站免费观看 | 久碰视频在线观看 | 国产精品 中文字幕 亚洲 欧美 | 成人av免费在线播放 | 四虎最新域名 | 久久国产精品视频 | 成人h视频 | 欧美日韩视频精品 | 久久中文字幕导航 | 黄色小网站免费看 | 日韩大片在线免费观看 | 欧美视频网址 | 黄色h在线观看 | 一本一道久久a久久精品蜜桃 | 国产在线国产 | 一区二区三区四区在线免费观看 | 亚洲欧美色婷婷 | 特黄一级毛片 | 欧美日韩三区二区 | 久热电影 | 欧美日韩激情视频8区 | 日韩动态视频 | 亚洲国产精品久久久久久 | 天天操天天干天天干 | 国产免费a | 欧美-第1页-屁屁影院 | 综合久色| a天堂最新版中文在线地址 久久99久久精品国产 | 一级做a视频 | 亚洲国产三级在线观看 | 日韩欧美在线免费 | 色亚洲激情 | 高清av中文在线字幕观看1 | 天天干天天干天天干天天干天天干天天干 | 99综合电影在线视频 | 日韩精品字幕 | 日韩福利在线观看 | 激情开心| 91秒拍国产福利一区 | 亚洲播放一区 | 成人教育av | 国产一级性生活视频 | 97**国产露脸精品国产 | 2023国产精品自产拍在线观看 | 黄色免费电影网站 | 久久99精品国产一区二区三区 | 国产在线观看中文字幕 | 久久久久亚洲国产精品 | 超碰人人草人人 | 日本久久电影 | 亚洲精品国产精品99久久 | 午夜电影久久久 | a视频在线| 99精品国产福利在线观看免费 | 91九色成人 | 99热超碰在线 | 欧美在线观看视频一区二区三区 | 国产精品嫩草影视久久久 | av在线等| 欧美久草在线 | 在线看污网站 | 久久99国产精品视频 | 黄色三级免费观看 | 视频在线观看亚洲 | 91视频国产高清 | 91手机视频在线 | av中文字幕在线观看网站 | www.福利| 香蕉网在线播放 | 日日摸日日爽 | 欧美日韩一区久久 | 99久久精品国产一区二区三区 | 国内三级在线观看 | 久久久噜噜噜久久久 | 日日爱影视 | 色999在线| 国产精品国产三级国产专区53 | 久久综合狠狠综合久久狠狠色综合 | 中文字幕第一页在线 | 久久久电影网站 | 成人在线视频网 | 久青草国产在线 | 亚洲欧洲国产视频 | 九月婷婷人人澡人人添人人爽 | 四虎在线免费观看 | 精品亚洲一区二区 | 日韩精品观看 | 毛片网站免费在线观看 | 日韩精品中文字幕在线 | 亚洲精品色视频 | 日韩精品极品视频 | 在线观看黄色小视频 | 人人精久 | 国产一级片视频 | 国产老太婆免费交性大片 | 国产午夜精品一区二区三区欧美 | 天天操夜夜逼 | 国产精品手机看片 | 久久99国产精品久久99 | 五月婷av | 日韩色一区二区三区 | 久久精品免费电影 | 日韩欧美精品一区二区三区经典 | 中文字幕第一页在线vr | 欧美老人xxxx18| 国产一级黄色av | 91免费国产在线观看 | 91久草视频 | 国产视频中文字幕在线观看 | 黄a网 | av在观看 | 色欧美成人精品a∨在线观看 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 五月天丁香亚洲 | 视频在线观看入口黄最新永久免费国产 | 精品欧美小视频在线观看 | 日韩av三区| 一级片黄色片网站 | 国产精品一区二区免费在线观看 | 九九热1 | 天天综合在线观看 | 日日爱影视| 99精品国产一区二区三区不卡 | 国产一区免费在线 | 久久久久久免费毛片精品 | 久久久久日本精品一区二区三区 | 国产精品福利小视频 | 在线观看免费一级片 | 久热爱 | 最新国产在线观看 | 色综合色综合色综合 | 懂色av一区二区在线播放 | 久久久精品欧美一区二区免费 | 日韩免费一区二区 | 久久久久久久影视 | 久久久久 免费视频 | 国产精品mv | 99热国产在线观看 | 国产成人久久久久 | www.久久久.com | 天堂av在线免费观看 | 国产99久久九九精品 | 91精品区| 国产三级久久久 | 天天操天天射天天 | 色婷婷精品大在线视频 | 久操免费视频 | 欧洲精品码一区二区三区免费看 | 香蕉手机在线 | 天天干,天天操,天天射 | 超碰人人99| 精品国产乱码一区二 | 爱爱av在线 | 91视频在线看| 欧美一区三区四区 | 亚洲精品人人 | 久久久久国产精品视频 | 91视频午夜| 一区二区不卡在线观看 | 在线观看av不卡 | 久草久草在线观看 | 免费观看xxxx9999片 | 国产视频二区三区 | 丁香视频全集免费观看 | 婷婷色影院 | 久久69精品久久久久久久电影好 | 久久成电影| 婷婷激情综合五月天 | 丝袜美腿在线 | 久久久国产99久久国产一 | 激情电影在线观看 | 久久精品91视频 | 成人影视免费 | 99精品国产兔费观看久久99 | 91av视频在线免费观看 | 日韩一区二区久久 | 日韩在线免费观看视频 | 91在线小视频 | 91在线国产观看 | 日韩在线观看的 | 能在线观看的日韩av | 超碰在线天天 | 国产视频久久久 | 日韩精品2区 | 国产成人在线观看 | 久久激情小说 | 欧美日韩一二三四区 | 国产亚洲成av片在线观看 | 免费在线激情视频 | 国产精品久久久久久av | 免费高清在线视频一区· | 久久免费在线视频 | 久久网页 | 国产一区二区精品91 | 天天干天天摸 | 久久久黄色av | 国产乱码精品一区二区蜜臀 | 国外成人在线视频网站 | 欧洲亚洲国产视频 | 超碰97人人爱 | 久草电影免费在线观看 | 日本3级在线观看 | 久草免费在线视频观看 | 国产成人亚洲在线电影 | 狠狠久久婷婷 | 亚洲毛片久久 | 九九欧美| 亚洲狠狠婷婷综合久久久 | 97色婷婷 | 97超碰国产在线 | 精品v亚洲v欧美v高清v | 亚洲午夜电影网 | 国产精品久久久视频 | 免费一级特黄录像 | 激情图片久久 | 69精品| 色com网| 久久精品a | 人人草在线视频 | 欧美少妇18p| 视频一区二区在线 | 六月婷婷久香在线视频 | 日产中文字幕 | 国产极品尤物在线 | 日本中文字幕一二区观 | www免费视频com━ | 高清一区二区三区av | 99视频偷窥在线精品国自产拍 | 中文字幕在线看视频国产 | a电影在线观看 | 国产精品成人久久久久久久 | 五月婷婷黄色 | 又黄又爽免费视频 | 国产一区二区高清 | 国内偷拍精品视频 | 久久九九影院 | 97免费公开视频 | 91在线精品播放 | 国产午夜精品视频 | 亚洲视频免费在线观看 | 国产精品白虎 | 国产精品久久久久影院 | 波多野结衣精品在线 | 亚洲va韩国va欧美va精四季 | 亚洲精品影视在线观看 | 国产999久久久 | 视频国产 | av免费电影在线观看 | 丁香久久五月 | av一级一片| 日本中文字幕网站 | 日本久久成人中文字幕电影 | 久久久久久国产精品999 | 天天干夜夜爽 |