精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

SDK 體積與性能優化實踐

精選
開發 前端
字節各類業務擁有眾多用戶群,作為字節前端性能監控 SDK,自身若存在性能問題,則會影響到數以億計的真實用戶的體驗,所以此類 SDK 自身的性能在設計之初,就必須達到一個非常極致的水準。

背景

字節各類業務擁有眾多用戶群,作為字節前端性能監控 SDK,自身若存在性能問題,則會影響到數以億計的真實用戶的體驗,所以此類 SDK 自身的性能在設計之初,就必須達到一個非常極致的水準。

與此同時,隨著業務不斷迭代,功能變得越來越多,對監控的需求也會變得越來越多。例如,今天 A 業務更新了架構,想要自定義性能指標的獲取規則,明天 B 業務接入了微前端框架,需要監控子應用的性能。在解決這些業務需求的同時,我們會不斷加入額外的判斷邏輯、配置項。同時由于用戶的電腦性能、瀏覽器環境的不同,我們又要解決各種兼容性問題,加入 polyfill 等代碼,不可避免地造成 SDK 體積膨脹,性能劣化。那么我們是如何在需求和功能不斷迭代的情況下,持續追蹤和優化 SDK 的體積和性能的呢?

SDK 體積優化

通常而言,體積的優化是最容易拿到收益的一項。

由于監控 SDK 通常作為第一個腳本被加載到頁面中,體積的膨脹不僅會增加用戶的下載時間,還會增加瀏覽器解析腳本的時間。對于體積優化,我們可以從宏觀和微觀兩個角度去實現。

微觀上,我們會去盡可能去精簡所有的表達,剝離冗余重復代碼,同時盡可能減少以下寫法的出現:

1.過多的 class 和過長的屬性方法名

Class 的定義會被轉換成 function 聲明 + prototype 賦值,以及常用代碼壓縮工具無法對 object 屬性名壓縮,過多的面向對象寫法會讓編譯后的 js 代碼體積膨脹得非常快。例如下列代碼:

class ClassWithLongName {
methodWithALongLongName() {}
}

經過 ts 轉換后會變成:

var ClassWithLongName = /** @class */ (function () {
function ClassWithLongName() {
}
ClassWithLongName.prototype.methodWithALongLongName = function () { };
return ClassWithLongName;
}());

壓縮后代碼為:

var ClassWithLongName=function(){function n(){}return n.prototype.methodWithALongLongName=function(){},n}();

可以看到以上長命名都無法被壓縮。

如果使用函數式編程來代替面向對象編程,能夠很好的避免代碼無法被壓縮的情況:

function functionWithLongName() {
return function MethodWithALongLongName(){}
}

經過壓縮后變成:

function n(){return function(){}}

相較于 class 的版本,壓縮后的代碼減小了50%以上。

2、內部函數傳參使用數組代替對象

原理同上,對象中的字段名通常不會被代碼壓縮工具壓縮。同時合理使用 TS named tuple 類型可以保證代碼可維護性。

function report(event, {optionA, optionB, optionC, optionD}: ObjectType){
}

改為:

function report(event, [optionA, optionB, optionC, optionD]: NamedTupleType){
}

3、在不需要判斷 nullable 時,盡可能避免?. ?? ??= 等操作符的出現。同理,盡可能避免一些例如 spread 操作符、generator 等新語法,這些語法在編譯成 es5 后通常會引入額外的 polyfill。

TS 會將這些操作符轉換成非常長的代碼,例如 a?.b會被轉換成:

a === null || a === void 0 ? void 0 : a.b

過多的 nullish 操作符也是代碼體積增加的一個原因。

當然,以上只列舉了部分體積優化措施,還有更多優化方法要結合具體代碼而議。對于我們的前端監控 SDK,為了性能和體積是可以犧牲一些開發體驗的,并且由于使用 TS 類型系統,并不會對代碼維護增加很多負擔。

從宏觀上,我們應該思考如何減少 SDK 所依賴的模塊,減少產物包含的內容,增加產物的“信噪比”,有以下幾個方式:

1.拆分文件

我們可以分離出 SDK 中不是必須提前執行的邏輯,拆分成異步加載的文件,僅將必須提前執行的邏輯加入初始腳本。同時將不同功能拆分成不同文件,業務按需加載,這樣可以最大程度減少對首屏加載時間的影響。

