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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > vue >内容正文

vue

细说 Vue.js 3.2 关于响应式部分的优化

發(fā)布時(shí)間:2023/12/9 vue 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 细说 Vue.js 3.2 关于响应式部分的优化 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

大家好,我是若川。上一篇寫(xiě)的是:初學(xué)者也能看懂的 Vue3 源碼中那些實(shí)用的基礎(chǔ)工具函數(shù)。今天再分享一篇?Vue 3.2?的文章。

學(xué)習(xí)源碼整體架構(gòu)系列、年度總結(jié)、JS基礎(chǔ)系列


背景

Vue 3 正式發(fā)布距今已經(jīng)快一年了,相信很多小伙伴已經(jīng)在生產(chǎn)環(huán)境用上了 Vue 3 了。如今,Vue.js 3.2 已經(jīng)正式發(fā)布,而這次 minor 版本的升級(jí)主要體現(xiàn)在源碼層級(jí)的優(yōu)化,對(duì)于用戶(hù)的使用層面來(lái)說(shuō)其實(shí)變化并不大。其中一個(gè)吸引我的點(diǎn)是提升了響應(yīng)式的性能:

  • More efficient ref implementation (~260% faster read / ~50% faster write)

  • ~40% faster dependency tracking

  • ~17% less memory usage

翻譯過(guò)來(lái)就是 ref API 的讀效率提升約為 260%,寫(xiě)效率提升約為 50% ,依賴(lài)收集的效率提升約為 40%,同時(shí)還減少了約 17% 的內(nèi)存使用。

這簡(jiǎn)直就是一個(gè)吊炸天的優(yōu)化啊,因?yàn)橐理憫?yīng)式系統(tǒng)是 Vue.js 的核心實(shí)現(xiàn)之一,對(duì)它的優(yōu)化就意味著對(duì)所有使用 Vue.js 開(kāi)發(fā)的 App 的性能優(yōu)化。

而且這個(gè)優(yōu)化并不是 Vue 官方人員實(shí)現(xiàn)的,而是社區(qū)一位大佬 @basvanmeurs 提出的,相關(guān)的優(yōu)化代碼在 2020 年 10 月 9 號(hào)就已經(jīng)提交了,但由于對(duì)內(nèi)部的實(shí)現(xiàn)改動(dòng)較大,官方一直等到了 Vue.js 3.2 發(fā)布,才把代碼合入。

這次 basvanmeurs 提出的響應(yīng)式性能優(yōu)化真的讓尤大喜出望外,不僅僅是大大提升了 Vue 3 的運(yùn)行時(shí)性能,還因?yàn)檫@么核心的代碼能來(lái)自社區(qū)的貢獻(xiàn),這就意味著 Vue 3 受到越來(lái)越多的人關(guān)注;一些能力強(qiáng)的開(kāi)發(fā)人員參與到核心代碼的貢獻(xiàn),可以讓 Vue 3 走的更遠(yuǎn)更好。

我們知道,相比于 Vue 2,Vue 3 做了多方面的優(yōu)化,其中一部分是數(shù)據(jù)響應(yīng)式的實(shí)現(xiàn)由 Object.defineProperty API 改成了 Proxy API。

當(dāng)初 Vue 3 在宣傳的時(shí)候,官方宣稱(chēng)在響應(yīng)式實(shí)現(xiàn)的性能上做了優(yōu)化,那么優(yōu)化體現(xiàn)在哪些方面呢?有部分小伙伴認(rèn)為是 Proxy API 的性能要優(yōu)于 Object.defineProperty 的,其實(shí)不然,實(shí)際上 Proxy 在性能上是要比 Object.defineProperty 差的,詳情可以參考 Thoughts on ES6 Proxies Performance 這篇文章,而我也對(duì)此做了測(cè)試,結(jié)論同上,可以參考這個(gè) repo。

既然 Proxy 慢,為啥 Vue 3 還是選擇了它來(lái)實(shí)現(xiàn)數(shù)據(jù)響應(yīng)式呢?因?yàn)?Proxy 本質(zhì)上是對(duì)某個(gè)對(duì)象的劫持,這樣它不僅僅可以監(jiān)聽(tīng)對(duì)象某個(gè)屬性值的變化,還可以監(jiān)聽(tīng)對(duì)象屬性的新增和刪除;而 Object.defineProperty 是給對(duì)象的某個(gè)已存在的屬性添加對(duì)應(yīng)的 getter 和 setter,所以它只能監(jiān)聽(tīng)這個(gè)屬性值的變化,而不能去監(jiān)聽(tīng)對(duì)象屬性的新增和刪除。

而響應(yīng)式在性能方面的優(yōu)化其實(shí)是體現(xiàn)在把嵌套層級(jí)較深的對(duì)象變成響應(yīng)式的場(chǎng)景。在 Vue 2 的實(shí)現(xiàn)中,在組件初始化階段把數(shù)據(jù)變成響應(yīng)式時(shí),遇到子屬性仍然是對(duì)象的情況,會(huì)遞歸執(zhí)行 Object.defineProperty 定義子對(duì)象的響應(yīng)式;而在 Vue 3 的實(shí)現(xiàn)中,只有在對(duì)象屬性被訪(fǎng)問(wèn)的時(shí)候才會(huì)判斷子屬性的類(lèi)型來(lái)決定要不要遞歸執(zhí)行 reactive,這其實(shí)是一種延時(shí)定義子對(duì)象響應(yīng)式的實(shí)現(xiàn),在性能上會(huì)有一定的提升。

因此,相比于 Vue 2,Vue 3 確實(shí)在響應(yīng)式實(shí)現(xiàn)部分做了一定的優(yōu)化,但實(shí)際上效果是有限的。而 Vue.js 3.2 這次在響應(yīng)式性能方面的優(yōu)化,是真的做到了質(zhì)的飛躍,接下來(lái)我們就來(lái)上點(diǎn)硬菜,從源碼層面分析具體做了哪些優(yōu)化,以及這些優(yōu)化背后帶來(lái)的技術(shù)層面的思考。

響應(yīng)式實(shí)現(xiàn)原理

所謂響應(yīng)式,就是當(dāng)我們修改數(shù)據(jù)后,可以自動(dòng)做某些事情;對(duì)應(yīng)到組件的渲染,就是修改數(shù)據(jù)后,能自動(dòng)觸發(fā)組件的重新渲染。

Vue 3 實(shí)現(xiàn)響應(yīng)式,本質(zhì)上是通過(guò) Proxy API 劫持了數(shù)據(jù)對(duì)象的讀寫(xiě),當(dāng)我們?cè)L問(wèn)數(shù)據(jù)時(shí),會(huì)觸發(fā) getter 執(zhí)行依賴(lài)收集;修改數(shù)據(jù)時(shí),會(huì)觸發(fā) setter 派發(fā)通知。

接下來(lái),我們簡(jiǎn)單分析一下依賴(lài)收集和派發(fā)通知的實(shí)現(xiàn)(Vue.js 3.2 之前的版本)。

依賴(lài)收集

首先來(lái)看依賴(lài)收集的過(guò)程,核心就是在訪(fǎng)問(wèn)響應(yīng)式數(shù)據(jù)的時(shí)候,觸發(fā) getter 函數(shù),進(jìn)而執(zhí)行 track 函數(shù)收集依賴(lài):

let?shouldTrack?=?true //?當(dāng)前激活的?effect let?activeEffect //?原始數(shù)據(jù)對(duì)象?map const?targetMap?=?new?WeakMap() function?track(target,?type,?key)?{if?(!shouldTrack?||?activeEffect?===?undefined)?{return}let?depsMap?=?targetMap.get(target)if?(!depsMap)?{//?每個(gè)?target?對(duì)應(yīng)一個(gè)?depsMaptargetMap.set(target,?(depsMap?=?new?Map()))}let?dep?=?depsMap.get(key)if?(!dep)?{//?每個(gè)?key?對(duì)應(yīng)一個(gè)?dep?集合depsMap.set(key,?(dep?=?new?Set()))}if?(!dep.has(activeEffect))?{//?收集當(dāng)前激活的?effect?作為依賴(lài)dep.add(activeEffect)//?當(dāng)前激活的?effect?收集?dep?集合作為依賴(lài)activeEffect.deps.push(dep)} }

分析這個(gè)函數(shù)的實(shí)現(xiàn)前,我們先想一下要收集的依賴(lài)是什么,我們的目的是實(shí)現(xiàn)響應(yīng)式,就是當(dāng)數(shù)據(jù)變化的時(shí)候可以自動(dòng)做一些事情,比如執(zhí)行某些函數(shù),所以我們收集的依賴(lài)就是數(shù)據(jù)變化后執(zhí)行的副作用函數(shù)。

track 函數(shù)擁有三個(gè)參數(shù),其中 target 表示原始數(shù)據(jù);type 表示這次依賴(lài)收集的類(lèi)型;key 表示訪(fǎng)問(wèn)的屬性。

track 函數(shù)外部創(chuàng)建了全局的 targetMap 作為原始數(shù)據(jù)對(duì)象的 Map,它的鍵是 target,值是 depsMap,作為依賴(lài)的 Map;這個(gè) depsMap 的鍵是 target 的 key,值是 dep 集合,dep 集合中存儲(chǔ)的是依賴(lài)的副作用函數(shù)。為了方便理解,可以通過(guò)下圖表示它們之間的關(guān)系:

因此每次執(zhí)行 track 函數(shù),就是把當(dāng)前激活的副作用函數(shù) activeEffect 作為依賴(lài),然后收集到 target 相關(guān)的 depsMap 對(duì)應(yīng) key 下的依賴(lài)集合 dep 中。

