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

性能優化竟白屏,難道真是我的鍋?

開發 前端
隨著項目日漸“強壯”,優化首屏加載渲染速度迫在眉睫,其中就采用了 React 框架提供的 Reat.lazy() 按需加載的方式,測試過程中,在我們的埋點監控平臺上,發現了很多網絡請求錯誤的日志,大部分來自分包資源下載失敗!難道我的優化變成負優化了?

[[408650]]

本文轉載自微信公眾號「DYBOY」,作者DYBOY。轉載本文請聯系DYBOY公眾號。

隨著項目日漸“強壯”,優化首屏加載渲染速度迫在眉睫,其中就采用了 React 框架提供的 Reat.lazy() 按需加載的方式,測試過程中,在我們的埋點監控平臺上,發現了很多網絡請求錯誤的日志,大部分來自分包資源下載失敗!難道我的優化變成負優化了?

通過我們的統計平臺量化數據可知,用戶網絡加載失敗的概率還是比較大,實驗發現,沒法兒使用 try{}catch{} 捕獲組件渲染錯誤,查詢官方文檔,有一個 Error Boundaries 的組件引入眼簾,提供了解決方法,那我們拿到了 demo 應該怎么完善并應用到我們的項目中,以及如何解決按需加載組件失敗的場景。

背景

某天我在開發了某個功能組件時,發現這個組件引用了一個非常大的三方庫,大概100kb,這么大,當然得使用按需加載啦,當我理所當然地覺得這一手“按需加載”的優化很穩,就交給測試同學測試了。

沒過多久測試同學反饋,你這個功能咋老白屏?—— 怎么可能?我的代碼不可能有BUG!

來到“事故現場”,稍加思索,打開瀏覽器控制臺,發現按需加載的遠程文件下載失敗了。

emmm~,繼續狡辯,這肯定是公司基建不行啊,網絡這么不穩,這鍋我不背!雖然極力狡辯,可是測試同學就不相信,就認定了是我的問題...

凡事講證據,冷靜下來想一想,萬一真的是我的問題,豈不是很尷尬?

為了挽回局面,于是強裝鎮定說到:“這個問題是網絡波動導致,雖然咱們的基建環境不太好,但是為了盡可能提升用戶體驗,我這嘗試下看看如何優化,可通過增加錯誤監控重試機制,增強用戶體驗,追求極致!”,趕緊溜回去看看咋解決吧...

一、Error Boundaries

React官方對于“Error Boundaries”的介紹:https://reactjs.org/docs/error-boundaries.html

A JavaScript error in a part of the UI shouldn’t break the whole app. To solve this problem for React users, React 16 introduces a new concept of an “error boundary”.

簡單翻譯,在 UI 渲染中發生的錯誤不應該阻塞整個應用的運行,為此,React 16 中提供了一種新的概念“錯誤邊界”。

也就是說,我們可以用“錯誤邊界”來優雅地處理 React 中的 UI 渲染錯誤問題。

React 中的懶加載使用Suspense包裹,其下的子節點發生了渲染錯誤,也就是下載組件文件失敗,并不會拋出異常,也沒法兒捕獲錯誤,那么用 ErrorBoundary 就正好可以決定再子節點發生渲染錯誤(常見于白屏)時候的處理方式。

注意:Error boundaries 不能捕獲如下類型的錯誤:

  • 事件處理(了解更多)
  • 異步代碼 (例如 setTimeout 或 requestAnimationFrame 回調)
  • 服務端渲染
  • 來自ErrorBoundary組件本身的錯誤 (而不是來自它包裹子節點發生的錯誤)

二、借鑒