2.盡可能避免 polyfill 的使用

polyfill 會顯著增加產物體積,我們盡可能不使用存在兼容性的方法。甚至在不需要兼容低端瀏覽器環境時,我們可以不使用 polyfill。

3.減少重復的常量字符串的出現次數

對于多次重復出現的常量字符串,提取成公共變量。例如

a.addEventListener('load', cb)
b.addEventListener('load', cb)
c.addEventListener('load', cb)

我們可以將 addEventListener?和 load 提取公共變量:

let ADD_EVENT_LISTENER = 'addEventLister'
let LOAD = 'load'
a[ADD_EVENT_LISTENER](LOAD, cb)
b[ADD_EVENT_LISTENER](LOAD, cb)
c[ADD_EVENT_LISTENER](LOAD, cb)

此段代碼壓縮后會變成:

let d="addEventLister",e="load";a[d](e,cb),b[d](e,cb),c[d](e,cb);

我們還可以使用 TSTransformer 或者 babel plugin 來幫我們自動地完成上述過程。

值得注意的是,這個方法在 web 端并不能取得很好的收益,因為瀏覽器在傳輸數據時會做 gzip 壓縮,已經將重復信息用最高效的算法壓縮了,我們做的并不會比 gzip 更好。但是在需要嵌入移動端 app 的監控 SDK 來說,這一做法能減少約 10 ~ 15% 產物體積。

除了體積優化以外,隨著需求不斷增加,功能不斷完善,不可避免的會影響到 SDK 的性能。接下來,我們介紹如何測量并優化 SDK 的性能。

使用工具進行性能衡量

通常來說,監控類 SDK 最有可能影響性能的地方為:

  1. 監控初始化時執行各類監聽的過程。
  2. 監控事件上報請求對業務的影響。
  3. SDK 維護數據緩存時的內存使用情況。

接下來,我們著重從以上幾個維度來衡量并優化 SDK 的性能。

性能衡量過程

使用 Benchmark 性能衡量工具的目的便是為了知道 SDK 運行過程中每一個函數執行的耗時,給業務帶來多大的影響,是否會引起 longtask。由于我們的監控 SDK 包含了性能、請求、資源等各類前端監控能力,這些功能的實現依賴對頁面各類事件的監聽、性能指標的獲取、請求對象的包裝。除此之外,SDK還提供給用戶(開發者)調用的方法,例如配置頁面信息、自定義埋點、更改監控行為等能力。根據 SDK 以上行為和能力,我們將測試分為兩個模塊:

  1. 接入 SDK 后自動運行的各類監控,這些行為大部分會在頁面加載之初執行,若此部分性能劣化,會嚴重影響到所有前端業務用戶的首屏加載。
  2. 用戶端(開發者)調用的方法,我們會將此類方法包裝成 client 對象以 npm 包的形式給開發者調用,這部分方法的執行由用戶控制,可能存在頻繁調用的情況,因此也應避免耗時過長的調用出現。

在過往文章前端監控系列1| 字節的前端監控 SDK 是怎樣設計的中我們講到,我們的 SDK 在設計時已經做到的盡可能的解耦,各個模塊各司其職,這一特點非常便于我們針對各個模塊方法進行單獨的性能衡量。

