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

React是怎樣煉成的,值得學習!

開發 前端
本文主要講述 React 的誕生過程和優化思路。內容整理自 2014 年的 OSCON - React Architecture by vjeux,雖然從今天(2018)來看可能會有點歷史感,但仍然值得學習了解。以史為鑒,從中也可以管窺 Facebook 優秀的工程管理文化。

[[220786]]

本文主要講述 React 的誕生過程和優化思路。

內容整理自 2014 年的 OSCON - React Architecture by vjeux,雖然從今天(2018)來看可能會有點歷史感,但仍然值得學習了解。以史為鑒,從中也可以管窺 Facebook 優秀的工程管理文化。

字符拼接時代 - 2004

時間回到 2004 年,Mark Zuckerberg 當時還在宿舍搗鼓最初版的 Facebook 。

這一年,大家都在用 PHP 的字符串拼接(String Concatenation)功能來開發網站。

 

  1. $str = '<ul>' 
  2. foreach ($talks as $talk) {  
  3.   $str += '<li>' . $talk->name . '</li>' 
  4.  
  5. $str += '</ul>'

這種網站開發方式在當時看來是非常正確的,因為不管是后端開發還是前端開發,甚至根本沒有開發經驗,都可以使用這種方式搭建一個大型網站。

唯一不足的是,這種開發方式容易造成 XSS 注入等安全問題。如果 $talk->name 中包含惡意代碼,而又沒有做任何防護措施的話,那么攻擊者就可以注入任意 JS 代碼。于是就催生了“永遠不要相信用戶的輸入”的安全守則。

最簡單的應對方法是對用戶的任何輸入都進行轉義(Escape)。然而這也帶來了其他麻煩,如果對字符串進行多次轉義,那么反轉義的次數也必須是相同的,否則會無法得到原內容。如果又不小心把 HTML 標簽(Markup)給轉義了,那么 HTML 標簽會直接顯示給用戶,從而導致很差的用戶體驗。

XHP 時代 - 2010

到了 2010 年,為了更加高效的編碼,同時也避免轉義 HTML 標簽的錯誤,Facebook 開發了 XHP 。XHP 是對 PHP 的語法拓展,它允許開發者直接在 PHP 中使用 HTML 標簽,而不再使用字符串。

 

  1. $content = <ul />;  
  2. foreach ($talks as $talk) {  
  3.   $content->appendChild(<li>{$talk->name}</li>);  

這樣的話,所有的 HTML 標簽都使用不同于 PHP 的語法,我們可以輕易的分辨哪些需要轉義哪些不需要轉義。

不久的后來,Facebook 的工程師又發現他們還可以創建自定義標簽,而且通過組合自定義標簽有助于構建大型應用。

而這恰恰是 Semantic Web 和 Web Components 概念的一種實現方式。

 

  1. $content = <talk:list />;  
  2. foreach ($talks as $talk) {  
  3.   $content->appendChild(<talk talk={$talk} />);  

之后,Facebook 在 JS 中嘗試了更多的新技術方式以減小客戶端和服務端之間的延時。比如跨瀏覽器 DOM 庫和數據綁定,但是都不是很理想。

JSX - 2013

等到 2013 年,突然有一天,前端工程師 Jordan Walke 向他的經理提出了一個大膽的想法:把 XHP 的拓展功能遷移到 JS 中。最開始大家都以為他瘋了,因為這與當時大家都看好的 JS 框架格格不入。不過他最終還是執著地說服了經理,允許他用 6 個月的時間來驗證這個想法。這里不得不說 Facebook 良好的工程師管理哲學讓人敬佩,值得借鑒。

    附:Lee Byron 談 Facebook 工程師文化:Why Invest in Tools 

要想把 XHP 的拓展功能遷移到 JS ,首要任務是需要一個拓展來讓 JS 支持 XML 語法,該拓展稱為 JSX 。當時,隨著 Node.js 的興起,Facebook 內部對于轉換 JS 已經有相當多的工程實踐了。所以實現 JSX 簡直輕而易舉,僅僅花費了大概一周的時間。

 

  1. const content = ( 
  2.   <TalkList> 
  3.     { talks.map(talk => <Talk talk={talk} />)} 
  4.   </TalkList> 
  5. ); 

React

自此,開始了 React 的萬里長征,更大的困難還在后頭。其中,最棘手的是如何再現 PHP 中的更新機制。

在 PHP 中,每當有數據改變時,只需要跳到一個由 PHP 全新渲染的新頁面即可。

從開發者的角度來看的話,這種方式開發應用是非常簡單的,因為它不需要擔心變更,且界面上用戶數據改變時所有內容都是同步的。

只要有數據變更,就重新渲染整個頁面。

雖然簡單粗暴,但是這種方式的缺點也尤為突出,那就是它非常慢。

“You need to be right before being good”,意思是說,為了驗證遷移方案的可行性,開發者必須快速實現一個可用版本,暫時不考慮性能問題。

DOM

取自于 PHP 的靈感,在 JS 中實現重新渲染的最簡單辦法是:當任何內容改變時,都重新構建整個 DOM,然后用新 DOM 取代舊 DOM 。

這種方式是可以工作的,但在有些場景下不適用。

比如它會失去當前聚焦的元素和光標,以及文本選擇和頁面滾動位置,這些都是頁面的當前狀態。

換句話來說,DOM 節點是包含狀態的。

既然包含狀態,那么記下舊 DOM 的狀態然后在新 DOM 上還原不就行了么?

但是非常不幸,這種方式不僅實現起來復雜而且也無法覆蓋所有情況。

在 OSX 電腦上滾動頁面時,會伴隨著一定的滾動慣性。但是 JS 并沒有提供相應的 API 來讀取或者寫入滾動慣性。

對包含 iframe 的頁面來說,情況則更復雜。如果它來自其他域,那么瀏覽器安全策略限制根本不會允許我們查看其內部的內容,更不用說還原了。

因此可以看出,DOM 不僅僅有狀態,它還包含隱藏的、無法觸達的狀態。

既然還原狀態行不通,那就換一種方式繞過去。

對于沒有改變的 DOM 節點,讓它保持原樣不動,僅僅創建并替換變更過的 DOM 節點。

這種方式實現了 DOM 節點復用(Reuse)。

至此,只要能夠識別出哪些節點改變了,那么就可以實現對 DOM 的更新。于是問題就轉化為如何比對兩個 DOM 的差異。

Diff

說到對比差異,相信大家馬上就能聯想到版本控制(Version Control)。它的原理很簡單,記錄多個代碼快照,然后使用 diff 算法比對前后兩個快照,從而生成一系列諸如“刪除 5 行”、“新增 3 行”、“替換單詞”等的改動;通過把這一系列的改動應用到先前的代碼快照就可以得到之后的代碼快照。

而這正是 React 所需要的,只不過它的處理對象是 DOM 而不是文本文件。

難怪有人說:“I tend to think of React as Version Control for the DOM” 。

DOM 是樹形結構,所以 diff 算法必須是針對樹形結構的。目前已知的完整樹形結構 diff 算法復雜度為 O(n^3) 。

假如頁面中有 10,000 個 DOM 節點,這個數字看起來很龐大,但其實并不是不可想象。為了計算該復雜度的數量級大小,我們還假設在一個 CPU 周期我們可以完成單次對比操作(雖然不可能完成),且 CPU 主頻為 1 GHz 。這種情況下,diff 要花費的時間如下:

整整有 17 分鐘之長,簡直無法想象!

雖然說驗證階段暫不考慮性能問題,但是我們還是可以簡單了解下該算法是如何實現的。

    附:完整的 Tree diff 實現算法

  1. 新樹上的每個節點與舊樹上的每個節點對比
  2. 如果父節點相同,繼續循環對比子樹

在上圖的樹中,依據最小操作原則,可以找到三個嵌套的循環對比。

但如果認真思考下,其實在 Web 應用中,很少有移動一個元素到另一個地方的場景。一個例子可能的是拖拽(Drag)并放置(Drop)元素到另一個地方,但它并不常見。

唯一的常用場景是在子元素之間移動元素,例如在列表中新增、刪除和移動元素。既然如此,那可以僅僅對比同層級的節點。

如上圖所示,僅對相同顏色的節點做 diff ,這樣能把時間復雜度降到了 O(n^2) 。

key

針對同級元素的比較,又引入了另一個問題。

同層級元素名稱不同時,可以直接識別為不匹配;相同時,卻沒那么簡單了。

假如在某個節點下,上一次渲染了三個 <input />,然后下一次渲染變成了兩個。此時 diff 的結果會是什么呢?

最直觀的結果是前面兩個保持不變,刪除第三個。

當然,也可以刪除第一個同時保持最后兩個。

如果不嫌麻煩,還可以把舊的三個都刪除,然后新增兩個新元素。

這說明,對于相同標簽名稱的節點,我們沒有足夠信息來對比前后差異。

如果再加上元素的屬性呢?比如 value ,如果前后兩次標簽名稱和 value 屬性都相同,那么就認為元素匹配中,無須改動。但現實是這行不通,因為用戶輸入時值總是在變,會導致元素一直被替換,導致失去焦點;;更糟糕的是,并不是所有 HTML 元素都有這個屬性。

那使用所有元素都有的 id 屬性呢?這是可以的,如上圖,我們可以容易的識別出前后 DOM 的差異。考慮表單情況,表單模型的輸入通常跟 id 關聯,但如果使用 AJAX 來提交表單的話,我們通常不會給 input 設置 id 屬性。因此,更好的辦法是引入一個新的屬性名稱,專門用來輔助 diff 算法。這個屬性最終確定為 key 。這也是為什么在 React 中使用列表時會要求給子元素設置 key 屬性的原因。

結合 key ,再加上哈希表,diff 算法最終實現了 O(n) 的最優復雜度。

至此,可以看到從 XHP 遷移到 JS 的方案可行的。接下來就可以針對各個環節進行逐步優化。

    附:詳細的 diff 理解:不可思議的 react diff

持續優化

Virtual DOM

前面說到,React 其實實現了對 DOM 節點的版本控制。

做過 JS 應用優化的人可能都知道,DOM 是復雜的,對它的操作(尤其是查詢和創建)是非常慢非常耗費資源的。看下面的例子,僅創建一個空白的 div,其實例屬性就達到 231 個。

 

  1. // Chrome v63 
  2. const div = document.createElement('div'); 
  3. let m = 0; 
  4. for (let k in div) { 
  5.   m++; 
  6. console.log(m); // 231 

之所以有這么多屬性,是因為 DOM 節點被用于瀏覽器渲染管道的很多過程中。

瀏覽器首先根據 CSS 規則查找匹配的節點,這個過程會緩存很多元信息,例如它維護著一個對應 DOM 節點的 id 映射表。

然后,根據樣式計算節點布局,這里又會緩存位置和屏幕定位信息,以及其他很多的元信息,瀏覽器會盡量避免重新計算布局,所以這些數據都會被緩存。

可以看出,整個渲染過程會耗費大量的內存和 CPU 資源。

現在回過頭來想想 React ,其實它只在 diff 算法中用到了 DOM 節點,而且只用到了標簽名稱和部分屬性。

如果用更輕量級的 JS 對象來代替復雜的 DOM 節點,然后把對 DOM 的 diff 操作轉移到 JS 對象,就可以避免大量對 DOM 的查詢操作。這種方式稱為 Virtual DOM 。

其過程如下:

  1. 維護一個使用 JS 對象表示的 Virtual DOM,與真實 DOM 一一對應
  2. 對前后兩個 Virtual DOM 做 diff ,生成變更(Mutation)
  3. 把變更應用于真實 DOM,生成最新的真實 DOM

可以看出,因為要把變更應用到真實 DOM 上,所以還是避免不了要直接操作 DOM ,但是 React 的 diff 算法會把 DOM 改動次數降到最低。

至此,React 的兩大優化:diff 算法和 Virtual DOM ,均已完成。再加上 XHP 時代嘗試的數據綁定,已經算是一個可用版本了。

這個時候 Facebook 做了個重大的決定,那就是把 React 開源!

React 的開源可謂是一石激起千層浪,社區開發者都被這種全新的 Web 開發方式所吸引,React 因此迅速占領了 JS 開源庫的榜首。

很多大公司也把 React 應用到生產環境,同時也有大批社區開發者為 React 貢獻了代碼。

接下來要說的兩大優化就是來自于開源社區。

批處理(Batching)

著名瀏覽器廠商 Opera 把重排和重繪(Reflow and Repaint)列為影響頁面性能的三大原因之一。

我們說 DOM 是很慢的,除了前面說到的它的復雜和龐大,還有另一個原因就是重排和重繪。

當 DOM 被修改后,瀏覽器必須更新元素的位置和真實像素;

當嘗試從 DOM 讀取屬性時,為了保證讀取的值是正確的,瀏覽器也會觸發重排和重繪。

因此,反復的“讀取、修改、讀取、修改...”操作,將會觸發大量的重排和重繪。

另外,由于瀏覽器本身對 DOM 操作進行了優化,比如把兩次很近的“修改”操作合并成一個“修改”操作。

所以如果把“讀取、修改、讀取、修改...”重新排列為“讀取、讀取...”和“修改、修改...”,會有助于減小重排和重繪的次數。但是這種刻意的、手動的級聯寫法是不安全的。

與此同時,常規的 JS 寫法又很容易觸發重排和重繪。

在減小重排和重繪的道路上,React 陷入了尷尬的處境。

最終,社區貢獻者 Ben Alpert 使用批處理的方式拯救了這個尷尬的處境。

在 React 中,開發者通過調用組件的 setState 方法告訴 React 當前組件要變更了。

Ben Alpert 的做法是,調用 setState 時不立即把變更同步到 Virtual DOM,而是僅僅把對應元素打上“待更新”的標記。如果組件內調用多次 setState ,那么都會進行相同的打標操作。

等到初始化事件被完全廣播開以后,就開始進行從頂部到底部的重新渲染(Re-Render)過程。這就確保了 React 只對元素進行了一次渲染。

這里要注意兩點:

  1. 此處的重新渲染是指把 setState 變更同步到 Virtual DOM ;在這之后才進行 diff 操作生成真實的 DOM 變更。
  2. 與前文提到的“重新渲染整個 DOM ”不同的是,真實的重新渲染僅渲染被標記的元素及其子元素,也就是說上圖中僅藍色圓圈代表的元素會被重新渲染

這也提醒開發者,應該讓擁有狀態的組件盡量靠近葉子節點,這樣可以縮小重新渲染的范圍。

裁剪(Pruning)

隨著應用越來越大,React 管理的組件狀態也會越來越多,這就意味著重新渲染的范圍也會越來越大。

認真觀察上面批處理的過程可以發現,該 Virtual DOM 右下角的三個元素其實是沒有變更的,但是因為其父節點的變更也導致了它們的重新渲染,多做了無用操作。

對于這種情況,React 本身已經考慮到了,為此它提供了 bool shouldComponentUpdate(nextProps, nextState) 接口。開發者可以手動實現該接口來對比前后狀態和屬性,以判斷是否需要重新渲染。這樣的話,重新渲染就變成如下圖所示過程。

當時,React 雖然提供了 shouldComponentUpdate 接口,但是并沒有提供一個默認的實現方案(總是渲染),開發者必須自己手動實現才能達到預期效果。

其原因是,在 JS 中,我們通常使用對象來保存狀態,修改狀態時是直接修改該狀態對象的。也就是說,修改前后的兩個不同狀態指向了同一個對象,所以當直接比較兩個對象是否變更時,它們是相同的,即使狀態已經改變。

對此,David Nolen 提出了基于不可變數據結構(Immutable Data Structure)的解決方案。

該方案的靈感來自于 ClojureScript ,在 ClojureScript 中,大部分的值都是不可變的。換句話說就是,當需要更新一個值時,程序不是去修改原來的值,而是基于原來的值創建一個新值,然后使用新值進行賦值。

David 使用 ClojureScript 寫了一個針對 React 的不可變數據結構方案:Om ,為 shouldComponentUpdate 提供了默認實現。

不過,由于不可變數據結構并未被 Web 工程師廣為接受,所以當時并未把這項功能合并進 React 。

遺憾的是,截止到目前,shouldComponentUpdate 也仍然未提供默認實現。

但是 David 卻為廣大開發者開啟了一個很好的研究方向。

如果真想利用不可變數據結構來提高 React 性能,可以參考與 React 師出同門的 Facebook Immutable.js,它是 React 好搭檔!

結束語

React 的優化仍在繼續,比如 React 16 中新引入 Fiber,它是對核心算法的一次重構,即重新設計了檢測變更的方法和時機,允許渲染過程可以分段完成,而不必一次性完成。

受篇幅限制,本文不會深入介紹 Fiber ,有興趣的可以參考 React Fiber是什么 。

最后,感謝 Facebook 給開源社區帶來了如此優秀的項目! 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2010-03-24 15:40:39

網管運維管理摩卡軟件

2014-06-20 10:34:42

開源

2015-09-06 09:09:13

2015-11-10 09:09:23

代碼程序員成長

2013-08-19 16:17:48

CIO

2024-03-28 08:13:51

GPTsOpenAI人工智能

2011-11-25 09:48:04

天線無線

2012-05-28 16:30:27

Web

2021-02-08 23:52:17

CISO安全主管首席信息安全官

2010-12-28 10:40:50

admin

2012-08-29 09:58:34

JavaScriptJavaScript模

2015-08-27 15:06:42

全能渠道華為

2009-02-23 13:05:32

程序員學習方法

2012-12-03 10:22:24

程序員

2021-06-29 08:45:55

邏輯變量法函數

2017-07-14 16:24:48

TensorFlow框架開發

2011-06-30 16:59:06

程序員

2016-01-06 14:43:21

2011-10-26 07:18:25

2015-08-13 10:38:30

點贊
收藏

51CTO技術棧公眾號

日本成人在线一区| 免费观看久久av| 亚洲.国产.中文慕字在线| 最新不卡av在线| 欧美一区二区.| 亚洲精品国产精品乱码在线观看| 日本免费精品| 色狠狠av一区二区三区| 少妇久久久久久被弄到高潮| 久蕉在线视频| 成人性视频网站| 国产精品视频在线观看| 日本三级视频在线| 93在线视频精品免费观看| 亚洲精品一区二区三区香蕉| 五月婷婷之综合激情| caoporn视频在线观看| 中文字幕在线观看不卡视频| 久久婷婷人人澡人人喊人人爽| 91成人一区二区三区| 亚洲欧美网站| 欧美激情精品久久久久久免费印度 | 亚洲av无码一区二区三区网址| 成人日韩av| 欧美天堂在线观看| 丁香色欲久久久久久综合网| 欧美jizzhd欧美| 久久亚洲捆绑美女| 国产伦精品一区二区三区高清版| 91丨porny丨在线中文 | 欧美福利专区| 中文字幕欧美精品日韩中文字幕| 亚洲欧美色图视频| 白嫩白嫩国产精品| 日韩免费高清视频| 色网站在线视频| 小说区图片区亚洲| 欧美中文字幕一区二区三区亚洲| 99999精品视频| 日韩理论视频| 精品国产鲁一鲁一区二区张丽| 91嫩草国产丨精品入口麻豆| av在线播放天堂| 少妇高潮久久久| 国产91在线观看丝袜| 91免费版网站入口| 91无套直看片红桃| 韩国三级在线一区| 91老司机精品视频| 国产又粗又大又爽视频| 九九视频精品免费| 成人亚洲欧美一区二区三区| 国产美女裸体无遮挡免费视频| 久久精品国产精品青草| 国产在线日韩在线| 国产精品亚洲欧美在线播放| 精品一区二区三区免费毛片爱| 国产一区二区丝袜| av中文字幕免费在线观看| 国产精品正在播放| www.久久久| 粉嫩小泬无遮挡久久久久久| av男人天堂一区| 麻豆av一区| www在线免费观看| 国产精品久久久久久久岛一牛影视| 亚洲欧洲日夜超级视频| 超碰人人在线| 亚洲国产日日夜夜| 欧美 国产 日本| 欧美日韩女优| 欧美一卡二卡在线| 91传媒理伦片在线观看| 国产乱码精品一区二区亚洲| 91网址在线观看精品| 91麻豆国产视频| 国产专区综合网| 5566中文字幕一区二区| 亚洲成人中文字幕在线| av电影一区二区| 深夜福利成人| 在线网址91| 欧洲午夜精品| 色国产精品一区在线观看| 中文字幕成人在线视频| 午夜久久av| 日韩精品中文字幕视频在线| www.99热| 欧美三级在线| 国产福利精品在线| 国产黄色av网站| 久久毛片高清国产| 中国一区二区三区| 国产自产自拍视频在线观看| 欧美日韩国产一区二区三区地区| 国产a级片视频| 国产一区二区三区日韩精品 | 国产九九精品| 成人黄色免费看| 久久大片网站| 丰满熟妇乱又伦| 欧美激情综合网| 久久久久久免费看| 日韩福利在线观看| 精品亚洲一区二区三区四区五区| 网站永久看片免费| 国产精品外国| 亚洲自拍小视频| xxxxx日韩| 欧美视频中文字幕在线| 黄色a级三级三级三级| 一区二区三区四区在线看 | 色婷婷在线播放| 一道本成人在线| gogo亚洲国模私拍人体| 日本黄色精品| 人体精品一二三区| 亚洲h视频在线观看| 国产精品天天看| 精品一区二区中文字幕| 高清欧美性猛交xxxx黑人猛| 日韩视频一区在线| 国产免费一级视频| 97成人超碰视| a天堂资源在线观看| 青草综合视频| 在线成人激情视频| 99re这里只有精品在线| 99久久99久久精品国产片果冻| 欧美少妇一区二区三区| 欧洲午夜精品| 色噜噜狠狠色综合网图区| 91免费综合在线| 国产成人精品无码高潮| 国产精品欧美精品| 玩弄japan白嫩少妇hd| 亚洲品质自拍| 57pao精品| 色屁屁草草影院ccyycom| 亚洲一区二区在线视频| 久久综合桃花网| 久久精品欧美一区| 成人午夜在线影院| 菠萝菠萝蜜在线观看| 欧美二区乱c少妇| 91禁男男在线观看| 美国毛片一区二区| 中文字幕久久一区| 视频91a欧美| 久久视频中文字幕| 国产av一区二区三区| 一区二区在线免费观看| 四川一级毛毛片| 黑丝一区二区| 精品国产乱码久久久久软件 | 日韩一区二区在线| 国产精品欧美在线| 黄网站在线播放| 欧美一级在线视频| 国产精品第一页在线观看| 成人av影院在线| 欧美国产激情视频| 精品国产乱码久久久久久果冻传媒| 国产v综合ⅴ日韩v欧美大片| 第一福利在线| 91麻豆精品国产91久久久久| 亚洲综合网在线| 国产91精品在线观看| 亚洲熟妇av日韩熟妇在线 | 亚洲欧美日韩在线综合| 精品国产亚洲一区二区三区大结局| 欧美成人手机在线| 婷婷色在线观看| 91精品福利视频| 精品国产视频一区二区三区| 成人激情校园春色| 女人另类性混交zo| 我不卡影院28| 精品欧美一区二区久久久伦 | 国产精品久久久久久免费观看| 激情视频在线播放| 97久久超碰| 欧美肥老妇视频| 男女视频在线观看| 91精品在线麻豆| 久久久久久久黄色片| 中文字幕免费一区| 亚洲国产精品狼友在线观看| 久久精品电影| 日韩不卡视频一区二区| 网曝91综合精品门事件在线| 国产日本欧美一区二区三区| 黄色18在线观看| 日韩中文第一页| 天天爱天天干天天操| 欧美日韩亚洲国产综合| 国产在线观看成人| 中文在线资源观看网站视频免费不卡| 97中文字幕在线观看| 美腿丝袜在线亚洲一区| 免费毛片网站在线观看| 久久精品亚洲欧美日韩精品中文字幕| 久草一区二区| 日韩国产在线不卡视频| 国产精品第二页| 欧美videossex| 日韩在线欧美在线国产在线| 婷婷伊人综合中文字幕| 欧美一区二区高清| 无码人妻精品一区二区三区不卡 | 日韩av片在线播放| 亚洲天天做日日做天天谢日日欢 | 免费a在线观看播放| 激情丁香综合五月| 91看片就是不一样| 亚洲经典在线| 欧美美女黄色网| 久久亚洲精品中文字幕蜜潮电影| 久久精品五月婷婷| 懂色av一区二区| 91在线观看免费网站| 国产日韩另类视频一区| 97香蕉久久夜色精品国产| 伊人电影在线观看| 久久五月天综合| 午夜在线小视频| 国产亚洲精品一区二区| 视频在线不卡| 亚洲精品成a人在线观看| 亚洲成熟女性毛茸茸| 欧美一区二区三区日韩| 一级黄色a视频| 国语产色综合| 国产精品网站大全| 亚洲天堂一区二区| 国产成人精品av| 美女写真久久影院| 国产成人精品一区二区| 日日av拍夜夜添久久免费| 欧美一级高清免费| 中文字幕一区久| 日本高清+成人网在线观看| 黄色视屏在线免费观看| 69久久夜色精品国产69乱青草| av岛国在线| 97香蕉超级碰碰久久免费的优势| a天堂资源在线| 91av在线国产| 成人免费网站视频| 日本精品视频网站| 日韩精品第一| 国产自产女人91一区在线观看| 国产精品99| 91九色单男在线观看| 久久免费精品| 国产精品视频一区二区三区经| 粉嫩久久久久久久极品| 国产三区精品| 国产一区二区三区天码| 亚洲一卡二卡三卡四卡无卡网站在线看| 欧美三级三级| 日本不卡一区二区三区四区| 欧美在线影院| www黄色日本| 日本怡春院一区二区| 91 在线视频观看| 国产丶欧美丶日本不卡视频| 国产原创剧情av| 久久精品一区二区| 天堂а√在线中文在线鲁大师| 亚洲人成在线观看一区二区| 国产 日韩 欧美 成人| 色婷婷久久99综合精品jk白丝| 在线视频欧美亚洲| 精品人在线二区三区| 日韩美女一级视频| 北条麻妃在线一区二区| 成年人国产在线观看| 日本精品久久久久久久| 国产999精品在线观看| 好吊色欧美一区二区三区四区 | 一本一道久久a久久精品综合| 亚洲欧美日韩高清在线| 日本网站免费在线观看| 奇米888四色在线精品| 亚洲v在线观看| 欧美国产1区2区| 精品无码久久久久久久| 色素色在线综合| 性猛交富婆╳xxx乱大交天津| 亚洲女人被黑人巨大进入al| 成人在线app| 日本中文字幕成人| 日韩在线成人| 亚洲美女少妇撒尿| 免费一级片视频| 欧美性受极品xxxx喷水| 国产自产一区二区| 国产一区二区三区在线观看网站 | 色狠狠av一区二区三区| www.com在线观看| 最近更新的2019中文字幕| 6699嫩草久久久精品影院| 国产精品久久久久久久久久久不卡| 99精品国产高清一区二区麻豆| 日韩在线三区| 亚洲视频大全| 亚洲欧美日韩中文字幕在线观看| 久久久久久久一区| 国产一级视频在线观看| 欧美一区中文字幕| 国产在线播放av| 97视频在线观看免费| 亚洲精品一区国产| 色呦呦网站入口| 日本视频在线一区| 国产白嫩美女无套久久| 亚洲一二三级电影| 国产欧美久久久| www.xxxx欧美| av亚洲一区二区三区| 精品国产一区二区三| 精品成人在线| 人妻精品久久久久中文字幕69| 国产精品久久久久久亚洲毛片| 中文字幕在线播| 精品亚洲一区二区| 亚洲电影观看| 国产一区二区三区免费不卡| 国产一在线精品一区在线观看| 超碰中文字幕在线观看| 中文字幕在线观看不卡| 中文字幕一二区| 在线丨暗呦小u女国产精品| 日韩新的三级电影| 日韩精品不卡| 日韩福利视频网| 午夜影院黄色片| 欧美色男人天堂| 欧美日韩xx| 成人久久久久久久| 中国精品18videos性欧美| 久久久久久久久久毛片| 亚洲三级在线免费观看| 国产三级视频在线播放| 久久人人爽亚洲精品天堂| 国产精品视频一区二区三区综合| 黄色免费高清视频| 国产一区二区三区国产| 九九精品在线观看视频| 亚洲第一中文字幕| 成人动漫一区| 色综合电影网| 久草热8精品视频在线观看| 神马久久精品综合| 日韩欧美国产成人一区二区| 国产蜜臀一区二区打屁股调教| 韩国成人av| 久久精品道一区二区三区| 少妇视频在线播放| 91精品国产福利| 丁香花在线电影小说观看| 蜜桃麻豆www久久国产精品| 日本午夜一区二区| 波多野结衣在线网址| 精品国产乱码久久久久久牛牛| 色老头在线一区二区三区| 日韩av电影免费播放| 激情综合色综合久久综合| 黄网站免费在线| 亚洲欧美国产另类| 日韩成人在线电影| 欧美在线观看视频免费| 91视频在线观看免费| 在线观看视频中文字幕| 欧美成人免费一级人片100| 日韩精品a在线观看91| 99视频在线视频| 一区二区三区免费网站| 欧美一区二区少妇| 91精品在线观| 午夜影院日韩| jizz亚洲少妇| 日韩高清a**址| 精品美女一区| 少妇人妻在线视频| 中文字幕国产一区二区| 精品久久久免费视频| 国产成人精品综合久久久| 欧美黄色一区| 日韩精品无码一区二区三区久久久| 欧美裸体一区二区三区| 678在线观看视频| www亚洲国产| 久久久噜噜噜久噜久久综合| 99在线精品视频免费观看软件| 日本一区二区不卡| 午夜精品免费| 992在线观看| 日韩精品视频中文在线观看|