老夫作為“CV工程師”,自然是信手拈來:

  1. class ErrorBoundary extends React.Component { 
  2.   constructor(props) { 
  3.     super(props); 
  4.     this.state = { hasError: false }; 
  5.   } 
  6.  
  7.   static getDerivedStateFromError(error) { 
  8.     // Update state so the next render will show the fallback UI. 
  9.     return { hasError: true }; 
  10.   } 
  11.  
  12.   componentDidCatch(error, errorInfo) { 
  13.     // You can also log the error to an error reporting service 
  14.     logErrorToMyService(error, errorInfo); 
  15.   } 
  16.  
  17.   render() { 
  18.     if (this.state.hasError) { 
  19.       // You can render any custom fallback UI 
  20.       return <h1>Something went wrong.</h1>; 
  21.     } 
  22.  
  23.     return this.props.children;  
  24.   } 

使用方法:

  1. <ErrorBoundary> 
  2.   <MyWidget /> 
  3. </ErrorBoundary> 

 

  • static getDerivedStateFromError(error):在 render phase 階段,子節點發生UI渲染拋出錯誤時候執行,return 的 {hasError: true} 用于更新 state 中的值,不允許包含副作用的代碼,觸發重新渲染(渲染fallback UI)內容。
  • componentDidCatch(error, errorInfo):在commit phase 階段,捕獲子節點中發生的錯誤,因此在該方法中可以執行有副作用的代碼,例如用于打印上報錯誤日志。

官方案例在線演示地址:https://codepen.io/gaearon/pen/wqvxGa?editors=0010

與此同時官方的建議:

In the event of an error, you can render a fallback UI with componentDidCatch() by calling setState, but this will be deprecated in a future release. Use static getDerivedStateFromError() to handle fallback rendering instead.

推薦大家在 getDerivedStateFromError() 中處理 fallback UI,而不是在 componentDidCatch() 方法中,componentDidCatch() 在未來的 React 版本中可能會被廢棄,當然只是推薦,僅供參考。

三、修飾

官方的 demo 組件如果要嵌入業務代碼中,還是有一些簡陋,為了更好地適應業務代碼以及更加通用,我們一步步來改造。

3.1 支持自定義fallback以及error callback

目標:滿足些場景下,開發者需要自行設置 fallback 的UI,以及自定義錯誤處理回調

實現也非常簡單,基于 TypeScript,再加上一些類型聲明,一個支持自定義fallback 和錯誤回調的 ErrorBoundary 就OK了!

  1. type IProps = { 
  2.   fallback?: ReactNode | null
  3.   onError?: () => void; 
  4.   children: ReactNode; 
  5. }; 
  6.  
  7. type IState = { 
  8.   isShowErrorComponent: boolean; 
  9. }; 
  10.  
  11. class LegoErrorBoundary extends React.Component<IProps, IState> { 
  12.   static getDerivedStateFromError(error: Error) { 
  13.     return { isShowErrorComponent: true }; 
  14.   } 
  15.  
  16.   constructor(props: IProps | Readonly<IProps>) { 
  17.     super(props); 
  18.     this.state = { isShowErrorComponent: false }; 
  19.   } 
  20.  
  21.   componentDidCatch(error: Error) { 
  22.     this.props.onError?.(); 
  23.   } 
  24.  
  25.   render() { 
  26.     const { fallback, children } = this.props; 
  27.     if (this.state.isShowErrorComponent) { 
  28.       if (fallback) { 
  29.         return fallback; 
  30.       } 
  31.       return <>加載失敗,請刷新重試!</>; 
  32.     } 
  33.     return children; 
  34.   } 
  35.  
  36. export default LegoErrorBoundary; 

3.2 支持錯誤手動重試

我們的按需加載組件就像局部組件更新一樣,當組件按需加載的渲染失敗時候,理論上我們應該給用戶提供手動/自動重試機制

手動重試機制,簡單的做法就是,在 fallback UI 中設置重試按鈕

  1.   static getDerivedStateFromError(error: Error) { 
  2.     return { isShowErrorComponent: true }; 
  3.   } 
  4.  
  5.   constructor(props) { 
  6.     super(props); 
  7.     this.state = { isShowErrorComponent: false }; 
  8. +   this.handleRetryClick = this.handleRetryClick.bind(this); 
  9.   } 
  10.      
  11. + handleRetryClick() { 
  12. +  this.setState({ 
  13. +    isShowErrorComponent: false
  14. +  }); 
  15. + } 
  16.  
  17.  render() { 
  18.   const { fallback, children } = this.props; 
  19.   if (this.state.isShowErrorComponent) { 
  20.     if (fallback) { 
  21.       return fallback; 
  22.     } 
  23. +    return ( 
  24. +       <div> 
  25. +        {/* CSS重置下按鈕樣式 */} 
  26. +        <button className="error-retry-btn" onClick={this.handleRetryClick}> 
  27. +          渲染錯誤,請點擊重試! 
  28. +        </button> 
  29. +      </div> 
  30. +    ); 
  31.    } 
  32.    return children; 
  33.  } 

寫一個普通的Counter(計數器)組件:

  1. import React, { useState } from 'react'
  2.  
  3. const Counter = (props) => { 
  4.     const [count, setCount] = useState(0); 
  5.  
  6.     const handleCounterClick = () => { 
  7.         setCount(count+1); 
  8.     } 
  9.  
  10.     const thr = () => { 
  11.         throw new Error('render error'
  12.     } 
  13.  
  14.     return ( 
  15.         <div> 
  16.             {count === 3 ?  thr() : ''
  17.             計數器:{count
  18.             <br/> 
  19.             <button onClick={handleCounterClick}>點擊+1</button> 
  20.         </div> 
  21.     ) 
  22.  
  23. export default Counter; 

我們使用這個 LegoErrorBoundary 組件包裹 Counter 計數器組件,Counter 組件中在第三次點擊時候拋出一個異常,來看看 ErrorBoundary 的捕獲處理情況!

表現效果:

如果咱不處理這個錯誤,就會導致“白屏”,也不利于研發同學排查問題,特別是涉及到一些異步渲染的問題。

3.3 支持發生錯誤自動重試渲染有限次數

手動重試,會增加用戶的一個操作,這會增加用戶的操作成本,為了更加便捷用戶使用軟件,提升用戶體驗,來瞅瞅采用自動重試有限次數的機制應該如何實現。

實現思路:

重試次數統計變量:retryCount,記錄重試渲染次數,超過次數則使用兜底渲染“錯誤提示”UI。

改造如下:

  1. type IState = { 
  2.   isShowErrorComponent: boolean; 
  3. + retryCount: number; 
  4. }; 
  5.  
  6. class LegoErrorBoundary extends React.Component<IProps, IState> { 
  7. -  static getDerivedStateFromError(error: Error) { 
  8. -    return { isShowErrorComponent: true }; 
  9. -  } 
  10.    
  11.   constructor(props: IProps | Readonly<IProps>) { 
  12.     super(props); 
  13. +   this.state = { isShowErrorComponent: false, retryCount: 0 }; 
  14. +  this.handleErrorRetryClick = this.handleErrorRetryClick.bind(this); 
  15.   } 
  16.  
  17.   componentDidCatch(error: Error) { 
  18. +  if (this.state.retryCount > 2) { 
  19. +      this.setState({ 
  20. +        isShowErrorComponent: true
  21. +      }) 
  22. +    } else { 
  23. +      this.setState({ 
  24. +        retryCount: this.state.retryCount + 1, 
  25. +      }); 
  26. +    } 
  27.   } 
  28.  
  29.   render() { 
  30.     const { fallback, children } = this.props; 
  31.     if (this.state.isShowErrorComponent) { 
  32.       if (fallback) { 
  33.         return fallback; 
  34.       } 
  35. +      return <>重試3次后,展示兜底錯誤提示!</>; 
  36.     } 
  37.     return children; 
  38.   } 
  39.  
  40. export default LegoErrorBoundary; 

來看看效果:

自動重試3次

改改Counter組件的代碼,看看能否處理好異步錯誤的問題:

  1. import React, { useEffect, useState } from 'react'
  2.  
  3. const Counter = (props) => { 
  4.   const [count, setCount] = useState(0); 
  5.  
  6.   const handleCounterClick = () => { 
  7.     setCount(count + 1); 
  8.   } 
  9.  
  10.   const thr = () => { 
  11.     throw new Error('render error'
  12.   } 
  13.  
  14.   useEffect(() => { 
  15.     setTimeout(() => { 
  16.       setCount(3) 
  17.     }, 1000); 
  18.   }, []); 
  19.  
  20.   return ( 
  21.     <div> 
  22.       { count === 3 ? thr() : '' } 
  23.       計數器:{ count } 
  24.       <br /> 
  25.       <button onClick={ handleCounterClick }>點擊+1</button> 
  26.     </div> 
  27.   ) 
  28.  
  29. export default Counter; 

表現:

處理異步發生的錯誤

也是OK的!這說明,屬于業務邏輯的代碼比如:網絡數據請求、異步執行導致渲染出錯的情況,“錯誤邊界”組件都是可以攔截并處理。

當前結論:使用 Errorboundary 組件包裹,能夠 handle 住子組件發生的渲染 error。

四、異步加載組件網絡錯誤

4.1 嘗試處理

把 App.js 中的 Counter 組件引用改為按需加載,然后在瀏覽器中模擬分包的組件下載失敗情況,看看是否能夠攔住!

  1. const LazyCounter = React.lazy(() => import('./components/counter/index')); 
  2.  
  3. function App() { 
  4.   return ( 
  5.     <div className="App"
  6.       <header className="App-header"
  7.         <img src={ logo } className="App-logo" alt="logo" /> 
  8.         <ErrorBoundary> 
  9.           <LazyCounter></LazyCounter> 
  10.         </ErrorBoundary> 
  11.       </header> 
  12.     </div> 
  13.   ); 

結果白屏了!也可以看到 ErrorBoundary 組件中打印了捕獲到的錯誤信息:

  1. ChunkLoadError: Loading chunk 3 failed. 
  2. (error: http://localhost:5000/static/js/3.18a27ea8.chunk.js) 
  3.     at Function.a.e ((index):1) 
  4.     at App.js:7 
  5.     at T (react.production.min.js:18) 
  6.     at Hu (react-dom.production.min.js:269) 
  7.     at Pi (react-dom.production.min.js:250) 
  8.     at xi (react-dom.production.min.js:250) 
  9.     at _i (react-dom.production.min.js:250) 
  10.     at vi (react-dom.production.min.js:243) 
  11.     at fi (react-dom.production.min.js:237) 
  12.     at Gi (react-dom.production.min.js:285) 

攔截到了,但是沒有觸發3次重試,componentDidCatch 中的 console.log('發生錯誤!', error); 只打印了一次錯誤日志,就掛了,看到大家的推薦做法是,發生一次錯誤就能夠處理到,所以嘗試把 retryCount 為 0 的時候就設置 isShowErrorComponent 的值,

  1. this.setState({ 
  2.     isShowErrorComponent: true
  3. }) 

這時能夠顯示錯誤的fallback UI:

但沒法兒實現自動重試有限次數異步組件的渲染,否則如果還按照之前的方案,就會繼續向上拋出錯誤,如果沒有后續 catch 處理錯誤,頁面就會白屏!

然后嘗試主動觸發重新渲染,發現并沒有發起二次請求,點擊重試只是捕獲到了錯誤~

4.2 定位原因

不生效,于是想到聲明引入組件的代碼如下:

const LazyCounter = React.lazy(() => import('./components/counter/index'));

經過測試驗證,的確打印了錯誤日志,而只發起了一次網絡請求的原因是,該 LazyCounter 組件并沒有在組件中聲明,重新渲染的時候,LazyCounter 組件作為組件外的全局變量,不受 rerender 影響。

4.3 解決方案

因此,想要解決網絡加載錯誤問題并重試,就得在聲明代碼 import 的時候處理,因為import 返回的是一個Promise,自然就可以用 .catch 捕獲異常。

  1. - const LazyCounter = React.lazy(() => import('./components/counter/index')); 
  2.  
  3. + const LazyCounter = React.lazy(() => import('./components/counter/index').catch(err => { 
  4. +   console.log('dyboy:', err); 
  5. + })); 

而 import() 代碼執行的時候才會觸發網絡請求拉取分包資源文件,所以我們可以在異常捕獲中重試,并且可以重試一定次數,所以需要實現一個工具函數,統一處理 import() 動態引入可能失敗的問題。

該工具函數如下:

  1. /** 
  2.  *  
  3.  * @param {() => Promise} fn 需要重試執行的函數 
  4.  * @param {number} retriesLeft 剩余重試次數 
  5.  * @param {number} interval 間隔重試請求時間,單位ms 
  6.  * @returns Promise<any
  7.  */ 
  8. export const retryLoad = (fn, retriesLeft = 5, interval = 1000) => { 
  9.   return new Promise((resolve, reject) => { 
  10.     fn() 
  11.       .then(resolve) 
  12.       .catch(err => { 
  13.         setTimeout(() => { 
  14.           if (retriesLeft === 1) { 
  15.             // 遠程上報錯誤日志代碼 
  16.             reject(err); 
  17.             // coding... 
  18.             console.log(err) 
  19.             return
  20.           } 
  21.           retryLoad(fn, retriesLeft - 1, interval).then(resolve, reject); 
  22.         }, interval); 
  23.       }); 
  24.   }); 

使用的時候只需要將 import() 包一下:

  1. const LazyCounter = React.lazy(() => retryLoad(import('./components/counter/index'))); 

與此同時,為了多次請求下,“錯誤邊界”組件能夠捕獲到錯誤,同時能夠觸發兜底渲染邏輯,把 ErrorBoundary 組件發生錯誤時候直接處理展示兜底邏輯,不做重復渲染。則將 ErrorBoundary 中的重渲染計數邏輯代碼刪除即可。

  1. componentDidCatch(error) { 
  2.   console.log('發生錯誤!', error); 
  3.   this.setState({ 
  4.     isShowErrorComponent: true
  5.   }); 

另外,如果我們既想要渲染出錯后的重試,還需要保證多次網絡出錯后能有錯誤上報,那么只需要在 retryLoad 工具函數中增加錯誤日志遠程上報邏輯,然后不拋出 reject()。

4.4 表現效果

處理如下三種情況的效果:

 

  1. 正常按需加載組件成功
  2. 網絡原因一直下載失敗,展示兜底錯誤
  3. 網絡原因,中途恢復,展示正常功能

 

責任編輯:武曉燕 來源: DYBOY
相關推薦

2010-09-01 09:48:14

UbuntuLinux

2015-05-22 10:03:05

NAS云計算共享存儲

2010-04-28 13:31:52

IT技術人員

2025-06-25 09:55:26

帶寬網絡寬帶

2021-07-28 14:35:09

代碼進度條前端

2022-04-11 09:58:07

數據庫SQL

2023-05-26 14:02:29

AI智能

2020-11-04 17:53:49

Windows 10Windows系統

2022-02-22 11:50:16

Python字典代碼

2020-12-21 08:32:07

內存性能優化

2020-11-16 08:37:16

MariaDB性能優化

2018-09-03 00:01:51

華為程序員技術

2016-06-12 10:22:31

云計算

2025-02-19 11:00:00

2021-09-29 08:23:56

項目css

2023-11-19 23:24:21

Golang開發

2022-01-07 13:36:00

MySQL數據庫分頁

2021-06-09 10:15:26

優化性能顆粒度

2009-06-06 15:37:22

Hibernate性能

2025-03-03 00:55:00

開源界微服務框架
點贊
收藏

51CTO技術棧公眾號

亚洲av无码一区二区三区网址| 一色桃子av在线| 国产亚洲精品v| 亚洲人成免费电影| 成 人 黄 色 小说网站 s色| 性国产高清在线观看| 91麻豆成人久久精品二区三区| 国产精品久久久久久av| 欧美人妻精品一区二区免费看| 欧美调教在线| 欧美精品777| 国产伦精品一区二区三区四区视频_| 理论视频在线| 丁香婷婷综合激情五月色| 国产成人综合一区二区三区| 天天鲁一鲁摸一摸爽一爽| 丝袜美腿一区二区三区动态图| 欧美精品 日韩| 日韩欧美xxxx| wwww亚洲| 亚洲黄色片在线观看| 日本欧美色综合网站免费| 亚洲精品国产一区二| 美国三级日本三级久久99| 98精品国产高清在线xxxx天堂| 久久精品亚洲a| 精品一区二区三| 亚洲精品wwww| 亚洲免费观看在线| 亚洲国产天堂| 欧美三级在线看| 免费在线观看毛片网站| 草莓视频丝瓜在线观看丝瓜18| 亚洲欧美自拍偷拍| 亚洲日本欧美在线| 国产综合在线观看| 久久久久久久综合| 久久本道综合色狠狠五月| 国产 日韩 欧美 综合| 激情文学综合插| 国产在线999| 伊人久久一区二区| 免费在线观看一区二区三区| 日韩免费高清在线观看| 成人午夜激情片| 久久视频免费观看| av电影在线不卡| 精品国产精品久久一区免费式| 亚洲国产三级网| 日本精品一二三区| 97久久亚洲| 亚洲精品在线观看网站| 国产精品熟妇一区二区三区四区| 欧美经典影片视频网站| 欧美一区二区三区人| 五月天婷婷在线观看视频| 欧美高清免费| 欧美日韩精品久久久| 在线观看av网页| 在线观看亚洲精品福利片| 欧美一区日韩一区| 91精品国产高清91久久久久久| 欧美经典影片视频网站| 亚洲成av人乱码色午夜| 精品影片一区二区入口| 国产99久久久国产精品成人免费| 亚洲精品丝袜日韩| 东京热无码av男人的天堂| 四虎国产精品免费观看| 久久国产精品亚洲| 国产乡下妇女做爰视频| 美女精品一区| 国产一区二区视频在线观看| a视频免费在线观看| 成人免费毛片片v| 精品国产一区二区三区四区vr| 日本在线丨区| 国产精品电影一区二区三区| 超薄肉色丝袜足j调教99| av白虎一区| 欧美视频13p| 一路向西2在线观看| 一区二区三区免费在线看| 亚洲黄色成人网| 免费一级黄色录像| 欧美+日本+国产+在线a∨观看| 91av在线播放| 国产精品无码久久久久成人app| 国产精品91一区二区| 久久精品美女| 日本美女在线中文版| 亚洲一区二区不卡免费| 国内外免费激情视频| 激情五月综合婷婷| 国产婷婷97碰碰久久人人蜜臀| 少妇视频一区二区| 99精品视频免费观看| 国产欧美婷婷中文| 天天操天天干天天操| 国产精品国产三级国产| 免费无码不卡视频在线观看| 日本黄色成人| 亚洲另类图片色| 极品盗摄国产盗摄合集| 久久九九国产| caoporn国产精品免费公开| 欧美在线观看在线观看| 夜夜亚洲天天久久| 在线免费视频一区| 日韩有码一区| 色综合五月天导航| 综合久久中文字幕| 97久久精品人人爽人人爽蜜臀| 亚洲精品乱码久久久久久蜜桃91| 黄色漫画在线免费看| 91精品国产一区二区人妖| 摸摸摸bbb毛毛毛片| 99亚洲一区二区| 97免费高清电视剧观看| 在线观看麻豆| 91国内精品野花午夜精品| 91传媒理伦片在线观看| 91成人免费| 国产精品免费视频xxxx| 欧美套图亚洲一区| 欧美日韩国产精品专区| 久久精品亚洲天堂| 色综合五月天| 国产精品xxx视频| 日韩福利一区二区| 天天综合日日夜夜精品| 中文字幕99页| 亚洲调教视频在线观看| 91高跟黑色丝袜呻吟在线观看| 男人天堂手机在线| 欧美体内she精视频| 国产精品密蕾丝袜| 久久久久看片| 欧美视频1区| 蜜桃av在线播放| 亚洲国产三级网| 九九热在线免费观看| 成人福利电影精品一区二区在线观看| 精品无码av无码免费专区| www999久久| 欧美大片在线免费观看| 99精品视频在线播放免费| 亚洲欧洲av另类| 992tv人人草| 欧美日韩影院| 国产精品久久久久久久小唯西川 | 国产一区二区三区18| www毛片com| 欧美国产精品一区| 久久99爱视频| 欧美一区成人| 国产高清精品一区二区三区| 黑人精品视频| 亚洲黄页网在线观看| 亚洲免费在线视频观看| 国产日韩精品久久久| 高清av免费看| 亚洲精品极品少妇16p| eeuss一区二区三区| 草草视频在线| 一级做a爰片久久毛片美女图片| 在线观看亚洲一区二区| 亚洲欧美日韩一区二区| 中文字幕三级电影| 久久精品30| 中文有码久久| 成人爽a毛片| 日产日韩在线亚洲欧美| 欧美日韩视频在线播放| 欧美r级电影在线观看| 91精品国产乱码久久久张津瑜 | 日本午夜精品一区二区三区| 久久女人天堂| 久久久久久久久久久免费精品| 天堂中文字幕在线| 欧美日韩在线一区二区| 青青草激情视频| 91女厕偷拍女厕偷拍高清| 性生交免费视频| 欧美午夜久久| 日韩在线电影一区| 日韩一区二区三区在线看| 欧洲成人免费视频| 黄色免费在线观看网站| 日韩精品在线观| 国产又粗又长视频| 欧美日韩亚洲精品一区二区三区 | 人成免费电影一二三区在线观看| 欧美性生活影院| 国产精品自拍视频一区| 国产精品麻豆久久久| 亚洲国产精品狼友在线观看| 人人爽香蕉精品| 97在线国产视频| 日韩av在线中文字幕| 国产精品一区二区你懂得| 日本肉肉一区| 136fldh精品导航福利| 国产美女福利在线| 伊人亚洲福利一区二区三区| 高潮毛片7777777毛片| 欧美日韩国产精选| 7799精品视频天天看| 亚洲综合丁香婷婷六月香| 精品国产aaa| 久久综合九色欧美综合狠狠| 中文写幕一区二区三区免费观成熟| 日本视频一区二区三区| 欧美亚洲精品一区二区| 欧美黄免费看| 一区二区视频国产| 国产一区二区区别| 久久久久久欧美精品色一二三四| 午夜精品在线| 91免费精品国偷自产在线| 深夜视频一区二区| 欧美在线一区二区视频| 国产拍在线视频| 高清视频欧美一级| 欧美xxxx黑人又粗又长| 精品国产一区二区三区四区在线观看 | 91美女视频网站| 中文在线字幕观看| 国产米奇在线777精品观看| 免费看涩涩视频| 人人爽香蕉精品| 色婷婷狠狠18| 蜜臀精品久久久久久蜜臀| 播放灌醉水嫩大学生国内精品| 伊人成人网在线看| 97超碰国产精品| 狠狠干综合网| 国产一二三区在线播放| 欧美日韩理论| 欧美激情亚洲天堂| 欧美日本亚洲韩国国产| 国产免费内射又粗又爽密桃视频| 亚洲国产精品91| 亚洲国产精品女人| 欧美激情1区2区3区| 三上悠亚免费在线观看| 午夜精品网站| 阿v天堂2018| 99综合在线| 日韩 欧美 高清| 日韩不卡一二三区| 日日噜噜夜夜狠狠| 激情亚洲综合在线| 欧美69精品久久久久久不卡| 高清国产午夜精品久久久久久| 深夜视频在线观看| av男人天堂一区| av小说在线观看| 中文字幕免费观看一区| 欧美日韩色视频| 亚洲高清中文字幕| 日韩一区二区视频在线| 欧美视频在线一区二区三区| 国产精品-色哟哟| 精品美女一区二区| 深夜福利视频在线观看| 在线看日韩欧美| 二区三区四区高清视频在线观看| 欧美高清自拍一区| 女厕盗摄一区二区三区| 国产精品久久一区| 欧美成人精品一级| 久久精品国产一区二区三区日韩| 日韩精品影视| 潘金莲一级淫片aaaaa免费看| 伊人久久大香线蕉av超碰演员| 国产精品97在线| 经典一区二区三区| 182在线视频| 国产精品美女一区二区三区| 九九在线观看视频| 91电影在线观看| 精品久久国产视频| 精品网站999www| 超碰在线观看免费| 欧美亚洲视频在线看网址| 精品美女一区| 国内一区二区在线视频观看| 日韩欧美字幕| 我的公把我弄高潮了视频| 蜜臀av性久久久久蜜臀aⅴ| 无码人妻丰满熟妇区毛片蜜桃精品| 久久精品人人做人人爽97 | 精品久久久久久久久国产字幕 | 日韩久久免费av| 精品999视频| 久久久亚洲影院| vam成人资源在线观看| 欧美性色黄大片人与善| 午夜精品电影| 九九精品久久久| 久久亚洲综合色一区二区三区| 强乱中文字幕av一区乱码| 欧美性欧美巨大黑白大战| 日本高清视频www| 久久精品国产久精国产思思| 自拍网站在线观看| 国产精品国产亚洲精品看不卡15| 婷婷亚洲综合| 国产精品入口免费软件| 91美女片黄在线观看91美女| 欧美三级免费看| 欧美日本乱大交xxxxx| 国产最新视频在线观看| 91av在线看| 亚洲精品视频一二三区| 中文字幕欧美人与畜| 日韩精品福利网| 国产三级视频网站| 亚洲va欧美va国产va天堂影院| av免费观看在线| 日韩亚洲第一页| 全球最大av网站久久| 欧美福利一区二区三区| 一区二区福利| 亚洲一区二区三区四区av| 一级精品视频在线观看宜春院| 国产青青草视频| 久久精品国产亚洲精品2020| 欧美日韩亚洲国产| 日本在线观看一区二区三区| 亚洲黄页一区| 国产激情视频一区二区在线观看| mm131丰满少妇人体欣赏图| 午夜国产精品影院在线观看| 午夜精品久久久久久久爽| 久久精品视频中文字幕| 国产午夜在线播放| 欧美 日韩 国产 一区| 日韩肉感妇bbwbbwbbw| 亚洲国产精品v| 亚洲天堂中文在线| 北条麻妃在线一区二区| 亚洲高清国产拍精品26u| 亚洲视频在线观看日本a| 免费精品视频在线| 国精产品久拍自产在线网站| 欧美日韩国产一二三| 欧美jizz18性欧美| 亚洲影院在线看| 狠狠入ady亚洲精品经典电影| 精品人妻在线视频| 精品电影在线观看| 男人天堂资源在线| 国产成人啪精品视频免费网| 精品日本12videosex| 一起操在线视频| 亚洲人成在线播放网站岛国| av资源免费看| 午夜伦理精品一区| 九九亚洲视频| 国产视频1区2区3区| 亚洲免费观看高清| 神马午夜精品95| 日本精品久久久| 97久久视频| 国产乱国产乱老熟300部视频| 欧美日韩国产精品一区二区三区四区 | 国产一区二区观看| 中文字幕亚洲欧洲| 亚洲一区二区视频在线观看| 婷婷视频在线观看| 国产va免费精品高清在线| 水蜜桃久久夜色精品一区| 91精品人妻一区二区三区蜜桃2| 懂色av中文一区二区三区天美| 岛国最新视频免费在线观看| 91久久精品一区| 一本久道久久综合婷婷鲸鱼| 国产精品国产三级国产专业不| 欧美丰满高潮xxxx喷水动漫| 欧美gv在线| 在线观看欧美亚洲| 99在线热播精品免费| 中文字幕人妻精品一区| 欧美激情一区二区久久久| 美日韩中文字幕| 亚洲一级片免费观看| 狠狠综合久久av一区二区小说| 秋霞影院午夜丰满少妇在线视频| 国产富婆一区二区三区| 日本欧美韩国一区三区| 久久综合久久鬼| 在线电影欧美日韩一区二区私密| 中文字幕区一区二区三| 乱子伦视频在线看| 亚洲一区在线观看网站| 日本免费在线观看| 久久99国产精品| 国产一区二区免费看|