派發(fā)通知

派發(fā)通知發(fā)生在數(shù)據(jù)更新的階段,核心就是在修改響應(yīng)式數(shù)據(jù)時(shí),觸發(fā) setter 函數(shù),進(jìn)而執(zhí)行 trigger 函數(shù)派發(fā)通知:

const?targetMap?=?new?WeakMap() function?trigger(target,?type,?key)?{//?通過(guò)?targetMap?拿到?target?對(duì)應(yīng)的依賴(lài)集合const?depsMap?=?targetMap.get(target)if?(!depsMap)?{//?沒(méi)有依賴(lài),直接返回return}//?創(chuàng)建運(yùn)行的?effects?集合const?effects?=?new?Set()//?添加?effects?的函數(shù)const?add?=?(effectsToAdd)?=>?{if?(effectsToAdd)?{effectsToAdd.forEach(effect?=>?{effects.add(effect)})}}//?SET?|?ADD?|?DELETE?操作之一,添加對(duì)應(yīng)的?effectsif?(key?!==?void?0)?{add(depsMap.get(key))}const?run?=?(effect)?=>?{//?調(diào)度執(zhí)行if?(effect.options.scheduler)?{effect.options.scheduler(effect)}else?{//?直接運(yùn)行effect()}}//?遍歷執(zhí)行?effectseffects.forEach(run) }

trigger 函數(shù)擁有三個(gè)參數(shù),其中 target 表示目標(biāo)原始對(duì)象;type 表示更新的類(lèi)型;key 表示要修改的屬性。

trigger 函數(shù) 主要做了四件事情:

  • 從 targetMap 中拿到 target 對(duì)應(yīng)的依賴(lài)集合 depsMap;

  • 創(chuàng)建運(yùn)行的 effects 集合;

  • 根據(jù) key 從 depsMap 中找到對(duì)應(yīng)的 effect 添加到 effects 集合;

  • 遍歷 effects 執(zhí)行相關(guān)的副作用函數(shù)。

  • 因此每次執(zhí)行 trigger 函數(shù),就是根據(jù) target 和 key,從 targetMap 中找到相關(guān)的所有副作用函數(shù)遍歷執(zhí)行一遍。

    在描述依賴(lài)收集和派發(fā)通知的過(guò)程中,我們都提到了一個(gè)詞:副作用函數(shù),依賴(lài)收集過(guò)程中我們把 activeEffect(當(dāng)前激活副作用函數(shù))作為依賴(lài)收集,它又是什么?接下來(lái)我們來(lái)看一下副作用函數(shù)的廬山真面目。

    副作用函數(shù)

    那么,什么是副作用函數(shù),在介紹它之前,我們先回顧一下響應(yīng)式的原始需求,即我們修改了數(shù)據(jù)就能自動(dòng)做某些事情,舉個(gè)簡(jiǎn)單的例子:

    import?{?reactive?}?from?'vue' const?counter?=?reactive({num:?0 }) function?logCount()?{console.log(counter.num) } function?count()?{counter.num++ } logCount() count()

    我們定義了響應(yīng)式對(duì)象 counter,然后在 logCount 中訪(fǎng)問(wèn)了 counter.num,我們希望在執(zhí)行 count 函數(shù)修改 counter.num 值的時(shí)候,能自動(dòng)執(zhí)行 logCount 函數(shù)。

    按我們之前對(duì)依賴(lài)收集過(guò)程的分析,如果logCount 是 activeEffect 的話(huà),那么就可以實(shí)現(xiàn)需求,但顯然是做不到的,因?yàn)榇a在執(zhí)行到 console.log(counter.num) 這一行的時(shí)候,它對(duì)自己在 logCount 函數(shù)中的運(yùn)行是一無(wú)所知的。

    那么該怎么辦呢?其實(shí)只要我們運(yùn)行 logCount 函數(shù)前,把 logCount 賦值給 activeEffect 就好了:

    activeEffect?=?logCount? logCount()

    順著這個(gè)思路,我們可以利用高階函數(shù)的思想,對(duì) logCount 做一層封裝:

    function?wrapper(fn)?{const?wrapped?=?function(...args)?{activeEffect?=?fnfn(...args)}return?wrapped } const?wrappedLog?=?wrapper(logCount) wrappedLog()

    wrapper 本身也是一個(gè)函數(shù),它接受 fn 作為參數(shù),返回一個(gè)新的函數(shù) wrapped,然后維護(hù)一個(gè)全局變量 activeEffect,當(dāng) wrapped 執(zhí)行的時(shí)候,把 activeEffect 設(shè)置為 fn,然后執(zhí)行 fn 即可。

    這樣當(dāng)我們執(zhí)行 wrappedLog 后,再去修改 counter.num,就會(huì)自動(dòng)執(zhí)行 logCount 函數(shù)了。

    實(shí)際上 Vue 3 就是采用類(lèi)似的做法,在它內(nèi)部就有一個(gè) effect 副作用函數(shù),我們來(lái)看一下它的實(shí)現(xiàn):

    //?全局?effect?棧 const?effectStack?=?[] //?當(dāng)前激活的?effect let?activeEffect function?effect(fn,?options?=?EMPTY_OBJ)?{if?(isEffect(fn))?{//?如果?fn?已經(jīng)是一個(gè)?effect?函數(shù)了,則指向原始函數(shù)fn?=?fn.raw}//?創(chuàng)建一個(gè)?wrapper,它是一個(gè)響應(yīng)式的副作用的函數(shù)const?effect?=?createReactiveEffect(fn,?options)if?(!options.lazy)?{//?lazy?配置,計(jì)算屬性會(huì)用到,非?lazy?則直接執(zhí)行一次effect()}return?effect } function?createReactiveEffect(fn,?options)?{const?effect?=?function?reactiveEffect()?{if?(!effect.active)?{//?非激活狀態(tài),則判斷如果非調(diào)度執(zhí)行,則直接執(zhí)行原始函數(shù)。return?options.scheduler???undefined?:?fn()}if?(!effectStack.includes(effect))?{//?清空?effect?引用的依賴(lài)cleanup(effect)try?{//?開(kāi)啟全局?shouldTrack,允許依賴(lài)收集enableTracking()//?壓棧effectStack.push(effect)activeEffect?=?effect//?執(zhí)行原始函數(shù)return?fn()}finally?{//?出棧effectStack.pop()//?恢復(fù)?shouldTrack?開(kāi)啟之前的狀態(tài)resetTracking()//?指向棧最后一個(gè)?effectactiveEffect?=?effectStack[effectStack.length?-?1]}}}effect.id?=?uid++//?標(biāo)識(shí)是一個(gè)?effect?函數(shù)effect._isEffect?=?true//?effect?自身的狀態(tài)effect.active?=?true//?包裝的原始函數(shù)effect.raw?=?fn//?effect?對(duì)應(yīng)的依賴(lài),雙向指針,依賴(lài)包含對(duì)?effect?的引用,effect?也包含對(duì)依賴(lài)的引用effect.deps?=?[]//?effect?的相關(guān)配置effect.options?=?optionsreturn?effect }

    結(jié)合上述代碼來(lái)看,effect 內(nèi)部通過(guò)執(zhí)行 createReactiveEffect 函數(shù)去創(chuàng)建一個(gè)新的 effect 函數(shù),為了和外部的 effect 函數(shù)區(qū)分,我們把它稱(chēng)作 reactiveEffect 函數(shù),并且還給它添加了一些額外屬性(我在注釋中都有標(biāo)明)。另外,effect 函數(shù)還支持傳入一個(gè)配置參數(shù)以支持更多的 feature,這里就不展開(kāi)了。

    reactiveEffect 函數(shù)就是響應(yīng)式的副作用函數(shù),當(dāng)執(zhí)行 trigger 過(guò)程派發(fā)通知的時(shí)候,執(zhí)行的 effect 就是它。

    按我們之前的分析,reactiveEffect 函數(shù)只需要做兩件事情:讓全局的 activeEffect 指向它, 然后執(zhí)行被包裝的原始函數(shù) fn。

    但實(shí)際上它的實(shí)現(xiàn)要更復(fù)雜一些,首先它會(huì)判斷 effect 的狀態(tài)是否是 active,這其實(shí)是一種控制手段,允許在非 active 狀態(tài)且非調(diào)度執(zhí)行情況,則直接執(zhí)行原始函數(shù) fn 并返回。

    接著判斷 effectStack 中是否包含 effect,如果沒(méi)有就把 effect 壓入棧內(nèi)。之前我們提到,只要設(shè)置 activeEffect = effect 即可,那么這里為什么要設(shè)計(jì)一個(gè)棧的結(jié)構(gòu)呢?

    其實(shí)是考慮到以下這樣一個(gè)嵌套 effect 的場(chǎng)景:

    import?{?reactive}?from?'vue'? import?{?effect?}?from?'@vue/reactivity'? const?counter?=?reactive({?num:?0,?num2:?0? })? function?logCount()?{?effect(logCount2)?console.log('num:',?counter.num)? }? function?count()?{?counter.num++? }? function?logCount2()?{?console.log('num2:',?counter.num2)? }? effect(logCount)? count()

    我們每次執(zhí)行 effect 函數(shù)時(shí),如果僅僅把 reactiveEffect 函數(shù)賦值給 activeEffect,那么針對(duì)這種嵌套場(chǎng)景,執(zhí)行完 effect(logCount2) 后,activeEffect 還是 effect(logCount2) 返回的 reactiveEffect 函數(shù),這樣后續(xù)訪(fǎng)問(wèn) counter.num 的時(shí)候,依賴(lài)收集對(duì)應(yīng)的 activeEffect 就不對(duì)了,此時(shí)我們外部執(zhí)行 count 函數(shù)修改 counter.num 后執(zhí)行的便不是 logCount 函數(shù),而是 logCount2 函數(shù),最終輸出的結(jié)果如下:

    num2:?0? num:?0? num2:?0

    而我們期望的結(jié)果應(yīng)該如下:

    num2:?0? num:?0? num2:?0? num:?1

    因此針對(duì)嵌套 effect 的場(chǎng)景,我們不能簡(jiǎn)單地賦值 activeEffect,應(yīng)該考慮到函數(shù)的執(zhí)行本身就是一種入棧出棧操作,因此我們也可以設(shè)計(jì)一個(gè) effectStack,這樣每次進(jìn)入 reactiveEffect 函數(shù)就先把它入棧,然后 activeEffect 指向這個(gè) reactiveEffect 函數(shù),接著在 fn 執(zhí)行完畢后出棧,再把 activeEffect 指向 effectStack 最后一個(gè)元素,也就是外層 effect 函數(shù)對(duì)應(yīng)的 reactiveEffect。

    這里我們還注意到一個(gè)細(xì)節(jié),在入棧前會(huì)執(zhí)行 cleanup 函數(shù)清空 reactiveEffect 函數(shù)對(duì)應(yīng)的依賴(lài) 。在執(zhí)行 track 函數(shù)的時(shí)候,除了收集當(dāng)前激活的 effect 作為依賴(lài),還通過(guò) activeEffect.deps.push(dep) 把 dep 作為 activeEffect 的依賴(lài),這樣在 cleanup 的時(shí)候我們就可以找到 effect 對(duì)應(yīng)的 dep 了,然后把 effect 從這些 dep 中刪除。cleanup 函數(shù)的代碼如下所示:

    function?cleanup(effect)?{const?{?deps?}?=?effectif?(deps.length)?{for?(let?i?=?0;?i?<?deps.length;?i++)?{deps[i].delete(effect)}deps.length?=?0} }

    為什么需要 cleanup 呢?如果遇到這種場(chǎng)景:

    <template><div v-if="state.showMsg">{{ state.msg }}</div><div v-else>{{ Math.random()}}</div><button @click="toggle">Toggle Msg</button><button @click="switchView">Switch View</button> </template> <script>import { reactive } from 'vue'export default {setup() {const state = reactive({msg: 'Hello World',showMsg: true})function toggle() {state.msg = state.msg === 'Hello World' ? 'Hello Vue' : 'Hello World'}function switchView() {state.showMsg = !state.showMsg}return {toggle,switchView,state}}} </script>

    結(jié)合代碼可以知道,這個(gè)組件的視圖會(huì)根據(jù) showMsg 變量的控制顯示 msg 或者一個(gè)隨機(jī)數(shù),當(dāng)我們點(diǎn)擊 Switch View 的按鈕時(shí),就會(huì)修改這個(gè)變量值。

    假設(shè)沒(méi)有 cleanup,在第一次渲染模板的時(shí)候,activeEffect 是組件的副作用渲染函數(shù),因?yàn)槟0?render 的時(shí)候訪(fǎng)問(wèn)了 state.msg,所以會(huì)執(zhí)行依賴(lài)收集,把副作用渲染函數(shù)作為 state.msg 的依賴(lài),我們把它稱(chēng)作 render effect。然后我們點(diǎn)擊 Switch View 按鈕,視圖切換為顯示隨機(jī)數(shù),此時(shí)我們?cè)冱c(diǎn)擊 Toggle Msg 按鈕,由于修改了 state.msg 就會(huì)派發(fā)通知,找到了 render effect 并執(zhí)行,就又觸發(fā)了組件的重新渲染。

    但這個(gè)行為實(shí)際上并不符合預(yù)期,因?yàn)楫?dāng)我們點(diǎn)擊 Switch View 按鈕,視圖切換為顯示隨機(jī)數(shù)的時(shí)候,也會(huì)觸發(fā)組件的重新渲染,但這個(gè)時(shí)候視圖并沒(méi)有渲染 state.msg,所以對(duì)它的改動(dòng)并不應(yīng)該影響組件的重新渲染。

    因此在組件的 render effect 執(zhí)行之前,如果通過(guò) cleanup 清理依賴(lài),我們就可以刪除之前 state.msg 收集的 render effect 依賴(lài)。這樣當(dāng)我們修改 state.msg 時(shí),由于已經(jīng)沒(méi)有依賴(lài)了就不會(huì)觸發(fā)組件的重新渲染,符合預(yù)期。

    響應(yīng)式實(shí)現(xiàn)的優(yōu)化

    前面分析了響應(yīng)式實(shí)現(xiàn)原理,看上去一切都很 OK,那么這里面還有哪些可以值得優(yōu)化的點(diǎn)呢?

    依賴(lài)收集的優(yōu)化

    目前每次副作用函數(shù)執(zhí)行,都需要先執(zhí)行 cleanup 清除依賴(lài),然后在副作用函數(shù)執(zhí)行的過(guò)程中重新收集依賴(lài),這個(gè)過(guò)程牽涉到大量對(duì) Set 集合的添加和刪除操作。在許多場(chǎng)景下,依賴(lài)關(guān)系是很少改變的,因此這里存在一定的優(yōu)化空間。

    為了減少集合的添加刪除操作,我們需要標(biāo)識(shí)每個(gè)依賴(lài)集合的狀態(tài),比如它是不是新收集的,還是已經(jīng)被收集過(guò)的。

    所以這里需要給集合 dep 添加兩個(gè)屬性:

    export?const?createDep?=?(effects)?=>?{const?dep?=?new?Set(effects)dep.w?=?0dep.n?=?0return?dep }

    其中 w 表示是否已經(jīng)被收集,n 表示是否新收集。

    然后設(shè)計(jì)幾個(gè)全局變量,effectTrackDepth、trackOpBit、maxMarkerBits。

    其中 effectTrackDepth 表示遞歸嵌套執(zhí)行 ?effect 函數(shù)的深度;trackOpBit 用于標(biāo)識(shí)依賴(lài)收集的狀態(tài);maxMarkerBits 表示最大標(biāo)記的位數(shù)。

    接下來(lái)看它們的應(yīng)用:

    function?effect(fn,?options)?{if?(fn.effect)?{fn?=?fn.effect.fn}//?創(chuàng)建?_effect?實(shí)例?const?_effect?=?new?ReactiveEffect(fn)if?(options)?{//?拷貝?options?中的屬性到?_effect?中extend(_effect,?options)if?(options.scope)//?effectScope?相關(guān)處理邏輯recordEffectScope(_effect,?options.scope)}if?(!options?||?!options.lazy)?{//?立即執(zhí)行_effect.run()}//?綁定?run?函數(shù),作為?effect?runnerconst?runner?=?_effect.run.bind(_effect)//?runner?中保留對(duì)?_effect?的引用runner.effect?=?_effectreturn?runner }class?ReactiveEffect?{constructor(fn,?scheduler?=?null,?scope)?{this.fn?=?fnthis.scheduler?=?schedulerthis.active?=?true//?effect?存儲(chǔ)相關(guān)的?deps?依賴(lài)this.deps?=?[]//?effectScope?相關(guān)處理邏輯recordEffectScope(this,?scope)}run()?{if?(!this.active)?{return?this.fn()}if?(!effectStack.includes(this))?{try?{//?壓棧effectStack.push((activeEffect?=?this))enableTracking()//?根據(jù)遞歸的深度記錄位數(shù)trackOpBit?=?1?<<?++effectTrackDepth//?超過(guò)?maxMarkerBits?則?trackOpBit?的計(jì)算會(huì)超過(guò)最大整形的位數(shù),降級(jí)為?cleanupEffectif?(effectTrackDepth?<=?maxMarkerBits)?{//?給依賴(lài)打標(biāo)記initDepMarkers(this)}else?{cleanupEffect(this)}return?this.fn()}finally?{if?(effectTrackDepth?<=?maxMarkerBits)?{//?完成依賴(lài)標(biāo)記finalizeDepMarkers(this)}//?恢復(fù)到上一級(jí)trackOpBit?=?1?<<?--effectTrackDepthresetTracking()//?出棧effectStack.pop()const?n?=?effectStack.length//?指向棧最后一個(gè)?effectactiveEffect?=?n?>?0???effectStack[n?-?1]?:?undefined}}}stop()?{if?(this.active)?{cleanupEffect(this)if?(this.onStop)?{this.onStop()}this.active?=?false}} }

    可以看到,effect 函數(shù)的實(shí)現(xiàn)做了一定的修改和調(diào)整,內(nèi)部使用 ReactiveEffect 類(lèi)創(chuàng)建了一個(gè) _effect 實(shí)例,并且函數(shù)返回的 runner 指向的是 ReactiveEffect 類(lèi)的 run 方法。

    也就是執(zhí)行副作用函數(shù) effect 函數(shù)時(shí),實(shí)際上執(zhí)行的就是這個(gè) run 函數(shù)。

    當(dāng) run 函數(shù)執(zhí)行的時(shí)候,我們注意到 cleanup 函數(shù)不再默認(rèn)執(zhí)行,在封裝的函數(shù) fn 執(zhí)行前,首先執(zhí)行 trackOpBit = 1 << ++effectTrackDepth 記錄 trackOpBit,然后對(duì)比遞歸深度是否超過(guò)了 maxMarkerBits,如果超過(guò)(通常情況下不會(huì))則仍然執(zhí)行老的 cleanup 邏輯,如果沒(méi)超過(guò)則執(zhí)行 initDepMarkers 給依賴(lài)打標(biāo)記,來(lái)看它的實(shí)現(xiàn):

    const?initDepMarkers?=?({?deps?})?=>?{if?(deps.length)?{for?(let?i?=?0;?i?<?deps.length;?i++)?{deps[i].w?|=?trackOpBit?//?標(biāo)記依賴(lài)已經(jīng)被收集}} }

    initDepMarkers 函數(shù)實(shí)現(xiàn)很簡(jiǎn)單,遍歷 _effect 實(shí)例中的 deps 屬性,給每個(gè) dep 的 w 屬性標(biāo)記為 trackOpBit 的值。

    接下來(lái)會(huì)執(zhí)行 fn 函數(shù),在就是副作用函數(shù)封裝的函數(shù),比如針對(duì)組件渲染,fn 就是組件渲染函數(shù)。

    當(dāng) fn 函數(shù)執(zhí)行時(shí)候,會(huì)訪(fǎng)問(wèn)到響應(yīng)式數(shù)據(jù),就會(huì)觸發(fā)它們的 getter,進(jìn)而執(zhí)行 track 函數(shù)執(zhí)行依賴(lài)收集。相應(yīng)的,依賴(lài)收集的過(guò)程也做了一些調(diào)整:

    function?track(target,?type,?key)?{if?(!isTracking())?{return}let?depsMap?=?targetMap.get(target)if?(!depsMap)?{//?每個(gè)?target?對(duì)應(yīng)一個(gè)?depsMaptargetMap.set(target,?(depsMap?=?new?Map()))}let?dep?=?depsMap.get(key)if?(!dep)?{//?每個(gè)?key?對(duì)應(yīng)一個(gè)?dep?集合depsMap.set(key,?(dep?=?createDep()))}const?eventInfo?=?(process.env.NODE_ENV?!==?'production')??{?effect:?activeEffect,?target,?type,?key?}:?undefinedtrackEffects(dep,?eventInfo) }function?trackEffects(dep,?debuggerEventExtraInfo)?{let?shouldTrack?=?falseif?(effectTrackDepth?<=?maxMarkerBits)?{if?(!newTracked(dep))?{//?標(biāo)記為新依賴(lài)dep.n?|=?trackOpBit?//?如果依賴(lài)已經(jīng)被收集,則不需要再次收集shouldTrack?=?!wasTracked(dep)}}else?{//?cleanup?模式shouldTrack?=?!dep.has(activeEffect)}if?(shouldTrack)?{//?收集當(dāng)前激活的?effect?作為依賴(lài)dep.add(activeEffect)//?當(dāng)前激活的?effect?收集?dep?集合作為依賴(lài)activeEffect.deps.push(dep)if?((process.env.NODE_ENV?!==?'production')?&&?activeEffect.onTrack)?{activeEffect.onTrack(Object.assign({effect:?activeEffect},?debuggerEventExtraInfo))}} }

    我們發(fā)現(xiàn),當(dāng)創(chuàng)建 dep 的時(shí)候,是通過(guò)執(zhí)行 createDep 方法完成的,此外,在 dep 把前激活的 effect 作為依賴(lài)收集前,會(huì)判斷這個(gè) dep 是否已經(jīng)被收集,如果已經(jīng)被收集,則不需要再次收集了。此外,這里還會(huì)判斷這 dep 是不是新的依賴(lài),如果不是,則標(biāo)記為新的。

    接下來(lái),我們?cè)賮?lái)看 fn 執(zhí)行完后的邏輯:

    finally?{if?(effectTrackDepth?<=?maxMarkerBits)?{//?完成依賴(lài)標(biāo)記finalizeDepMarkers(this)}//?恢復(fù)到上一級(jí)trackOpBit?=?1?<<?--effectTrackDepthresetTracking()//?出棧effectStack.pop()const?n?=?effectStack.length//?指向棧最后一個(gè)?effectactiveEffect?=?n?>?0???effectStack[n?-?1]?:?undefined }

    在滿(mǎn)足依賴(lài)標(biāo)記的條件下,需要執(zhí)行 finalizeDepMarkers 完成依賴(lài)標(biāo)記,來(lái)看它的實(shí)現(xiàn):

    const?finalizeDepMarkers?=?(effect)?=>?{const?{?deps?}?=?effectif?(deps.length)?{let?ptr?=?0for?(let?i?=?0;?i?<?deps.length;?i++)?{const?dep?=?deps[i]//?曾經(jīng)被收集過(guò)但不是新的依賴(lài),需要?jiǎng)h除if?(wasTracked(dep)?&&?!newTracked(dep))?{dep.delete(effect)}else?{deps[ptr++]?=?dep}//?清空狀態(tài)dep.w?&=?~trackOpBitdep.n?&=?~trackOpBit}deps.length?=?ptr} }

    finalizeDepMarkers 主要做的事情就是找到那些曾經(jīng)被收集過(guò)但是新的一輪依賴(lài)收集沒(méi)有被收集的依賴(lài),從 deps 中移除。這其實(shí)就是解決前面提到的需要 cleanup 場(chǎng)景的問(wèn)題:在新的組件渲染過(guò)程中沒(méi)有訪(fǎng)問(wèn)到的響應(yīng)式對(duì)象,那么它的變化不應(yīng)該觸發(fā)組件的重新渲染。

    以上就實(shí)現(xiàn)了依賴(lài)收集部分的優(yōu)化,可以看到相比于之前每次執(zhí)行 effect 函數(shù)都需要先清空依賴(lài),再添加依賴(lài)的過(guò)程,現(xiàn)在的實(shí)現(xiàn)會(huì)在每次執(zhí)行 effect 包裹的函數(shù)前標(biāo)記依賴(lài)的狀態(tài),過(guò)程中對(duì)于已經(jīng)收集的依賴(lài)不會(huì)重復(fù)收集,執(zhí)行完 effect 函數(shù)還會(huì)移除掉已被收集但是新的一輪依賴(lài)收集中沒(méi)有被收集的依賴(lài)。

    優(yōu)化后對(duì)于 dep 依賴(lài)集合的操作減少了,自然也就優(yōu)化了性能。

    響應(yīng)式 API 的優(yōu)化

    響應(yīng)式 API 的優(yōu)化主要體現(xiàn)在對(duì) ref、computed 等 API 的優(yōu)化。

    以 ref API 為例,來(lái)看看它優(yōu)化前的實(shí)現(xiàn):

    function?ref(value)?{return?createRef(value) }const?convert?=?(val)?=>?isObject(val)???reactive(val)?:?valfunction?createRef(rawValue,?shallow?=?false)?{if?(isRef(rawValue))?{//?如果傳入的就是一個(gè) ref,那么返回自身即可,處理嵌套 ref 的情況。return?rawValue}return?new?RefImpl(rawValue,?shallow) }class?RefImpl?{constructor(_rawValue,?_shallow?=?false)?{this._rawValue?=?_rawValuethis._shallow?=?_shallowthis.__v_isRef?=?true//?非?shallow?的情況,如果它的值是對(duì)象或者數(shù)組,則遞歸響應(yīng)式this._value?=?_shallow???_rawValue?:?convert(_rawValue)}get?value()?{//?給?value?屬性添加?getter,并做依賴(lài)收集track(toRaw(this),?'get'?/*?GET?*/,?'value')return?this._value}set?value(newVal)?{//?給?value?屬性添加?setterif?(hasChanged(toRaw(newVal),?this._rawValue))?{this._rawValue?=?newValthis._value?=?this._shallow???newVal?:?convert(newVal)//?派發(fā)通知trigger(toRaw(this),?'set'?/*?SET?*/,?'value',?newVal)}} }

    ref 函數(shù)返回了 createRef 函數(shù)執(zhí)行的返回值,而在 createRef 內(nèi)部,首先處理了嵌套 ref 的情況,如果傳入的 rawValue 也是個(gè) ref,那么直接返回 rawValue;接著返回 RefImpl 對(duì)象的實(shí)例。

    而 RefImpl 內(nèi)部的實(shí)現(xiàn),主要是劫持它的實(shí)例 value 屬性的 getter 和 setter。

    當(dāng)訪(fǎng)問(wèn)一個(gè) ref 對(duì)象的 value 屬性,會(huì)觸發(fā) getter 執(zhí)行 track 函數(shù)做依賴(lài)收集然后返回它的值;當(dāng)修改一個(gè) ref 對(duì)象的 value 值,則會(huì)觸發(fā) setter 設(shè)置新值并且執(zhí)行 trigger 函數(shù)派發(fā)通知,如果新值 newVal 是對(duì)象或者數(shù)組類(lèi)型,那么把它轉(zhuǎn)換成一個(gè) reactive 對(duì)象。

    接下來(lái),我們?cè)賮?lái)看 Vue.js 3.2 對(duì)于這部分的實(shí)現(xiàn)相關(guān)的改動(dòng):

    class?RefImpl?{constructor(value,?_shallow?=?false)?{this._shallow?=?_shallowthis.dep?=?undefinedthis.__v_isRef?=?truethis._rawValue?=?_shallow???value?:?toRaw(value)this._value?=?_shallow???value?:?convert(value)}get?value()?{trackRefValue(this)return?this._value}set?value(newVal)?{newVal?=?this._shallow???newVal?:?toRaw(newVal)if?(hasChanged(newVal,?this._rawValue))?{this._rawValue?=?newValthis._value?=?this._shallow???newVal?:?convert(newVal)triggerRefValue(this,?newVal)}} }

    主要改動(dòng)部分就是對(duì) ref 對(duì)象的 value 屬性執(zhí)行依賴(lài)收集和派發(fā)通知的邏輯。

    在 Vue.js 3.2 版本的 ref 的實(shí)現(xiàn)中,關(guān)于依賴(lài)收集部分,由原先的 track 函數(shù)改成了 trackRefValue,來(lái)看它的實(shí)現(xiàn):

    function?trackRefValue(ref)?{if?(isTracking())?{ref?=?toRaw(ref)if?(!ref.dep)?{ref.dep?=?createDep()}if?((process.env.NODE_ENV?!==?'production'))?{trackEffects(ref.dep,?{target:?ref,type:?"get"?/*?GET?*/,key:?'value'})}else?{trackEffects(ref.dep)}} }

    可以看到這里直接把 ref 的相關(guān)依賴(lài)保存到 dep 屬性中,而在 track 函數(shù)的實(shí)現(xiàn)中,會(huì)把依賴(lài)保留到全局的 targetMap 中:

    let?depsMap?=?targetMap.get(target) if?(!depsMap)?{//?每個(gè)?target?對(duì)應(yīng)一個(gè)?depsMaptargetMap.set(target,?(depsMap?=?new?Map())) } let?dep?=?depsMap.get(key) if?(!dep)?{//?每個(gè)?key?對(duì)應(yīng)一個(gè)?dep?集合depsMap.set(key,?(dep?=?createDep())) }

    顯然,track 函數(shù)內(nèi)部可能需要做多次判斷和設(shè)置邏輯,而把依賴(lài)保存到 ref 對(duì)象的 dep 屬性中則省去了這一系列的判斷和設(shè)置,從而優(yōu)化性能。

    相應(yīng)的,ref 的實(shí)現(xiàn)關(guān)于派發(fā)通知部分,由原先的 trigger 函數(shù)改成了 triggerRefValue,來(lái)看它的實(shí)現(xiàn):

    function?triggerRefValue(ref,?newVal)?{ref?=?toRaw(ref)if?(ref.dep)?{if?((process.env.NODE_ENV?!==?'production'))?{triggerEffects(ref.dep,?{target:?ref,type:?"set"?/*?SET?*/,key:?'value',newValue:?newVal})}else?{triggerEffects(ref.dep)}} }function?triggerEffects(dep,?debuggerEventExtraInfo)?{for?(const?effect?of?isArray(dep)???dep?:?[...dep])?{if?(effect?!==?activeEffect?||?effect.allowRecurse)?{if?((process.env.NODE_ENV?!==?'production')?&&?effect.onTrigger)?{effect.onTrigger(extend({?effect?},?debuggerEventExtraInfo))}if?(effect.scheduler)?{effect.scheduler()}else?{effect.run()}}} }

    由于直接從 ref 屬性中就拿到了它所有的依賴(lài)且遍歷執(zhí)行,不需要執(zhí)行 trigger 函數(shù)一些額外的查找邏輯,因此在性能上也得到了提升。

    trackOpBit 的設(shè)計(jì)

    細(xì)心的你可能會(huì)發(fā)現(xiàn),標(biāo)記依賴(lài)的 trackOpBit,在每次計(jì)算時(shí)采用了左移的運(yùn)算符 trackOpBit = 1 << ++effectTrackDepth;并且在賦值的時(shí)候,使用了或運(yùn)算:

    deps[i].w?|=?trackOpBit dep.n?|=?trackOpBit

    那么為什么這么設(shè)計(jì)呢?因?yàn)?effect 的執(zhí)行可能會(huì)有遞歸的情況,通過(guò)這種方式就可以記錄每個(gè)層級(jí)的依賴(lài)標(biāo)記情況。

    在判斷某個(gè) dep 是否已經(jīng)被依賴(lài)收集的時(shí)候,使用了 wasTracked 函數(shù):

    const?wasTracked?=?(dep)?=>?(dep.w?&?trackOpBit)?>?0

    通過(guò)與運(yùn)算的結(jié)果是否大于 0 來(lái)判斷,這就要求依賴(lài)被收集時(shí)嵌套的層級(jí)要匹配。舉個(gè)例子,假設(shè)此時(shí) dep.w 的值是 2,說(shuō)明它是在第一層執(zhí)行 effect 函數(shù)時(shí)創(chuàng)建的,但是這時(shí)候已經(jīng)執(zhí)行了嵌套在第二層的 effect 函數(shù),trackOpBit 左移兩位變成了 4,2 & 4 的值是 0,那么 wasTracked 函數(shù)返回值為 false,說(shuō)明需要收集這個(gè)依賴(lài)。顯然,這個(gè)需求是合理的。

    可以看到,如果沒(méi)有 trackOpBit 位運(yùn)算的設(shè)計(jì),你就很難去處理不同嵌套層級(jí)的依賴(lài)標(biāo)記,這個(gè)設(shè)計(jì)也體現(xiàn)了 basvanmeurs 大佬非常扎實(shí)的計(jì)算機(jī)基礎(chǔ)功力。

    總結(jié)

    一般在 Vue.js 的應(yīng)用中,對(duì)響應(yīng)式數(shù)據(jù)的訪(fǎng)問(wèn)和修改都是非常頻繁的操作,因此對(duì)這個(gè)過(guò)程的性能優(yōu)化,將極大提升整個(gè)應(yīng)用的性能。

    大部分人去看 Vue.js 響應(yīng)式的實(shí)現(xiàn),可能目標(biāo)最多就是搞明白其中的實(shí)現(xiàn)原理,而很少去關(guān)注其中實(shí)現(xiàn)是否是最優(yōu)的。而 basvanmeurs 大佬能對(duì)提出這一系列的優(yōu)化的實(shí)現(xiàn),并且手寫(xiě)了一個(gè) benchmark 工具來(lái)驗(yàn)證自己的優(yōu)化,非常值得我們學(xué)習(xí)。

    希望你看完這篇文章,除了點(diǎn)贊在看轉(zhuǎn)發(fā)三連之外,也可以去看看原貼,看看他們的討論,相信你會(huì)收獲更多。

    前端的性能優(yōu)化永遠(yuǎn)是一個(gè)值得深挖的方向,希望在日后的開(kāi)發(fā)中,不論是寫(xiě)框架還是業(yè)務(wù),你都能夠經(jīng)常去思考其中可能存在的優(yōu)化的點(diǎn)。

    參考資料

    [1]?Vue.js 3.2 升級(jí)介紹: https://blog.vuejs.org/posts/vue-3.2.html

    [2] basvanmeurs GitHub 地址:https://github.com/basvanmeurs

    [3] 相關(guān) PR 討論地址:https://github.com/vuejs/vue-next/pull/2345

    [4] Thoughts on ES6 Proxies Performance: https://thecodebarbarian.com/thoughts-on-es6-proxies-performance

    [5] Proxy-vs-DefineProperty repo: https://github.com/ustbhuangyi/Proxy-vs-DefineProperty

    [6 ]benchmark 工具: https://github.com/basvanmeurs/vue-next-benchmarks

    最近組建了一個(gè)湖南人的前端交流群,如果你是湖南人可以加我微信?ruochuan12?私信 湖南?拉你進(jìn)群。


    推薦閱讀

    我在阿里招前端,該怎么幫你(可進(jìn)面試群)
    我讀源碼的經(jīng)歷

    面對(duì) this 指向丟失,尤雨溪在 Vuex 源碼中是怎么處理的
    老姚淺談:怎么學(xué)JavaScript?

    ·················?若川簡(jiǎn)介?·················

    你好,我是若川,畢業(yè)于江西高校。現(xiàn)在是一名前端開(kāi)發(fā)“工程師”。寫(xiě)有《學(xué)習(xí)源碼整體架構(gòu)系列》多篇,在知乎、掘金收獲超百萬(wàn)閱讀。
    從2014年起,每年都會(huì)寫(xiě)一篇年度總結(jié),已經(jīng)寫(xiě)了7篇,點(diǎn)擊查看年度總結(jié)。
    同時(shí),活躍在知乎@若川,掘金@若川。致力于分享前端開(kāi)發(fā)經(jīng)驗(yàn),愿景:幫助5年內(nèi)前端人走向前列。

    識(shí)別方二維碼加我微信、拉你進(jìn)源碼共讀

    今日話(huà)題

    略。歡迎分享、收藏、點(diǎn)贊、在看我的公眾號(hào)文章~

    總結(jié)

    以上是生活随笔為你收集整理的细说 Vue.js 3.2 关于响应式部分的优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    日本中文字幕电影在线免费观看 | 久久久久国产成人免费精品免费 | 亚洲日本色 | 永久中文字幕 | 欧美亚洲另类在线视频 | 西西www4444大胆在线 | 91av在| 午夜 免费| 91色综合| 黄色大片入口 | 亚洲成人精品久久久 | 天天艹天天干天天 | 天天色综合久久 | 亚洲精品国产精品乱码在线观看 | 西西人体4444www高清视频 | 欧美日韩国产一区 | 国产精品九九九九九九 | 久久黄色美女 | 久久久男人的天堂 | 国产视频在线播放 | 国产精品久久久久久影院 | 日韩成人一级大片 | 久久这里只有精品视频首页 | 精品一区二区三区电影 | 欧美影院久久 | 成人av中文字幕 | 日本在线精品视频 | 国产精品正在播放 | 国产欧美精品一区二区三区四区 | 久久久亚洲精华液 | 久久网页 | 久久亚洲欧美日韩精品专区 | 色偷偷88888欧美精品久久久 | 欧美激情视频一二三区 | www.久热| 四虎成人精品永久免费av九九 | 日韩在线视频观看免费 | 免费福利片| 国产精品毛片久久久久久久 | 成人va在线观看 | 国产精品毛片久久久久久久 | 国产亚洲一区二区在线观看 | www.色就是色 | 久久9精品 | 日日操操操 | 国产女人18毛片水真多18精品 | 日韩1页 | 精品一区二区三区在线播放 | 色偷偷男人的天堂av | 狠狠干夜夜爱 | 国产美女精品视频免费观看 | 天堂v中文| 黄色一级动作片 | 日韩xxxxxxxxx | 欧美福利在线播放 | 亚洲国产精品va在线看 | 久久综合色影院 | 亚洲精品999 | 99在线免费观看视频 | 伊人亚洲综合 | 18性欧美xxxⅹ性满足 | 波多野结衣综合网 | 三级av免费看 | 午夜精品视频一区二区三区在线看 | 久久夜色电影 | 韩国精品一区二区三区六区色诱 | 天天综合狠狠精品 | 丝袜网站在线观看 | 开心激情久久 | 麻豆视频在线免费观看 | 超碰免费97 | 久久999久久 | 久久成视频 | 黄色大片网| 天天操夜夜操夜夜操 | 久久三级毛片 | 免费观看性生交大片3 | 99热精品国产| 一区二区精品在线观看 | 日本激情视频中文字幕 | 91麻豆高清视频 | 97精品国产 | 99视频免费看 | 91传媒在线看 | 欧美一级日韩三级 | 精品国产aⅴ麻豆 | 午夜久久精品 | 国产精品精品视频 | 激情综合电影网 | 91精品视频在线观看免费 | 亚洲视频免费在线看 | 麻豆国产视频下载 | 天天干,天天射,天天操,天天摸 | www.国产高清 | 日韩三级在线 | 精品久久久999 | 91视频最新网址 | 国产精品刺激对白麻豆99 | 狠狠狠色丁香综合久久天下网 | 久久精品国产第一区二区三区 | 在线欧美国产 | 亚洲精品视频在线播放 | 日本一区二区免费在线观看 | 日韩欧美国产精品 | 国产色就色 | 在线 视频 一区二区 | 国产日韩欧美精品在线观看 | 欧美一级视频在线观看 | 91人人干 | 亚洲国产精品激情在线观看 | 91网站在线视频 | www最近高清中文国语在线观看 | 日韩中文字幕a | 伊人成人久久 | 在线视频一二区 | 91中文字幕 | 国产资源在线视频 | 激情丁香在线 | 亚洲色影爱久久精品 | 在线免费观看亚洲视频 | 久久精品伊人 | 高清有码中文字幕 | 国产小视频免费在线网址 | 成年人网站免费观看 | 一区二区精品在线 | 97精品国产97久久久久久春色 | 免费在线观看av网址 | 久久成人国产精品入口 | 国内精品视频在线播放 | 欧美一区二区伦理片 | 亚洲狠狠丁香婷婷综合久久久 | 国产亚洲欧美日韩高清 | 亚洲成人免费在线观看 | 五月开心婷婷网 | 久久久伦理 | 人人超碰在线 | 99福利片 | 婷婷丁香激情 | 国产亚洲精品久久久久动 | 欧美一级电影片 | 国产精品99精品 | 色播五月激情综合网 | 国产精品欧美日韩 | 日日夜夜网 | 在线视频91 | 96精品视频 | 亚洲免费国产视频 | 欧美日韩久久不卡 | 亚洲成人在线免费 | 久久国产精品视频 | 婷婷久久丁香 | 婷婷国产一区二区三区 | 美女视频永久黄网站免费观看国产 | 手机看国产毛片 | 又黄又刺激的视频 | 在线免费色 | 麻豆视频入口 | 99视频久| 久久国产精品网站 | 欧美精品视 | 日本精品久久久久中文字幕5 | 麻豆91在线播放 | 麻豆视频国产精品 | 成人毛片在线观看视频 | 91视频链接 | 国产精品私人影院 | 伊人狠狠色 | www.亚洲激情.com | 国产小视频在线播放 | 日韩激情中文字幕 | 91系列在线| 在线观看免费成人av | 成 人 黄 色 片 在线播放 | 亚洲国产成人精品电影在线观看 | 成人国产电影在线观看 | 色久天 | 99久久精品免费看国产免费软件 | 久久这里有 | 国产vs久久 | 国产精品大片在线观看 | 久久久激情视频 | 五月天狠狠操 | 欧美婷婷色 | 欧美精品乱码久久久久 | 国产视频一区精品 | 中文字幕在线影视资源 | 欧美大片mv免费 | 精品人人人人 | 久久久久亚洲精品成人网小说 | 伊人影院av | 免费在线观看亚洲视频 | 国产福利91精品张津瑜 | 日日干夜夜骑 | 国产伦理久久 | www免费网站在线观看 | 天天操天天舔天天爽 | 久久久久激情 | 一级黄色视屏 | 亚洲欧洲在线视频 | 国产一级片免费播放 | 天天天天天操 | 成人午夜性影院 | 国产一区在线免费观看视频 | 高清不卡毛片 | 久草视频中文在线 | 天天做天天射 | 欧美日韩中 | 欧洲亚洲激情 | 91黄站| 久久精品91久久久久久再现 | 91网页版在线观看 | 日韩中文字幕免费看 | 久久国产精品一区二区三区 | 久草99 | 草久草久| 久草热视频 | 欧美一区二区三区四区夜夜大片 | 国产精品观看 | 久久精品激情 | 一区二区三区日韩精品 | 久久精品免费观看 | 国产精品一区二区精品视频免费看 | 亚洲午夜精品久久久久久久久 | 天天操夜夜曰 | 国产亚州精品视频 | 中文字幕中文字幕在线中文字幕三区 | 日韩欧美区 | 丁香六月在线 | 揉bbb玩bbb少妇bbb | 日韩 精品 一区 国产 麻豆 | 国产精品久久久久一区二区国产 | 激情久久一区二区三区 | 91精品一区二区三区久久久久久 | 国产网站在线免费观看 | 99在线热播精品免费99热 | 欧美精品中文在线免费观看 | 日韩欧美久久 | 免费网站黄 | 久久伊人热| 天天操狠狠操 | 久久久久久久久久久久影院 | 在线观看免费一区 | av视屏在线播放 | 欧美成年性 | 国产精品乱码久久久 | 国产精品欧美久久久久三级 | 亚洲 欧洲 国产 精品 | 国产成年免费视频 | 在线观看免费视频你懂的 | 99 国产精品| av成人免费网站 | 天天操操操操操操 | 国产真实精品久久二三区 | 手机在线看a | 99麻豆久久久国产精品免费 | 五月精品| 国产在线观看av | 国产亚洲精品福利 | 一二三精品视频 | 日韩视频一区二区 | 草久草久 | 免费网站在线观看成人 | 欧美日韩中文在线视频 | 99精品国产99久久久久久福利 | 亚洲免费av在线播放 | 精品久久久久亚洲 | 三级a视频 | 四虎在线观看视频 | 国产一区久久 | 欧美性黄网官网 | 天天操天天干天天综合网 | 6080yy精品一区二区三区 | 久久久免费av | 久久久高清视频 | 新av在线 | 日韩av黄| 中文字幕在线观看一区二区三区 | 香蕉国产91| 亚洲欧美日韩精品久久久 | 99久久精品日本一区二区免费 | 国产精品久久久久一区二区三区共 | 国产在线视频资源 | 国产人在线成免费视频 | 久久久久免费视频 | 视频在线一区二区三区 | 亚洲日韩中文字幕 | 久久精品—区二区三区 | 不卡国产视频 | 国产精品免费视频一区二区 | 国产在线v | 就要干b | 日本久久高清视频 | 国内精品美女在线观看 | 免费观看www视频 | 欧美另类成人 | 国产成人一区二区三区在线观看 | 国产香蕉视频在线播放 | 99c视频在线 | 国产精品久久久久久久久久久不卡 | 国产不卡在线视频 | 五月激情视频 | 色婷婷激婷婷情综天天 | 中文字幕中文中文字幕 | 日韩在线观看网址 | 国产色在线视频 | av怡红院| 草久视频在线 | 一区二区成人国产精品 | 四虎国产精品免费观看视频优播 | 欧美一区二区日韩一区二区 | 91精品国| 九九热免费在线视频 | 欧美日韩免费网站 | 黄色av电影在线观看 | 亚洲免费国产 | av在线免费播放 | 亚洲精品国精品久久99热 | 播五月婷婷| 欧美成人日韩 | 日韩视频一区二区三区 | 在线播放精品一区二区三区 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | av三级在线免费观看 | 中文字幕av免费在线观看 | 又色又爽的网站 | 亚洲精品免费看 | 欧美乱码精品一区二区 | 国产一级做a爱片久久毛片a | 99热精品久久 | 美女黄久久 | 久久激五月天综合精品 | 日本久久精品视频 | www.黄色在线 | 五月婷婷丁香网 | 五月天婷婷丁香花 | 国产免费xvideos视频入口 | 成人在线视频一区 | 成片免费观看视频大全 | 18国产精品白浆在线观看免费 | 亚洲91精品| 色婷婷狠狠五月综合天色拍 | 一区二区精品国产 | 国产视频在线观看免费 | 黄色av高清 | 国产亚洲在 | 欧美a免费| 天天摸天天操天天舔 | 欧美日韩在线免费观看视频 | 国产成人三级在线播放 | 96久久久 | 91久久人澡人人添人人爽欧美 | 国产精品一区二区美女视频免费看 | 在线看国产精品 | 日韩久久精品一区二区 | 天天插视频 | 久久久999精品视频 国产美女免费观看 | 伊人开心激情 | 久久精品国产v日韩v亚洲 | 欧美少妇的秘密 | 国产又粗又猛又爽 | 一级免费看视频 | 久草在线免费色站 | 国产福利91精品张津瑜 | 天天·日日日干 | 国内久久精品视频 | 人人爱人人射 | 九九色网| 日韩电影在线视频 | 亚洲精品xx | 国产精品一区二区精品视频免费看 | 亚洲国产wwwccc36天堂 | 婷婷色站 | www看片网站 | 国产va精品免费观看 | 奇米影视8888在线观看大全免费 | 91精品播放 | 日本黄色a级大片 | 久久精品视频国产 | 中文在线免费一区三区 | 夜夜看av | 成人午夜在线观看 | 一区二区视频免费在线观看 | 超碰免费公开 | 国产麻豆果冻传媒在线观看 | 国产高清在线免费视频 | 伊人久久五月天 | 天堂av在线中文在线 | 日韩影片在线观看 | 国产一区二区视频在线播放 | 久久久久综合精品福利啪啪 | 久久久午夜剧场 | 超碰97人人射妻 | 日韩69视频| 国产91av视频在线观看 | 亚洲九九影院 | 97国产| 欧美精品第一 | 啪啪免费试看 | 黄色免费高清视频 | 亚洲精品人人 | 黄色日本免费 | 97免费| 青青草国产免费 | 中国一级片免费看 | 欧美乱熟臀69xxxxxx | 人人艹视频 | 久久精品资源 | 免费看黄电影 | 欧美日韩精品在线视频 | 中文字幕在线影视资源 | 亚洲成人资源 | 麻豆免费视频观看 | 毛片1000部免费看 | 婷婷精品国产欧美精品亚洲人人爽 | 在线免费色 | 日韩字幕| 亚洲欧美视频一区二区三区 | 日韩激情片在线观看 | 久久综合久久综合九色 | 男女精品久久 | 丁香久久综合 | 在线免费精品视频 | 国产一级片免费播放 | av电影在线观看 | 夜夜嗨av色一区二区不卡 | 成人免费视频免费观看 | 丁香六月久久综合狠狠色 | 免费a级大片 | 97超碰人人爱 | 日韩免费三区 | 国产精品国产三级国产不产一地 | 国产91精品一区二区 | 中文字幕免费一区二区 | 伊人精品在线 | 免费三级网 | 国产精品一区二区三区在线看 | 手机在线视频福利 | 国产精品久久久久久久妇 | 黄色小说免费在线观看 | 日韩激情网 | 二区三区精品 | 亚洲一区av| 91视频 - 88av| 天天做日日做天天爽视频免费 | 丁香六月激情 | 日本中文字幕在线一区 | 国产一级视屏 | 久久精品视频国产 | 欧美国产日韩一区二区三区 | 91精品久| 欧美aa一级| 日本一区二区三区免费看 | 久久免费看片 | 69精品在线观看 | 日韩激情精品 | 黄色网免费 | 天堂视频中文在线 | 九九色综合| 特及黄色片 | 婷婷丁香花 | 中文字幕一区二区三区在线播放 | 日本韩国中文字幕 | 四虎4hu永久免费 | 中文字幕免费观看 | 黄色免费av | 天天天天天天干 | 欧美精品在线观看免费 | 成人一区二区在线观看 | 日本久久成人 | 国产亚洲成av人片在线观看桃 | 亚洲国产小视频在线观看 | 欧美日韩国产综合一区二区 | 中国精品一区二区 | 亚洲伦理一区 | 亚州欧美精品 | 国产亚洲视频系列 | 欧美日产在线观看 | 亚洲资源网 | 国产在线a视频 | 久久综合婷婷国产二区高清 | 伊人婷婷激情 | 久久99九九99精品 | 国产99久久久国产精品免费二区 | 日韩精品久久久久 | 久草久草在线 | 91丨九色丨蝌蚪丨对白 | 亚洲欧美国产视频 | 91九色porn在线资源 | 久久免费观看少妇a级毛片 久久久久成人免费 | 国产99久久久国产精品免费看 | 国产精品欧美一区二区 | 9在线观看免费高清完整版在线观看明 | 深夜免费小视频 | 91天堂素人约啪 | 91喷水| 在线中文字幕电影 | 91在线www | 欧美日韩一区二区三区视频 | 亚洲在线高清 | 日韩精品视频免费专区在线播放 | 国内精品免费久久影院 | www.啪啪.com| 欧美精品在线观看一区 | 色婷五月天 | avcom在线| av黄免费看| 免费观看一级特黄欧美大片 | 欧美一区二区精品在线 | 天天爽天天爽夜夜爽 | 免费黄色av电影 | 中文字幕成人网 | 免费男女羞羞的视频网站中文字幕 | 成人免费看视频 | 国产精品入口传媒 | 91在线免费看片 | 中文字幕色在线 | 99国产精品久久久久久久久久 | 欧美激情xxxx | 日韩av成人 | a一片一级| 久久精品99国产精品日本 | a在线观看免费视频 | 干 操 插| 成片免费观看视频 | 久久99亚洲精品 | 91视频下载 | 激情一区二区三区欧美 | 91精品一区二区在线观看 | 久久综合久久鬼 | 国产精品影音先锋 | 黄色片免费电影 | 亚洲黄色免费在线看 | 国产精品欧美精品 | 国内视频在线 | 91欧美视频网站 | 国产专区一| 国产在线观看中文字幕 | 91在线www | 国产视频一区在线播放 | 国产一级片直播 | 国产精品美女久久久久久网站 | 中文字幕在线有码 | 国产精品一区二区久久 | 干干操操 | 色五月色开心色婷婷色丁香 | 成人黄色在线视频 | 美女视频黄的免费的 | 中文字幕日韩国产 | 美女网站视频免费都是黄 | 国产黄色网 | 色综合夜色一区 | 成人午夜黄色影院 | 日韩av网址在线 | 久久综合射 | 亚洲精品短视频 | 97日日碰人人模人人澡分享吧 | 激情五月婷婷激情 | 久人人| 日日夜夜天天操 | av再线观看| 一级α片免费看 | 欧美日韩国产欧美 | www.天天草| 久久的色 | 亚洲视频免费在线看 | 欧美性色综合网站 | 欧美最新另类人妖 | 国产 中文 日韩 欧美 | 在线小视频 | 亚洲国产成人精品电影在线观看 | 99久久精品国产一区二区成人 | 久久www免费人成看片高清 | 国语久久 | 国产伦精品一区二区三区照片91 | 欧美日本国产在线观看 | 久草在线免费资源 | 激情av网址| 九九热精品视频在线播放 | 国产成人亚洲精品自产在线 | 欧美动漫一区二区三区 | 丁香花在线观看视频在线 | 国产精品麻豆视频 | 在线视频久 | 97操碰| 一区二区三区在线播放 | 992tv人人网tv亚洲精品 | 一级做a视频 | 四虎www.| 美女黄频在线观看 | 国产精品久久久久久av | 美女视频黄免费 | 最近中文国产在线视频 | 97精品国产97久久久久久 | 最近中文字幕大全中文字幕免费 | 黄污网站在线 | 欧美午夜精品久久久久久孕妇 | 免费看黄电影 | 99视频这里只有 | 一区二区三区免费在线观看视频 | 狠狠色丁香婷婷综合久小说久 | 精品99在线观看 | 国产精品精品久久久久久 | 成人网色| 深夜国产在线 | 欧美大片aaa | 黄a在线观看 | 97视频网站 | 91系列在线 | 亚洲精品国产精品国自 | 91久久国产精品 | 天天干,天天射,天天操,天天摸 | 最新国产中文字幕 | 亚洲男男gaygayxxxgv | 日本高清dvd| 久久久国产精品成人免费 | 精品久久久久久亚洲综合网 | 又黄又爽又刺激的视频 | 大型av综合网站 | av福利免费 | 激情五月婷婷综合网 | 人人澡人人草 | 亚洲国产午夜精品 | 国产精品观看 | 狠狠色综合网站久久久久久久 | www.五月婷婷.com | 国产精品久久久久久久久婷婷 | 狠狠干夜夜操 | 国偷自产中文字幕亚洲手机在线 | 成人影音av| 东方av在 | 伊人色**天天综合婷婷 | 国产一区二区久久 | 亚洲男女精品 | 国产视频手机在线 | 成人黄性视频 | 色综合五月 | 麻豆一级视频 | 黄在线免费观看 | 国产成人高清在线 | 日韩精品一区二区三区电影 | 美女网站视频免费都是黄 | 天天综合婷婷 | 天天插狠狠插 | 91av短视频 | 91av在 | 在线观看视频在线 | 亚洲va欧美va人人爽春色影视 | 国产精品日韩欧美 | 人人澡人人草 | 国产热re99久久6国产精品 | 麻豆传媒视频在线播放 | 成人久久18免费网站麻豆 | 最新久久久 | 日本在线视频网址 | 日日天天狠狠 | 欧美一级艳片视频免费观看 | 国产精品久久久久av福利动漫 | 日韩电影一区二区在线观看 | 99久久夜色精品国产亚洲 | 欧美性视频网站 | 国产精品黑丝在线观看 | 国产91亚洲精品 | 亚洲在线网址 | 亚洲精品玖玖玖av在线看 | 天天爱天天操天天爽 | 在线观看色视频 | 91精品老司机久久一区啪 | 中文字幕一区二区三区视频 | 国产精品久久久久久久电影 | 伊人色播 | 在线观看免费一级片 | 欧美成人基地 | 天天爱天天操天天干 | 色偷偷97| 亚洲精品在线观看中文字幕 | 国产精品久久久久久久久久了 | 久久99精品国产 | 人人爽人人舔 | 免费高清在线观看成人 | 在线成人欧美 | 国产亚洲精品久久久久动 | 国产亚洲va综合人人澡精品 | 在线观看v片 | 欧美精品在线观看一区 | 三级黄免费看 | 久久久久久久久久久久久久av | 久久一视频| 精品影院一区二区久久久 | 精品国产片 | 天天摸天天操天天舔 | 国产精品va在线观看入 | 成人一级片免费看 | 黄色大片视频网站 | 国产99久久久欧美黑人 | 国产精品不卡视频 | 精品三级av| 一区二区三区日韩在线 | 国产最新视频在线观看 | 国产 日韩 在线 亚洲 字幕 中文 | 国产精品亚洲精品 | 久久精品精品电影网 | 毛片网站在线看 | 色综合久久久久综合 | 国产五月婷 | 久久资源在线 | 高清av免费看 | 五月天亚洲精品 | 天天操天天摸天天干 | av在线日韩 | 91视频在线观看下载 | 99r在线观看 | 人人草人人草 | 黄色aa久久| 黄色小说免费观看 | 国产成人av在线影院 | av电影一区二区三区 | 超碰97免费在线 | 中文字幕乱码一区二区 | 国产天天爽 | 国产精品麻豆果冻传媒在线播放 | 大荫蒂欧美视频另类xxxx | 96久久欧美麻豆网站 | 外国av网 | 91成人免费 | 日本一区二区三区视频在线播放 | 九九热只有这里有精品 | 亚洲视频www| av成人资源| 日韩视频一区二区三区 | 天天干天天上 | 亚洲一片黄 | 91chinesexxx| 国产精品青草综合久久久久99 | 在线视频国产区 | 天天操夜夜想 | 国产剧情在线一区 | 在线免费色 | 99中文字幕在线观看 | 国产精品高清免费在线观看 | 欧美日韩久 | 看国产黄色片 | 日韩高清精品免费观看 | 亚洲天堂香蕉 | 久久这里只有精品首页 | 三级av小说| 日韩一区在线播放 | 国产涩涩在线观看 | 久久久久久97三级 | 探花视频免费观看 | 可以免费看av | 久久久毛片 | 欧美日韩精品在线 | 亚洲精品国产精品乱码不99热 | 亚洲aⅴ乱码精品成人区 | 人人揉人人揉人人揉人人揉97 | 婷婷av综合 | 91网在线看 | 狠狠狠色丁香婷婷综合激情 | 91视频 - v11av | 午夜久久久久久久久久影院 | 激情开心网站 | 九色91福利 | 欧美日韩一级久久久久久免费看 | 成人h在线| 亚洲综合欧美日韩狠狠色 | av丝袜美腿 | 五月婷婷婷婷婷 | 又黄又刺激 | av免费看在线 | 成人在线网站观看 | 久久久久99精品成人片三人毛片 | 男女全黄一级一级高潮免费看 | 久久久婷 | 亚洲日本国产 | a黄色大片| 欧美一级久久久 | av中文字幕在线播放 | 成人黄色小说在线观看 | 国产精品自产拍在线观看蜜 | 激情五月激情综合网 | 欧美孕妇与黑人孕交 | 国产中文欧美日韩在线 | 日韩中文三级 | 麻豆精品视频 | 国产精品久久久久久高潮 | 日韩在线免费 | 日韩理论片 | 国产电影一区二区三区四区 | 亚洲精品乱码久久久久久 | 久久久wwww| 欧美a级在线免费观看 | 国产理论一区二区三区 | 香蕉久久久久久久 | 中文字幕在线观看免费高清完整版 | 欧美综合在线视频 | 国产色小视频 | 射综合网 | 麻豆久久久 | 欧美一级黄大片 | 免费一级黄色 | 久久久久久久久久久国产精品 | 婷婷亚洲五月色综合 | 日本69hd| 亚洲国产片| 婷婷综合久久 | 色婷丁香 | 久精品在线 | 92av视频| 国产高清 不卡 | 亚洲精品美女久久久久网站 | 激情综合色综合久久综合 | 人成电影网 | 亚洲精品一区二区三区高潮 | 国产精品久久久久婷婷二区次 | 日韩午夜精品 | 久久精品中文字幕少妇 | 成人黄大片视频在线观看 | 免费欧美精品 | 欧美aa在线 | 黄色国产成人 | 成人免费在线播放视频 | 久久午夜免费观看 | 婷婷综合导航 | 免费看一级一片 | 国产成人精品在线播放 | 91在线资源 | 美国三级黄色大片 | 国产v在线播放 | 欧美夫妻性生活电影 | 免费看久久久 | 2018亚洲男人天堂 | 日本女人的性生活视频 | 免费网址你懂的 | 国产中文字幕视频在线观看 | 色吊丝在线永久观看最新版本 | 免费视频一区 | 激情图片久久 | 国产手机在线精品 | 久久草草影视免费网 | 国产伦理一区二区三区 | av在线小说 | 天天曰| 色九九影院| 久操视频在线免费看 | 91天堂在线观看 | 国产偷国产偷亚洲清高 | 亚洲专区一二三 | 午夜免费福利片 | 99精品亚洲 | 国产香蕉视频在线观看 | 91在线观看视频网站 | 中文视频在线播放 | 亚洲三级av| 久草视频免费看 | 日本在线观看一区二区三区 | 蜜臀av一区二区 | 日韩精品最新在线观看 | 免费日韩电影 | 成人高清av在线 | 久久久一本精品99久久精品 | 奇米四色影狠狠爱7777 | 精品国产成人av | 亚洲欧洲精品久久 | 天天插天天爱 | 少妇视频一区 | 国产正在播放 | 亚洲韩国一区二区三区 | 在线观看成人福利 | 欧美国产精品一区二区 | 97在线视频观看 | 人人干天天干 | 日韩欧美国产精品 | 日本特黄特色aaa大片免费 | 午夜影院在线观看18 | 一区二区三区四区精品 | 中文国产在线观看 | 夜夜夜草| 免费在线色电影 | 欧美视频xxx | 色999五月色 | 视频在线观看91 | 福利一区在线 | 伊人色综合网 | 中文字幕二区 | 久久久国产视频 | 深夜免费福利 | 色视频 在线| 日韩成人精品在线观看 | 91精品色 | 色网免费观看 | 亚洲精品欧美专区 | 色婷婷av在线 | 亚洲理论在线观看电影 | 国产色就色 | 亚洲精品男人天堂 | 亚洲香蕉视频 | 中文字幕在线日本 | 在线观看视频你懂得 | 超碰在线资源 | 激情文学综合丁香 | 丁五月婷婷 | 6699私人影院 | 免费在线成人av | 国产精品18久久久 | 国产精品久久久久久69 | adc在线观看 | 91福利在线导航 | 国产精品久久久久久久久婷婷 | 成人午夜影视 | a资源在线 | 国产精品嫩草影视久久久 | 特级毛片在线 | 国产原创av片 | 久久精品欧美一区 | 日韩一级片观看 | 国产视频网站在线观看 | 天堂av最新网址 | 欧美韩日精品 | 九色精品免费永久在线 | av理论电影| 久久国产视屏 | 国产精品亚洲精品 | 国产精品久久久一区二区三区网站 | 亚洲国产成人久久综合 | 免费在线91 | 日韩一区正在播放 | 玖操 | 日韩在线小视频 | 国产一二三区av | 丁香视频在线观看 | 五月婷婷激情六月 | 天天操天天谢 | 91九色蝌蚪国产 | 99视频99| 日韩中文字幕网站 | 91麻豆精品国产91久久久无需广告 | 亚洲永久精品在线观看 | 国产字幕在线看 | 日本精品一区二区三区在线观看 | 又大又硬又黄又爽视频在线观看 | 亚洲影视资源 | 久久久久国产精品免费免费搜索 | 91亚洲精品国产 | 色偷偷88888欧美精品久久 | 国产成人免费观看久久久 | 久久天天操 | 狠狠干美女 | 成人在线观看网址 | 色婷婷午夜| 久久久久亚洲精品中文字幕 | 中文字幕av在线电影 | 国产精品一区久久久久 | 91免费网址 | 国产精品九九热 | 99在线免费观看 | 国产亚洲人成网站在线观看 | 日本韩国精品一区二区在线观看 | 国产亚洲精品久久 | 丁香 久久 综合 | 91丨精品丨蝌蚪丨白丝jk | 国产精品久久电影观看 | 日韩黄色影院 | 天天舔天天射天天操 | 日韩亚洲欧美中文字幕 | 91成熟丰满女人少妇 | 欧美日韩在线精品 | 高清av在线免费观看 | 日本中文字幕久久 | 黄色特级一级片 | 国产精品黑丝在线观看 | 国产成人三级在线 | 91资源在线 | 狠狠狠操| 日本婷婷色 | 五月天综合 | 三上悠亚一区二区在线观看 | 黄色三几片 | av免费电影网站 | 亚洲视频一区二区三区在线观看 | 蜜桃久久久 | 天天干.com | 日本久久中文字幕 | 国产成人一区二区在线观看 | 亚洲成成品网站 | 91大神dom调教在线观看 | caobi视频 | 欧美大片aaa| 国产视频一区二区在线观看 | 99国产情侣在线播放 | 精品一区91 | 亚洲成av人电影 | 国产在线不卡 | 日本三级不卡 | 欧美日韩一区二区视频在线观看 | 午夜在线免费观看 | 免费在线观看不卡av | 欧美日产在线观看 | 男女免费av |