下面我們以使用 benny (https://github.com/caderek/benny) 這一開源工具為例,展示一段方便理解 benchmark 過程的偽代碼,僅作參考:

benny 是一個非常簡單易用的 benchmark 工具,通過 suite? 方法創建測試用例組合,通過add?方法添加需要測試的函數,cycle?方法用于多次循環執行測試用例,complete用于添加測試完成之后的回調函數。更多詳細的使用說明可以查閱官方文檔。

const { suite, add, cycle, complete, save } = require('benny')
// 衡量 SDK 各類監控初始化運行性能
suite(
'collectors setup',
add('route', () => route(context)),
add('exception', () => exception(context)),
add('ajax', () => ajax(context)),
add('FCP', getFCP),
add('LCP', getLCP),
add('longtask', getLongtask),
cycle(),
complete(),
)

// 衡量 Client 實例方法耗時
suite(
'npm client',
add('set config', () => client.config({pid})),
add('set context', () => client.context.set({ something })),
add('send custom pv', () => client.sendPageView(pid)),
add('send custom event', () => client.sendCustom(ev)),
// ...
cycle(),
complete(),
)

通常這類 benchmark 工具都是在 Node 上執行的,但是我們的 SDK 是個前端監控 SDK,依賴了非常多的瀏覽器環境對象,我們幾乎不可能在 Node 環境去創造或模擬這些對象,我們有沒有辦法在瀏覽器里去運行這段腳本,做性能自動化測試呢?

利用 Puppeteer 在瀏覽器環境中執行 Benchmark

由于我們的前端監控依賴瀏覽器環境,我們可以將上述 benchmark 測試代碼打包成 commonjs 之后放入 headless chrome 瀏覽器中執行,并通過 puppeteer 收集執行結果。

Puppeteer 是一個 Node 模塊,提供了通過 Devtool Protocol 控制 Chrome 或者 Chromium 的能力。Puppeteer 默認運行 Chrome 的無頭版本,也可以通過設置運行 Chrome 用戶界面版。

下面是一段方便理解操作 puppeteer 過程的偽代碼,僅作參考,實際情況較為復雜,需要等待未完成的異步請求等:

const browser = await puppeteer.launch()
const page = await browser.newPage()
const cdp = await page.target().createCDPSession()

// 用于 benchmark 腳本和 puppeteer 之間的通信,用以收集結果
await page.evaluate(() => (window.benchmarks = []))
// 將 pushResult 方法暴露給瀏覽器,來將結果收集到 node 端
await page.exposeFunction(
'pushResult',
(result: any) => benchmark.results.push(result)
)

await cdp.send('Profiler.enable')
await cdp.send('Profiler.start')

// 開始執行 benchmark
await page.addScriptTag({
content: file.toString(),
})

await Promise.race([timeout, allBenchmarksDone()])

// profile 可用于繪制火焰圖
const { profile } = await cdp.send('Profiler.stop')
await page.close()

通過運行以上腳本,我們便可以在無頭瀏覽器中運行我們的性能測試腳本,在測試腳本產出結果后添加調用 pushResult 方法來收集測試結果。

在實際的 benchmark 測試中,我們發現開啟性能監聽(即運行各個性能監控的 PerformanceObserver.observe 方法)最大耗時達到了21ms,雖然看上去并不久,但若和其他監聽同時執行,加上引入業務代碼的復雜性和移動端更弱的 CPU 性能,極有可能成為給業務帶來 longtask 的罪魁禍首。性能監控性能成為了瓶頸。

接下來,我們將性能監聽一個個拆分,用同樣的方式單獨測試每一個性能監聽的耗時。在實際的 benchmark 結果中,我們發現 fp、fcp、lcp、cls 監控耗時最大,加在一起超過了10ms,占了一半以上,是我們之后需要重點優化的地方。

除此之外利用 puppeteer 的能力,我們不僅可以得到 benchmark 的結果,還可以獲取到整個 benchmark 過程的 profile 數據,利用 speedscope (https://github.com/jlfwong/speedscope/blob/main/README-zh_CN.md) 繪制出函數執行過程中的火焰圖:

繪制火焰圖的具體實現不在本文討論范圍內,感興趣的同學可以參考 speedscope 官方文檔

圖片

此處顯示的時間為該用例執行總耗時(單次耗時*次數)

如何衡量異步任務性能?

Benny 的 api 是支持異步測試用例的,測量的是每個異步函數從開始執行到 resolve 的時間。但通常這并不是我們想要的衡量的數據,因為異步任務的執行過程中并不是一直占據著主線程。對于一些異步的定時任務(例如 SDK 的崩潰檢測、卡頓檢測、白屏檢測),將他們拆解為一系列可測的同步任務能更直觀的展示各個階段的性能耗時。

例如我們 SDK 的前端白屏檢測,由一個 mutationObserver 和觸發白屏檢測的函數組成。我們可以單獨對 mutationObserver 的回調和觸發函數做性能衡量。

這兩個方法已沒有很好的優化方式了。但是根據 benchmark 結果并結合源碼可以發現,性能監控所有指標項的開啟均為同步執行,每一項指標都會對頁面做事件監聽或者 PerformanceObserver 監聽,且這些原生監聽耗時都在毫秒級。于是我們對性能做了如下優化:

  1. 性能監控邏輯分片運行,將各項性能指標的監聽同步拆為異步,用 requestIdleCallback (https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestIdleCallback) 做調度并區分優先級。
  2. 多個性能指標監聽同一事件的公用監聽器,例如 CLS 和 LCP 都需要監聽 onBFCacheRestore,讓他們只做一次 addEventListener。
  3. 可以延遲執行的方法延遲執行,例如在高版本的 Chrome 中 PerformanceObserver 是有 buffer (https://www.w3.org/TR/performance-timeline-2/#dom-performanceobserverinit-buffered) 的,可以直接獲取到調用之前的性能指標,這些方法調用就可以等待頁面完全加載完成之后執行,從而盡可能減少對業務頁面首屏影響。

通過 Perfsee 的 Lab 結果分析性能問題

以上的 benchmark 流程得到的結果畢竟是一種理想化、單純的方法調用的性能情況,然而在實際瀏覽器環境中我們前端監控 SDK 對性能影響有多大呢,對于這一類頁面初始化即加載的 SDK 可以通過 Perfsee (https://perfsee.com/) 的 Lab 功能進行性能衡量。

Perfsee 是一個針對前端 web 應用在整個研發流程中的性能分析平臺。提供性能分析報告、產物分析報告、源碼分析、競品分析等模塊,定位與梳理性能問題,提供專業的優化方案來漸進地優化產品性能。

Lab 模塊性能分析的依據是,使用 headless 瀏覽器運行用戶指定的頁面,通過運行時數據的收集,分析并產出關鍵性能指標分數、網絡請求信息、主線程 JS/渲染/Longtask 信息供業務方參考優化。具體使用說明請查看 perfsee.com (https://perfsee.com/docs/cn/lab/get-started)

注意,本文所展示 Perfsee 功能示例為早期版本,并不與開源版本功能和界面完全一致。

準備基準頁面作為對照組

我們的目的是衡量 SDK 對業務性能造成的影響,便需要找到一個基準頁面作為對比。此處以 React Server Component Demo (https://github.com/reactjs/server-components-demo) 為例作為基準頁面。該應用有以下幾個特點:

  1. 容易搭建,一個命令就能跑起來。
  2. 自身邏輯簡單,性能好,SDK 所造成的影響容易被放大觀察。
  3. SPA 應用,含有異步加載的邏輯,更容易探測到監控 SDK 對頁面 FCP、LCP 等指標影響。
  4. 無外部網絡請求,頁面結果穩定不易波動。

我們修改一下應用的邏輯,能夠通過 url 參數注入監控 sdk 腳本,把它部署在服務器上。接著,我們在 perfsee 平臺上配置好基準頁面和注入 SDK 的頁面這兩個 page,并觸發一次性能掃描。

查看 Lab 性能報告

我們將沒有注入 SDK 的頁面作為空白組 (empty),注入了 SDK 的頁面作為實驗組 (with-sdk)。

首先我們需要配置好空白組和實驗組的 pages 以及 profile,觸發一次 snapshot 之后,我們得到了多份報告,我們可以點擊 compare 將空白組和實驗組的數據進行比對。

圖片

在實際的 lab 性能掃描結果中,我們可以看到兩個頁面所有性能指標的對比。我們發現 sdk 的注入在 mobile profile(4倍降頻) 下還是給業務帶來了 fcp 70ms、lcp 90ms、load 200ms 的劣化。

圖片

同時我們還可以觀察到注入了 sdk 之后,fmp 和 lcp 之前的請求僅多了 1 個,這是符合預期的。不過這仍是我們保持觀察的指標之一,因為在一些中低端的環境中,頁面加載完成之前每發出一個請求就可能讓業務更高優先級的請求被延后,從而引起頁面性能指標的下降。

切換到 Breakdown Tab,我們還可以看到頁面首屏時間線。我們需要重點關注幾個關鍵指標(load、fcp、lcp)之前的線程占用情況,hover 在 load 之前這一黃色色塊上,我們發現 sdk 在 load 之前執行了 30ms,成為了拖慢了業務指標的原因之一。

圖片

此處截圖省略了一些內部信息,一般情況下,如果需要更多信息可以借助 Source 模塊來找到引起主線程密集計算的代碼位置。

在這個例子中,這個調用未觸發 longtask,并且我們很容易發現這就是 SDK 初始化的邏輯,也是接下來需要優化的地方。

問題分析與性能優化

通過上述 benchmark 工具和 perfsee lab 性能分析結果,我們可以看出 SDK 初始化邏輯以及大量的事件監聽確實對業務性能造成了一定影響。

例如上文火焰圖中所示每一個 onBFCacheRestore 都占用了超過 15ms 的時間,我們在源碼里搜索這個函數,此部分偽代碼如下:

const onBFCacheRestore = (cb) => {
addEventListener('pageshow', (e) => {
if (e.persisted) cb(e)
}, true)
}

BFCache (https://web.dev/bfcache/) 即 back-forward cache,可稱為“往返緩存”,可以在用戶使用瀏覽器的“后退”和“前進”按鈕時加快頁面的轉換速度。這個緩存不僅保存頁面數據,還保存了 DOM 和 JS 的狀態,實際上是將整個頁面都保存在內存里。如果頁面位于 BFCache 中,那么再次打開該頁面就不會觸發 onload 事件。

可以看到,耗時主要由 onBFCacheRestore 和 onHidden 兩個方法中的原生 addEventListener 造成。這些監聽本身都是在毫秒級的,回調函數也沒有什么優化空間,從實際場景考慮,這兩處回調是為了監聽用戶頁面前進和返回的,并非優先級最高的任務。

我們可以從以下幾個方面降低對業務造成的影響:

1. 監控任務切片運行,區分優先級

對于監控 SDK 而言,除了必要的監聽以及事件預收集等任務,其他任何任務不應該阻礙到業務代碼的執行。對于字節前端監控需求而言,異常和請求監聽為必須前置執行的任務,其他所有事件監聽可以拆分為單獨的任務,所有的采樣、數據運算、上報請求等數據后處理邏輯只在空閑時執行,通過 requestIdleCallback 調用。

2. 減少重復監聽次數

多個性能指標監聽同一事件的公用監聽器,例如 CLS 和 LCP 這兩個指標都需要監聽 onBFCacheRestore,讓他們只做一次 addEventListener。

3. 請求數量的優化

我們 SDK 的腳本是由一個必須最先執行的主腳本(包含預收集、請求hook、錯誤監聽等邏輯)和多個通過不同配置開啟的異步插件腳本(性能、資源、白屏等)組成,主腳本的請求無法省略,而插件腳本可以通過接入 cdn combo 服務或自行搭建 combo 服務將多個請求合并成一個。

  • 對于事件上報請求,我們在內部維護一個緩存,只有當間隔達到一定時間或者累計一定數量之后才會統一上報。在這個場景中,我們又需要考慮兩個問題:
  • 瀏覽器對請求并發量有限制,所以存在網絡資源競爭的可能性
  • 瀏覽器在頁面卸載時會忽略異步ajax請求,而同步 ajax 通常在現代瀏覽器中已被禁用

我們可以通過使用 navigator.sendBeacon 方法解決上述問題。

這個方法主要用于滿足統計和診斷代碼的需要,這些代碼通常嘗試在卸載(unload)文檔之前向 Web 服務器發送數據。過早的發送數據可能導致錯過收集數據的機會。然而,對于開發者來說保證在文檔卸載期間發送數據一直是一個困難。因為用戶代理通常會忽略在 unload (en-US)? 事件處理器中產生的異步 XMLHttpRequest

經過以上優化后,我們注入優化過后的 SDK 再次跑分。

優化后的 SDK 對業務 FCP、LCP、LOAD 等性能的影響已經降到了最低,已經達到了非常高的性能標準。

責任編輯:未麗燕 來源: 字節跳動技術團隊
相關推薦

2022-06-07 15:33:51

Android優化實踐

2023-10-30 16:14:44

Metrics SD數據庫

2024-11-13 21:18:02

2023-07-19 22:17:21

Android資源優化

2020-03-23 15:15:57

MySQL性能優化數據庫

2023-10-31 12:50:35

智能優化探索

2020-07-17 19:55:50

Vue前端性能優化

2010-07-06 09:07:09

2025-04-11 03:00:55

2025-10-09 09:28:01

KotlinArkTS

2021-09-24 14:02:53

性能優化實踐

2019-08-02 11:28:45

HadoopYARN調度系統

2022-06-01 09:18:37

抖音ReDex算法優化

2025-03-27 03:20:00

C#開發字符串

2024-11-06 08:13:28

2022-03-29 13:27:22

Android優化APP

2022-07-08 09:38:27

攜程酒店Flutter技術跨平臺整合

2016-11-17 09:00:46

HBase優化策略

2022-07-15 09:20:17

性能優化方案

2012-12-24 09:55:15

JavaJava WebJava優化
點贊
收藏

51CTO技術棧公眾號

亚洲高清视频一区| 久久久国产一区二区| 99视频在线免费播放| 三级视频网站在线| 日韩精品欧美精品| 久久国产精品久久精品| 99精品一区二区三区无码吞精| 午夜激情电影在线播放| 国产精品色哟哟网站| 91精品国产高清久久久久久91裸体 | 777午夜精品福利在线观看| 成年人网站免费在线观看| 国模私拍国内精品国内av| 一区二区三区日韩在线观看| 秋霞久久久久久一区二区| 97久久人国产精品婷婷| 国产日韩一区二区三区在线| xvideos国产精品| 香港三级日本三级| 91久久青草| 色88888久久久久久影院野外 | 国产精品无码网站| 91久久青草| 欧美性极品少妇| 欧美激情 国产精品| 日本三级视频在线观看| 91亚洲国产成人精品一区二三 | 国产日产欧产精品推荐色| 成人免费淫片视频软件| 91在线视频免费播放| 亚洲国产高清一区二区三区| 久久久999国产| 精品国产aaa| 日韩高清成人在线| 日韩欧美国产一区二区在线播放| 日本在线观看免费视频| 日本乱码一区二区三区不卡| 亚洲一线二线三线视频| 亚洲一一在线| 99riav在线| 国产视频视频一区| 久久久久久高清| 人人妻人人玩人人澡人人爽| 韩国一区二区视频| 国产日韩欧美成人| 中文字幕免费高清在线观看| 99精品国产99久久久久久福利| 毛片精品免费在线观看| 免费看一级黄色| 日韩欧美午夜| 尤物精品国产第一福利三区| 国产精品扒开腿做爽爽| 亚洲+变态+欧美+另类+精品| 亚洲国产中文字幕久久网| 国产香蕉精品视频| 99re8这里有精品热视频免费| 91精品国产全国免费观看| 五月婷婷丁香色| 国产精品伦一区二区| 欧美四级电影网| 婷婷六月天在线| 69堂免费精品视频在线播放| 日本黄色一区二区| 亚洲精品一二三四五区| 99re久久| 777奇米成人网| 亚洲第一区第二区第三区| 色成人综合网| 日韩欧美在线不卡| 亚洲视频 中文字幕| 欧美精品密入口播放| 日韩精品在线免费观看视频| 五月婷婷综合在线观看| 国产精品一区高清| 国产一区二区三区中文| 91久久久久久久久久久久久久| 亚洲美女视频| 97碰碰碰免费色视频| 亚洲欧美偷拍视频| 日本不卡一区二区| 91麻豆桃色免费看| 懂色av蜜臀av粉嫩av分享吧| 成人性生交大合| 久久av一区二区| 国产高清视频在线| 亚洲欧美在线另类| 丰满的少妇愉情hd高清果冻传媒 | 亚洲制服丝袜在线| 欧美日韩在线中文| 性欧美video另类hd尤物| 欧美一级片免费看| 国产精品探花一区二区在线观看| 欧美丝袜丝交足nylons172| 欧美成人免费播放| 少妇高潮av久久久久久| 美女视频黄a大片欧美| 91久久精品国产91久久性色tv | 色综合久久久888| 可以在线观看av的网站| 蜜臀av性久久久久蜜臀aⅴ四虎| 3d蒂法精品啪啪一区二区免费| 亚洲aⅴ在线观看| 中文字幕一区二区日韩精品绯色| 免费超爽大片黄| 国产日韩电影| 欧美一级爆毛片| 亚洲色成人网站www永久四虎| 欧美在线黄色| 国产精品黄色av| 成人免费观看在线视频| 欧美国产精品一区二区| 亚洲精品蜜桃久久久久久| 欧美日韩女优| 国产视频精品一区二区三区| 日日噜噜夜夜狠狠久久波多野| 亚洲免费影院| 懂色一区二区三区av片| 91精品专区| 欧美日韩久久久久| 色欲欲www成人网站| 久久在线电影| 国产成人综合一区二区三区| 韩国av免费在线| 亚洲日本在线看| 免费黄色一级网站| 校园春色另类视频| 欧美成人精品一区| 啪啪小视频网站| 91天堂素人约啪| 99色这里只有精品| 亚洲国产中文在线二区三区免| 日韩中文理论片| 中文字幕a级片| 国产丝袜欧美中文另类| 日批视频在线免费看| 精品国产午夜肉伦伦影院| 欧美成人剧情片在线观看| 一级成人免费视频| 国产人伦精品一区二区| 东京热加勒比无码少妇| 精品三级av在线导航| 色综合久久天天综线观看| 国产免费一区二区三区最新不卡 | 精品一区91| 久久精品99国产精品酒店日本| 69av视频在线观看| 久久色在线观看| 日韩欧美一区三区| 六月丁香久久丫| 国产69久久精品成人| www.激情五月| 亚洲国产综合人成综合网站| 欧美熟妇精品一区二区| 国产精品a久久久久| 97人人模人人爽人人少妇| 任你弄在线视频免费观看| 欧美白人最猛性xxxxx69交| 欧美性猛交xxxxx少妇| 国产九九视频一区二区三区| 992tv快乐视频| 99亚洲乱人伦aⅴ精品| 国模精品一区二区三区色天香| 亚洲第一精品网站| 午夜精品成人在线视频| 在线精品一区二区三区| 久久婷婷久久| 婷婷久久青草热一区二区| 日韩成人精品一区二区三区| 欧美不卡视频一区发布| 蜜桃av中文字幕| 欧美性生活大片免费观看网址| 法国伦理少妇愉情| 日韩中文字幕亚洲一区二区va在线| 欧洲亚洲一区二区| 久久久久久一区二区三区四区别墅| 久久深夜福利免费观看| 成人h动漫精品一区二区无码| 亚洲国产精品久久人人爱| 中国极品少妇videossexhd| 丝袜美腿一区二区三区| 一本一本a久久| 成人h动漫精品一区二区器材| 国内精品视频一区| 黄色在线视频观看网站| 欧美浪妇xxxx高跟鞋交| 久久老司机精品视频| 91视频在线观看免费| 天堂网在线免费观看| 欧美久久九九| 日韩av不卡播放| 欧美欧美在线| 日韩免费在线观看视频| 久久久久久久久免费视频| 欧美videos大乳护士334| 中文字字幕在线中文| 中文字幕一区三区| 成年女人免费视频| 蜜桃一区二区三区在线| 亚洲 欧美 综合 另类 中字| 国产伦精品一区二区三区视频| 91视频国产一区| 中文在线8资源库| 日韩小视频在线| 人妻无码中文字幕| 欧美裸体一区二区三区| 九九热在线视频播放| 亚洲欧美一区二区视频| 黄色正能量网站| 国产盗摄一区二区三区| 欧美婷婷精品激情| 国产农村妇女精品一区二区| 中文字幕欧美日韩一区二区三区 | 日韩精品福利网站| 国产一区二区网站| 日韩欧美在线播放| 久久久久久久国产精品毛片| 中文字幕欧美日韩一区| 国产成人精品无码片区在线| 激情五月婷婷综合| 久久久久狠狠高潮亚洲精品| 亚洲二区视频| 日韩视频一二三| 成人激情视频| 蜜桃91精品入口| 国产精品99久久免费观看| 成人黄色在线观看| 亚洲日本网址| 欧美在线性视频| 波多野结依一区| 久青草国产97香蕉在线视频| 99精品老司机免费视频| 亚洲人精品午夜在线观看| 天天干,夜夜操| 精品电影一区二区| 超碰在线播放97| 日韩一区二区免费电影| 91麻豆成人精品国产免费网站| 色偷偷成人一区二区三区91| 国产精品999在线观看| 五月综合激情网| 91精品一区二区三区蜜桃| 久久先锋影音av鲁色资源| 妖精视频一区二区| 国产成人啪免费观看软件| 免费不卡av网站| 久久国产乱子精品免费女| 男人女人黄一级| 玖玖精品视频| 日韩免费高清在线| 日韩av在线播放中文字幕| 日韩一级在线免费观看| 免费视频一区| www.色就是色| 久久99国产精品久久99果冻传媒| 国产高清视频网站| 美女mm1313爽爽久久久蜜臀| 久久久国产欧美| 日本少妇一区二区| 99九九99九九九99九他书对| 国内精品伊人久久久久av一坑| 久久成年人网站| 国产一区二区不卡在线| 人妻巨大乳一二三区| 盗摄精品av一区二区三区| 黄色国产在线视频| 91理论电影在线观看| 高潮毛片无遮挡| 欧美国产激情一区二区三区蜜月| 99自拍偷拍视频| 亚洲视频1区2区| 国产一级性生活| 日韩欧美中文在线| 在线播放国产一区| 91精品国产乱| 图片区 小说区 区 亚洲五月| 亚洲精品在线观看www| 日本电影全部在线观看网站视频| 美日韩在线视频| 九九色在线视频| 日本免费一区二区三区视频观看| 国产另类xxxxhd高清| 国产色视频一区| 红杏视频成人| 午夜老司机精品| 亚洲午夜激情在线| 一本久道中文无码字幕av| 国产在线一区二区| 黄色网址在线视频| 国产精品对白交换视频| 久久婷婷国产麻豆91| 日韩欧美亚洲国产一区| 一级黄色录像大片| 日韩精品在线观| 秋霞a级毛片在线看| 高清一区二区三区日本久| 日韩欧美一区二区三区在线观看| 91在线观看免费| 免费视频一区三区| 久久久99精品视频| 久久综合九色| 国产人妻黑人一区二区三区| 日本一区二区三区视频视频| 久久久久99精品成人片毛片| 欧美在线你懂得| 天天操天天干天天插| 日韩视频免费观看| 竹内纱里奈兽皇系列在线观看| 成人午夜一级二级三级| 国产伦精品一区二区三区视频| 欧美日韩激情四射| 麻豆久久久久久久| 国产精品久久不卡| 一区二区三区资源| 在线观看免费视频a| 亚洲美女黄色片| 波多野结衣在线观看| 成人激情视频在线| 国内精品久久久久久久影视简单 | 懂色一区二区三区免费观看| jizz18女人高潮| 日韩欧美国产免费播放| www.国产三级| 久久精品福利视频| 日韩成人亚洲| 欧美日韩成人一区二区三区| 激情自拍一区| 日本r级电影在线观看| 中文字幕制服丝袜一区二区三区| 日韩色图在线观看| 亚洲国产成人精品电影| 在线观看男女av免费网址| 国产免费亚洲高清| 精品精品99| 欧美精品一区二区三区免费播放| eeuss鲁片一区二区三区在线观看| 国产大学生自拍| 88在线观看91蜜桃国自产| 天堂中文а√在线| 国产日韩欧美在线看| 日韩在线观看| 天天干天天爽天天射| 中文字幕乱码一区二区免费| 国产女主播喷水视频在线观看| 日韩精品小视频| 自拍网站在线观看| 欧美一二三区| 日日摸夜夜添夜夜添精品视频| 少妇久久久久久久久久| 欧美性猛交xxxx乱大交| 青青久在线视频免费观看| 国产69久久精品成人看| 精品一区毛片| 91淫黄看大片| 国产精品国产三级国产普通话99| 在线观看毛片视频| 久久精品91久久香蕉加勒比| 一区二区三区在线免费看| 国产二区视频在线| www.66久久| wwwwww国产| 一本一本久久a久久精品牛牛影视| 欧美日韩尤物久久| 亚洲高清在线播放| 国内精品免费在线观看| 国产精品成人免费观看| 精品国产123| 欧美1级2级| 视频一区二区在线| 国内精品第一页| 免费一级a毛片夜夜看| 亚洲黄色免费三级| 黄色亚洲网站| 老司机av福利| 成人h动漫精品一区二区| 天天干天天干天天干天天| 国产亚洲视频在线观看| 国产成人久久精品一区二区三区| www.99riav| 91亚洲男人天堂| 国产一区二区女内射| 国语自产精品视频在免费| 国产伦精品一区二区三区千人斩 | 波多野结衣日韩| 日韩视频免费在线观看| 国产精品午夜av| 人人干人人干人人| 亚洲一区二区在线免费观看视频| 日av在线播放| 91免费看片网站| 一区二区激情| 日韩一卡二卡在线观看| 亚洲成人1234| 国产亚洲欧美日韩精品一区二区三区| 日韩不卡一二区| 久久久精品综合| 精品黑人一区二区三区在线观看 | 中文字幕视频精品一区二区三区| 777久久久精品一区二区三区 | 成人高清在线视频| 在线观看黄色国产|