国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

白屏度量 阿里是怎么監(jiān)控前端白屏的?

共 16155字,需瀏覽 33分鐘

 ·

2021-07-10 14:12

點(diǎn)擊上方關(guān)注 全棧前端精選,一起學(xué)習(xí),天天進(jìn)步


引用下集團(tuán)監(jiān)控的 slogan:關(guān)注業(yè)務(wù)穩(wěn)定性的人,運(yùn)氣都不會太差~

背景

不知從什么時候開始,前端白屏問題成為一個非常普遍的話題,'白屏' 甚至成為了前端 bug 的代名詞:_喂,你的頁面白了。_而且,'白' 這一現(xiàn)象似乎對于用戶體感上來說更加強(qiáng),回憶起 windows 系統(tǒng)的崩潰 '藍(lán)屏':



可以說是非常相似了,甚至能明白了白屏這個詞匯是如何統(tǒng)一出來的。那么,體感如此強(qiáng)烈的現(xiàn)象勢必會給用戶帶來一些不好的影響,如何能盡早監(jiān)聽,快速消除影響就顯得很重要了。

為什么單獨(dú)監(jiān)控白屏

不光光是白屏,白屏只是一種現(xiàn)象,我們要做的是精細(xì)化的異常監(jiān)控。異常監(jiān)控各個公司肯定都有自己的一套體系,集團(tuán)也不例外,而且也足夠成熟。但是通用的方案總歸是有缺點(diǎn)的,如果對所有的異常都加以報(bào)警和監(jiān)控,就無法區(qū)分異常的嚴(yán)重等級,并做出相應(yīng)的響應(yīng),所以在通用的監(jiān)控體系下定制精細(xì)化的異常監(jiān)控是非常有必要的。這就是本文討論白屏這一場景的原因,我把這一場景的邊界圈定在了 “白屏” 這一現(xiàn)象。

方案調(diào)研

白屏大概可能的原因有兩種:

  1. js 執(zhí)行過程中的錯誤
  2. 資源錯誤

這兩者方向不同,資源錯誤影響面較多,且視情況而定,故不在下面方案考慮范圍內(nèi)。為此,參考了網(wǎng)上的一些實(shí)踐加上自己的一些調(diào)研,大概總結(jié)出了一些方案:

一、onerror + DOM 檢測

原理很簡單,在當(dāng)前主流的 SPA 框架下,DOM 一般掛載在一個根節(jié)點(diǎn)之下(比如 <div id="root"></div> )發(fā)生白屏后通?,F(xiàn)象是根節(jié)點(diǎn)下所有 DOM 被卸載,該方案就是通過監(jiān)聽全局的 onerror 事件,在異常發(fā)生時去檢測根節(jié)點(diǎn)下是否掛載 DOM,若無則證明白屏。我認(rèn)為是非常簡單暴力且有效的方案。但是也有缺點(diǎn):其一切建立在 白屏 === 根節(jié)點(diǎn)下 DOM 被卸載 成立的前提下,實(shí)際并非如此比如一些微前端的框架,當(dāng)然也有我后面要提到的方案,這個方案和我最終方案天然沖突。

二、Mutation Observer Api

不了解的可以看下文檔[1]。其本質(zhì)是監(jiān)聽 DOM 變化,并告訴你每次變化的 DOM 是被增加還是刪除。為其考慮了多種方案:

  1. 搭配 onerror 使用,類似第一個方案,但很快被我否決了,雖然其可以很好的知道 DOM 改變的動向,但無法和具體某個報(bào)錯聯(lián)系起來,兩個都是事件監(jiān)聽,兩者是沒有必然聯(lián)系的。
  2. 單獨(dú)使用判斷是否有大量 DOM 被卸載,缺點(diǎn):白屏不一定是 DOM 被卸載,也有可能是壓根沒渲染,且正常情況也有可能大量 DOM 被卸載。完全走不通。
  3. 單獨(dú)使用其監(jiān)聽時機(jī)配合 DOM 檢測,其缺點(diǎn)和方案一一樣,而且我覺得不如方案一。因?yàn)樗鼪]法和具體錯誤聯(lián)系起來,也就是沒法定位。當(dāng)然我和其他團(tuán)隊(duì)同學(xué)交流的時候他們給出了其他方向:通過追蹤用戶行為數(shù)據(jù)來定位問題,我覺得也是一種方法。

一開始我認(rèn)為這就是最終答案,經(jīng)過了漫長的心里斗爭,最終還是否定掉了。不過它給了一個比較好的監(jiān)聽時機(jī)的選擇。

三、餓了么-Emonitor 白屏監(jiān)控方案

餓了么的白屏監(jiān)控方案,其原理是記錄頁面打開 4s 前后 html 長度變化,并將數(shù)據(jù)上傳到餓了么自研的時序數(shù)據(jù)庫。如果一個頁面是穩(wěn)定的,那么頁面長度變化的分布應(yīng)該呈現(xiàn)「冪次分布」曲線的形態(tài),p10、p20 (排在文檔前 10%、20%)等數(shù)據(jù)線應(yīng)該是平穩(wěn)的,在一定的區(qū)間內(nèi)波動,如果頁面出現(xiàn)異常,那么曲線一定會出現(xiàn)掉底的情況。

其他

其他都大同小樣,其實(shí)調(diào)研了一圈下來發(fā)現(xiàn)無非就是兩點(diǎn)

  1. 監(jiān)控時機(jī):調(diào)研下來常見的就三種:
  2. onerror
  3. mutation observer api
  4. 輪訓(xùn)
  5. DOM 檢測:這個方案就很多了,除了上述的還可以:
  6. elementsFromPoint api 采樣
  7. 圖像識別
  8. 基于 DOM 的各種數(shù)據(jù)的各種算法識別
  9. ...

改變方向

幾番嘗試下來幾乎沒有我想要的,其主要原因是準(zhǔn)確率 -- 這些方案都不能保證我監(jiān)聽到的是白屏,單從理論的推導(dǎo)就說不通。他們都有一個共同點(diǎn):監(jiān)聽的是'白屏'這個現(xiàn)象,從現(xiàn)象去推導(dǎo)本質(zhì)雖然能成功,但是不夠準(zhǔn)確。所以我真正想要監(jiān)聽的是造成白屏的本質(zhì)。

那么回到最開始,什么是白屏?他是如何造成的?是因?yàn)殄e誤導(dǎo)致的瀏覽器無法渲染?不,在這個 spa 框架盛行的現(xiàn)在實(shí)際上的白屏是框架造成的,本質(zhì)是由于錯誤導(dǎo)致框架不知道怎么渲染所以干脆就不渲染。由于我們團(tuán)隊(duì) React 技術(shù)棧居多,我們來看看 React 官網(wǎng)的一段話[2]



React 認(rèn)為把一個錯誤的 UI 保留比完全移除它更糟糕。我們不討論這個看法的正確與否,至少我們知道了白屏的原因:渲染過程的異常且我們沒有捕獲異常并處理。

反觀目前的主流框架:我們把 DOM 的操作托管給了框架,所以渲染的異常處理不同框架方法肯定不一樣,這大概就是白屏監(jiān)控難統(tǒng)一化產(chǎn)品化的原因。但大致方向肯定是一樣的。

那么關(guān)于白屏我認(rèn)為可以這么定義:異常導(dǎo)致的渲染失敗。

那么白屏的監(jiān)控方案即:監(jiān)控渲染異常。那么對于 React 而言,答案就是:Error Boundaries

Error Boundaries

我們可以稱之為錯誤邊界,錯誤邊界是什么?它其實(shí)就是一個生命周期,用來監(jiān)聽當(dāng)前組件的 children 渲染過程中的錯誤,并可以返回一個 降級的 UI 來渲染:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasErrorfalse };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染能夠顯示降級后的 UI
    return { hasErrortrue };
  }

  componentDidCatch(error, errorInfo) {
    // 我們可以將錯誤日志上報(bào)給服務(wù)器
    logErrorToMyService(error, errorInfo);
  }

  render() {
    if (this.state.hasError) {
      // 我們可以自定義降級后的 UI 并渲染
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children; 
  }
}

一個有責(zé)任心的開發(fā)一定不會放任錯誤的發(fā)生。錯誤邊界可以包在任何位置并提供降級 UI,也就是說,一旦開發(fā)者'有責(zé)任心' 頁面就不會全白,這也是我之前說的方案一與之天然沖突且其他方案不穩(wěn)定的情況。那么,在這同時我們上報(bào)異常信息,這里上報(bào)的異常一定會導(dǎo)致我們定義的白屏,這一推導(dǎo)是 100% 正確的。

100% 這個詞或許不夠負(fù)責(zé),接下來我們來看看為什么我說這一推導(dǎo)是 100% 準(zhǔn)確的:

React 渲染流程

我們來簡單回顧下從代碼到展現(xiàn)頁面上 React 做了什么。我大致將其分為幾個階段:render => 任務(wù)調(diào)度 => 任務(wù)循環(huán) => 提交 => 展示 我們舉一個簡單的例子來展示其整個過程(任務(wù)調(diào)度不再本次討論范圍故不展示):

const App = ({ children }) => (
  <>
    <p>hello</p>
    { children }
  </>

);
const Child = () => <p>I'm child</p>

const a = ReactDOM.render(
  <App><Child/></App>,
  document.getElementById('root')
);

準(zhǔn)備

首先瀏覽器是不認(rèn)識我們的 jsx 語法的,所以我們通過 babel 編譯大概能得到下面的代碼:

var App = function App(_ref2{
  var children = _ref2.children;
  return React.createElement("p"null"hello"), children);
};

var Child = function Child({
  return React.createElement("p"null"I'm child");
};

ReactDOM.render(React.createElement(App, null, React.createElement(Child, null)), document.getElementById('root'));

babel 插件將所有的 jsx 都轉(zhuǎn)成了 createElement 方法,執(zhí)行它會得到一個描述對象 ReactElement 大概長這樣子:

{
    $$typeofSymbol(react.element),
  keynull,
  props: {}, // createElement 第二個參數(shù) 注意 children 也在這里,children 也會是一個 ReactElement 或 數(shù)組
  type'h1' // createElement 的第一個參數(shù),可能是原生的節(jié)點(diǎn)字符串,也可能是一個組件對象(Function、Class...)
}

所有的節(jié)點(diǎn)包括原生的 <a></a> 、 <p></p> 都會創(chuàng)建一個 FiberNode ,他的結(jié)構(gòu)大概長這樣:

FiberNode = {
    elementTypenull// 傳入 createElement 的第一個參數(shù)
  keynull,
  type: HostRoot, // 節(jié)點(diǎn)類型(根節(jié)點(diǎn)、函數(shù)組件、類組件等等)
  returnnull// 父 FiberNode
  childnull// 第一個子 FiberNode
  siblingnull// 下一個兄弟 FiberNode
  flagnull// 狀態(tài)標(biāo)記
}

你可以把它理解為 Virtual Dom 只不過多了許多調(diào)度的東西。最開始我們會為根節(jié)點(diǎn)創(chuàng)建一個 FiberNodeRoot 如果有且僅有一個 ReactDOM.render 那么他就是唯一的根,當(dāng)前有且僅有一個 FiberNode 樹。

我只保留了一些渲染過程中重要的字段,其他還有很多用于調(diào)度、判斷的字段我這邊就不放出來了,有興趣自行了解

render

現(xiàn)在我們要開始渲染頁面,是我們剛才的例子,執(zhí)行 ReactDOM.render 。這里我們有個全局 workInProgress 對象標(biāo)志當(dāng)前處理的 FiberNode

  1. 首先我們?yōu)楦?jié)點(diǎn)初始化一個 FiberNodeRoot ,他的結(jié)構(gòu)就如上面所示,并將 workInProgress= FiberNodeRoot。
  2. 接下來我們執(zhí)行 ReactDOM.render 方法的第一個參數(shù),我們得到一個 ReactElement :
ReactElement = {
  $$typeofSymbol(react.element),
  keynull,
  props: {
    children: {
      $$typeofSymbol(react.element),
      keynull,
      props: {},
      refnull,
      type: ? Child(),
    }
  }
  refnull,
  type: f App()
}

該結(jié)構(gòu)描述了 <App><Child /></App>

  1. 我們?yōu)?nbsp;ReactElement 生成一個 FiberNode 并把 return 指向父 FiberNode ,最開始是我們的根節(jié)點(diǎn),并將 workInProgress = FiberNode
{
  elementType: f App(), // type 就是 App 函數(shù)
  keynull,
  type: FunctionComponent, // 函數(shù)組件類型
  return: FiberNodeRoot, // 我們的根節(jié)點(diǎn)
  childnull,
  siblingnull,
  flagsnull
}
  1. 只要workInProgress 存在我們就要處理其指向的 FiberNode 。節(jié)點(diǎn)類型有很多,處理方法也不太一樣,不過整體流程是相同的,我們以當(dāng)前函數(shù)式組件為例子,直接執(zhí)行 App(props) 方法,這里有兩種情況
  2. 該組件 return 一個單一節(jié)點(diǎn),也就是返回一個 ReactElement 對象,重復(fù) 3 - 4 的步驟。并將當(dāng)前 節(jié)點(diǎn)的 child 指向子節(jié)點(diǎn) CurrentFiberNode.child = ChildFiberNode 并將子節(jié)點(diǎn)的 return 指向當(dāng)前節(jié)點(diǎn) ChildFiberNode.return = CurrentFiberNode
  3. 該組件 return 多個節(jié)點(diǎn)(數(shù)組或者 Fragment ),此時我們會得到一個 ChildiFberNode 的數(shù)組。我們循環(huán)他,每一個節(jié)點(diǎn)執(zhí)行 3 - 4 步驟。將當(dāng)前節(jié)點(diǎn)的 child 指向第一個子節(jié)點(diǎn) CurrentFiberNode.child = ChildFiberNodeList[0] ,同時每個子節(jié)點(diǎn)的 sibling 指向其下一個子節(jié)點(diǎn)(如果有) ChildFiberNode[i].sibling = ChildFiberNode[i + 1] ,每個子節(jié)點(diǎn)的 return 都指向當(dāng)前節(jié)點(diǎn) ChildFiberNode[i].return = CurrentFiberNode

如果無異常每個節(jié)點(diǎn)都會被標(biāo)記為待布局 FiberNode.flags = Placement

  1. 重復(fù)步驟直到處理完全部節(jié)點(diǎn) workInProgress 為空。

最終我們能大概得到這樣一個 FiberNode 樹:

FiberNodeRoot = {
  elementTypenull,
  type: HostRoot,
  returnnull,
  child: FiberNode<App>,
  siblingnull,
  flags: Placement, // 待布局狀態(tài)
}

FiberNode<App> {
  elementType: f App(),
  type: FunctionComponent,
  return: FiberNodeRoot,
  child: FiberNode<p>,
  siblingnull,
  flags: Placement // 待布局狀態(tài)
}

FiberNode<p> {
  elementType'p',
  type: HostComponent,
  return: FiberNode<App>,
  sibling: FiberNode<Child>,
  childnull,
  flags: Placement // 待布局狀態(tài)
}

FiberNode<Child> {
  elementType: f Child(),
  type: FunctionComponent,
  return: FiberNode<App>,
  childnull,
  flags: Placement // 待布局狀態(tài)
}

提交階段

提交階段簡單來講就是拿著這棵樹進(jìn)行深度優(yōu)先遍歷 child => sibling,放置 DOM 節(jié)點(diǎn)并調(diào)用生命周期。

那么整個正常的渲染流程簡單來講就是這樣。接下來看看異常處理

錯誤邊界流程

剛剛我們了解了正常的流程現(xiàn)在我們制造一些錯誤并捕獲他:

const App = ({ children }) => (
  <>
  <p>hello</p>
  { children }
  </>

);
const Child = () => <p>I'm child {a.a}</p>

const a = ReactDOM.render(
  <App>
    <ErrorBoundary><Child/></ErrorBoundary>
  </App>
,
  document.getElementById('root')
);

執(zhí)行步驟 4 的函數(shù)體是包裹在 try...catch 內(nèi)的如果捕獲到了異常則會走異常的流程:

do {
  try {
    workLoopSync(); // 上述 步驟 4
    break;
  } catch (thrownValue) {
    handleError(root, thrownValue);
  }
while (true);

執(zhí)行步驟 4 時我們調(diào)用 Child 方法由于我們加了個不存在的表達(dá)式 {a.a} 此時會拋出異常進(jìn)入我們的 handleError 流程此時我們處理的目標(biāo)是 FiberNode<Child> ,我們來看看 handleError :

function handleError(root, thrownValue): void {
  let erroredWork = workInProgress; // 當(dāng)前處理的 FiberNode 也就是異常的 節(jié)點(diǎn)
  throwException(
    root, // 我們的根 FiberNode
    erroredWork.return, // 父節(jié)點(diǎn)
    erroredWork,
    thrownValue, // 異常內(nèi)容
  );
    completeUnitOfWork(erroredWork);
}

function throwException(
  root: FiberRoot,
  returnFiber: Fiber,
  sourceFiber: Fiber,
  value: mixed,
{
  // The source fiber did not complete.
  sourceFiber.flags |= Incomplete;

  let workInProgress = returnFiber;
  do {
    switch (workInProgress.tag) {
      case HostRoot: {
        workInProgress.flags |= ShouldCapture;
        return;
      }
      case ClassComponent:
        // Capture and retry
        const ctor = workInProgress.type;
        const instance = workInProgress.stateNode;
        if (
          (workInProgress.flags & DidCapture) === NoFlags &&
          (typeof ctor.getDerivedStateFromError === 'function' ||
            (instance !== null &&
              typeof instance.componentDidCatch === 'function' &&
              !isAlreadyFailedLegacyErrorBoundary(instance)))
        ) {
          workInProgress.flags |= ShouldCapture;
          return;
        }
        break;
      default:
        break;
    }
    workInProgress = workInProgress.return;
  } while (workInProgress !== null);
}

代碼過長截取一部分 先看 throwException 方法,核心兩件事:

  1. 將當(dāng)前也就是出問題的節(jié)點(diǎn)狀態(tài)標(biāo)志為未完成 FiberNode.flags = Incomplete
  2. 從父節(jié)點(diǎn)開始冒泡,向上尋找有能力處理異常( ClassComponent )且的確處理了異常的(聲明了 getDerivedStateFromError 或 componentDidCatch 生命周期)節(jié)點(diǎn),如果有,則將那個節(jié)點(diǎn)標(biāo)志為待捕獲 workInProgress.flags |= ShouldCapture ,如果沒有則是根節(jié)點(diǎn)。

completeUnitOfWork 方法也類似,從父節(jié)點(diǎn)開始冒泡,找到 ShouldCapture 標(biāo)記的節(jié)點(diǎn),如果有就標(biāo)記為已捕獲 DidCapture ,如果沒找到,則一路把所有的節(jié)點(diǎn)都標(biāo)記為 Incomplete 直到根節(jié)點(diǎn),并把 workInProgress 指向當(dāng)前捕獲的節(jié)點(diǎn)。

之后從當(dāng)前捕獲的節(jié)點(diǎn)(也有可能沒捕獲是根節(jié)點(diǎn))開始重新走流程,由于其狀態(tài) react 只會渲染其降級 UI,如果有 sibling 節(jié)點(diǎn)則會繼續(xù)走下面的流程。我們看看上述例子最終得到的 FiberNode 樹:

FiberNodeRoot = {
  elementTypenull,
  type: HostRoot,
  returnnull,
  child: FiberNode<App>,
  siblingnull,
  flags: Placement, // 待布局狀態(tài)
}

FiberNode<App> {
  elementType: f App(),
  type: FunctionComponent,
  return: FiberNodeRoot,
  child: FiberNode<p>,
  siblingnull,
  flags: Placement // 待布局狀態(tài)
}

FiberNode<p> {
  elementType'p',
  type: HostComponent,
  return: FiberNode<App>,
  sibling: FiberNode<ErrorBoundary>,
  childnull,
  flags: Placement // 待布局狀態(tài)
}

FiberNode<ErrorBoundary> {
  elementType: f ErrorBoundary(),
  type: ClassComponent,
  return: FiberNode<App>,
  childnull,
  flags: DidCapture // 已捕獲狀態(tài)
}

FiberNode<h1> {
  elementType: f ErrorBoundary(),
  type: ClassComponent,
  return: FiberNode<ErrorBoundary>,
  childnull,
  flags: Placement // 待布局狀態(tài)
}

如果沒有配置錯誤邊界那么根節(jié)點(diǎn)下就沒有任何節(jié)點(diǎn),自然無法渲染出任何內(nèi)容。

ok,相信到這里大家應(yīng)該清楚錯誤邊界的處理流程了,也應(yīng)該能理解為什么我之前說由 ErrorBoundry 推導(dǎo)白屏是 100% 正確的。當(dāng)然這個 100% 指的是由 ErrorBoundry 捕捉的異?;旧蠒?dǎo)致白屏,并不是指它能捕獲全部的白屏異常。以下場景也是他無法捕獲的:

  • 事件處理
  • 異步代碼
  • SSR
  • 自身拋出來的錯誤

React SSR 設(shè)計(jì)使用流式傳輸,這意味著服務(wù)端在發(fā)送已經(jīng)處理好的元素的同時,剩下的仍然在生成 HTML,也就是其父元素?zé)o法捕獲子組件的錯誤并隱藏錯誤的組件。這種情況似乎只能將所有的 render 函數(shù)包裹 try...catch ,當(dāng)然我們可以借助 babel 或 TypeScript 來幫我們簡單實(shí)現(xiàn)這一過程,其最終得到的效果是和 ErrorBoundry 類似的。

而事件和異步則很巧,雖說 ErrorBoundry 無法捕獲他們之中的異常,不過其產(chǎn)生的異常也恰好不會造成白屏(如果是錯誤的設(shè)置狀態(tài),間接導(dǎo)致了白屏,剛好還是會被捕獲到)。這就在白屏監(jiān)控的職責(zé)邊界之外了,需要別的精細(xì)化監(jiān)控能力來處理它。

總結(jié)

那么最后總結(jié)下本文的出的幾個結(jié)論:我對白屏的定義:異常導(dǎo)致的渲染失敗。對應(yīng)方案是:資源監(jiān)聽 + 渲染流程監(jiān)聽。

在目前 SPA 框架下白屏的監(jiān)控需要針對場景做精細(xì)化的處理,這里以 React 為例子,通過監(jiān)聽渲染過程異常能夠很好的獲得白屏的信息,同時能增強(qiáng)開發(fā)者對異常處理的重視。而其他框架也會有相應(yīng)的方法來處理這一現(xiàn)象。

當(dāng)然這個方案也有弱點(diǎn),由于是從本質(zhì)推導(dǎo)現(xiàn)象其實(shí)無法 cover 所有的白屏的場景,比如我要搭配資源的監(jiān)聽來處理資源異常導(dǎo)致的白屏。當(dāng)然沒有一個方案是完美的,我這里也是提供一個思路,歡迎大家一起討論。

作者:ES2049 / 金城武

https://zhuanlan.zhihu.com/p/383686310

參考資料


[1]

文檔: https://link.zhihu.com/?target=https%3A//developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver

[2]

一段話: https://link.zhihu.com/?target=https%3A//zh-hans.reactjs.org/docs/error-boundaries.html%23new-behavior-for-uncaught-errors


The End


歡迎自薦投稿到《全棧前端精選》,如果你覺得這篇內(nèi)容對你挺有啟發(fā),記得點(diǎn)個 「在看」


點(diǎn)個『在看』支持下 

瀏覽 76
點(diǎn)贊
評論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)
評論
圖片
表情
推薦
點(diǎn)贊
評論
收藏
分享

手機(jī)掃一掃分享

分享
舉報(bào)

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 99re伊人| 琪琪色视频| 国产丝袜人妖TS系列| 猛男大粗猛爽h男人味| 国产91一区在线精品| 日本黄色免费视频| 伊人99热| 草草在线视频| 怡红院综合网| www.91com| 波多野结衣久久精品| 亚洲无码在线资源| 亚洲精品一区中文字幕乱码| 久热久| 欧美日韩一二三区| 五月婷丁香| 国产啊啊啊啊| 日韩在线播放视频| 欧美AAA在线观看| 操BBB操BBB| 2024av在线| 中文无码Av| 国产45页| 99在线精品视频| 一级黄色视频网站| 岛国av在线播放| 69AV在线播放| 久久99人妻无码精品一区| 7799精品视频天天看| 一区二区三区四区av| 95四川乱子伦视频国产| 午夜神马51| 少妇456| 亚洲第一黄色| 中文字幕+乱码+中文乱码91| www香蕉成人片com| 欧美亚洲性爱| 噜噜噜在线| 操操干| 激情视频免费在线观看| 亚洲男人的天堂视频网在线观看+720P | 国产毛片一照区| 91综合在线| 国产va| 99在线视频免费观看| av中文字幕网| 国产精品久久久久久亚洲影视| 免费观看黄色小视频| а√在线中文8| 国产九九热视频| 中文字幕av免费在线观看| 豆花视频在线免费观看| 欧美日韩性色无码免费| 亚洲中文无码AV在线| sm视频网站| 国产激情内射| 成人影片在线观看18| 国产乱码精品一区二区三区的特点| 亚洲欧洲无码在线| 亚洲精品视频在线观看网站| 一级黄色毛片| 一区在线观看| 99热这里有精品| 中文字幕av在线观看| 日韩欧美中文字幕在线观看| 人人妻人人澡人人爽人人欧美一区 | 国产精品夜夜爽7777777| 色综合天天综合| 亚洲日韩欧美在线观看| 一二三四区视频| 亚洲AV黄片| 亚洲黄色毛片| 亚洲AV播放| 日本有码在线| 操学生妹| 97人妻精品一区二区三区图片| 欧美性猛交XXXX乱大交HD | 中文乱伦视频| 欧美午夜三级| 国产黄色视频免费| 亚洲综合国产| 一级黄色a片| 波多野结衣视频在线| 成人av无码| 日本激情网站| 四虎AV| 天天干天天操天天干| 国产成人网| 国产中文字幕在线播放| 黄色三级视频在线观看| 亚洲中文字幕一区| 水蜜桃在线视频| 中文有码| 久久亚洲福利视频| 国产欧美激情| 91黄色在线视频| 伊人性视频| 国产青草视频在线观看| 成人一级黄色电影| 97色吧| 国产又黄又| 欧美日韩久久久| 91嫩操| 日韩夜夜操| 无码人妻丰满熟妇区蜜桃| 亚州天堂网| 日本一区二区三区免费观看| 国产精品18禁| 成人午夜无码福利视频| 91精品久久香蕉国产线看观看| 三级片中文字幕| 精品欧美无人区乱码毛片| 成人精品在线| 麻豆精东一区二区欧美国产| 香蕉网站操逼片| 欧美性爱高清| 色久影院| 免费电影日本黄色| 国产精品久久久久久精| 成人AV十八亚洲二区| 国产一区二区三区在线视频| 中文字幕免费在线视频| jizz在线观看视频| 在线无码播放| 午夜黄色操逼视频| 亚洲护士无码| 无码AV电影在线观看| 色色激情网| 人人操国产| 骚妇大战黑人15P| 成人做爰69片免费观看| 人人操夜夜操| 久久久精品电影| 亚洲无码精品视频| 人妻精品电影| 夜夜操狠狠操| 日本A在线播放| 欧美国产性爱| 黄色电影中文字幕| 正在播放JUQ-878木下凛凛子 | 无码123| 蜜桃av秘无码一区三区四| 國產美女AV操逼網站| 色吟av| 久久久久久无码精品亚洲日韩麻豆 | 日韩激情| 蜜桃精品一区二区三区美女| 国产欧美在线免费观看| 荫蒂添的高潮免费视频| 亚洲秘av无码一区二区| 成人亚洲A片V一区二区三区蜜月| 成人激情综合网| 日韩在线视频一区| 国产激情欧洲在线观看一区二区三区| 成年人性生活免费视频| 黄色三级片视频| 免费国产在线视频| 先锋av资源网| 日韩av一区二区三区| 水果派AV解说| 午夜国产精品AV| 欧洲无码一区二区三区| 日韩欧美小电影| 色综合中文字幕| 亚洲精品成人7777777| 亚洲黄片免费观看| 欧美性爱精品一区| 国产精品一级A片| 中文激情网| 神马午夜福利影院| 手机看片1204| 在线观看国产视频| 少妇456| 无码AA| 人人操国产| 久99视频| 人妻97| 996视频| 91黄网站在线观看| 久久视频一区| 91人人在线| www.婷婷五月天| 中文字幕操逼网站| 一级黄色视频网站| 法国《少女日记》电影| 俺也色俺也干| 久久久国产一区| 成人影片在线观看18| 青青青亚州视频在线| 亚洲成人无码一区| 黄片网站视频| 亚色网址| 国产精品v欧美精品v日韩精品| 日本在线一区二区| 欧美成人激情视频| 加勒比无码在线| 日韩性AV| 亚洲第一成人久久网站| 亚洲免费黄片| 国产天堂在线| 成人小视频十八禁免费观看| 久久综合大香蕉| 乱子伦日B视频| 天天插夜夜操| 久久国产精品视频| 九九成人免费视频| 西西特级WWW444无码| 老鸭窝在线观看视频| 久青草视频| 亚洲无码另类| 色五月婷婷久久| 蜜桃视频网站18| 亚洲久久久| 中文字幕无码A片久久| 精品成人影视| 日韩一区二区免费视频| 大地二中文在线观看免费鲁大师 | 探花一区二区| 天天色AV| 欧美手机在线| 欧美老妇大BBBBXXXX| 色视频国产| 99精品久久久久久无码| 亚洲综合区| 国产高清无码网站| 丁香六月综合激情| 亚洲第一天堂| 国产美女操逼网站| 欧美成人网站免费在线观看| 亚洲无码在线免费视频| 黄片视频大全| 日韩v亚洲| 一级a免一级a做免费线看内祥| 久久亚洲AV| 伊人在线成人视频| 无码一区二区黑人猛烈视频网站| 亚洲三级片在线| 免费黄色AV| 国产高清无码网站| 国产日韩一区二区| 欧美精产国品一二三产品在哪买 | 91丨牛牛丨国产人妻| av手机在线| 男女啪啪| 黄色成人网站在线观看| 欧美日韩黄色极品| 亚洲中文免费视频| 亚洲无码成人电影| 色综合99久久久无码国产精品| 亚洲精品无码a片| 色噜噜狠狠色综无码久久合欧美 | 爱爱爱爱视频| 精品国产三级| 久久嫩草精品| 亚洲AV综合网| 日韩视频一区二区三区| 日本少妇激情视频| 免费无码又爽又黄又刺激网站| 日韩一级免费视频| 日韩欧美国产成人| 97国产精品人人爽人人做| 日韩中文字幕av| 青娱亚洲| 想要xx在线观看| 日产久久视频| 久久久久99| 欧美精品日韩| 在线观看高清无码| AV黑人| 欧美熟妇性爱| 性爱AV在线观看| 国产精品你懂得| 中国一级A片| 成人黄色毛片视频| 西西人体44www大胆无码| 91日韩欧美| 人人色人人草| 黑巨茎大战欧美白妞小说| 亚洲日韩中文字幕| 自拍欧美亚洲| 亚洲无码一区二区在线观看| 亚洲午夜无码精品专区| 99er在线观看视频| 一区不卡| 成人H动漫精品一区二区无码| 69成人免费视频| 亚洲美女喷水视频| 日韩毛片在线看| 黄色在线免费| 国产精品欧美激情| 午夜久久久久久久久久久久91 | 91麻豆国产福利在线观看| 国产综合av| 性做久久久久久| 69av在线观看视频| 色播五月丁香| 亚洲一区亚洲二区| 蜜桃BBwBBWBBwBBw| 午夜偷拍网站| 欧一美一色一伦一A片| 中文无码在线| 国产免费www| 国产AV无码成人精品毛片| 亚洲最新在线观看| 熟妇人妻中文AV无码| 日韩三级在线免费观看| 国产无码AV在线| 无码视频免费| 婷婷五月天激情电影| 国产性爱在线观看| 97精产国品久久蜜桃臀| AV中文字幕在线播放| 91操美女视频| 中文字幕在线观看日本| 青青草无码成人AV片| 黄色电影av| 精品人无码一区二区三区下载| 爽爽午国产浪潮AV性色www| 1024国产| 日韩vA| 特级婬片AAAAAAA级| 狠狠躁夜夜躁人人爽人妻| 免费久草视频| 亚洲有码中文字幕| www.久热| 欧美精产国品一二三| 操逼短视频| 中文av字幕| 黄色AV电影| 亚洲欧美在线播放| 91ThePorn国产| 欧美精品久久久久| 国精产品九九国精产品| 亚洲精品国产成人综合久久久久久久久 | 四虎av在线播放| 久久成人导航| 91亚洲在线观看| 91成人无码看片在线观看网址| 男人AV网| 日韩无码内射| 青青三级片| 大香蕉婷婷五月天| 视色视频在线观看| 五月丁香婷婷激情| 亚洲Japanese办公室制服| 在线免费观看无码视频| 日本高清视频网站网wwwwww| 免费日韩毛片| 五月天激情爱爱| 一本色道无码道| www.a日逼| 中文字幕在线电影| 成人毛片在线播放免费| 超碰免费人妻| 操逼视频观看免费| 秋霞午夜视频| 91免费在线视频观看| 日韩一级无码特黄AAA片| 色五月婷婷丁香五月| 91日韩精品| 日韩av在线不卡| 学生妹一级片| 五香丁香天堂网| 护士小雪的yin荡高日记H视频 | 日逼一级片| 成人黄色录像| 黄色伊人| 五月婷婷操逼| 青青草资源站| 密臀AV在线| 麻豆视频在线看| 99热r| 日本人妻在线播放| 青娱乐91| 欧美成人手机在线观看| 丰滿老婦BBwBBwBBw| 99国产精品久久久久久久成人| 伊人97| 亚洲免费观看高清完整版在线观 | 亚洲天堂无码在线观看| 天天爱天天插| 欧美视频一区二区| 老太色HD色老太HD-百度| 正在播放李彩斐被洋老外| 久久在线免费视频| 免费无码婬片A片AA片| 精品国产AⅤ麻豆| 成年片免费观看网站免费观看,亚洲+欧...| 日韩午夜精品| 亚洲综合视频网| 狠狠狠操| 日韩中文字幕无码中字字幕| 免费V片在线观看| 欧美黄色三级片| 色优久久| 婷婷五月天激情四射| 囯产一级a一级a免费视频| 青误乐在线播放| 欧美黄片一区| 国产欧美综合一区| 大香蕉一级片| 蜜臀网| 人妻精品一卡二卡| 青娱乐伊人| 黄片视频在线免费播放| 水蜜桃一区| 骚逼逼影院| 香蕉国产AV| 壁特壁视频在线观看| 中国老女人日逼| 97无码人妻| 大骚逼影院| 亚洲国产成人va| 91精品国产综合久久蜜臀使用方法 | 老妇bbw| 成人无码网站| 国产成人午夜高潮毛片| 性99网站| 性无码一区二区| 国产小视频在线看| 99久久精品国产色欲| A一级黄色片| 中文字幕精品综合| 五月婷婷激情网| 色哟哟在线观看| 亚洲精品国产精品乱码视99| 猛男大粗猛爽H男人味| 人成在线观看| 日韩人妻无码精品| 男人亚洲天堂| 日韩毛片在线免费观看| 中文字幕一区在线观看| 国产亚洲久一区二区三区| 成人五月天黄色电影| 日日干夜夜操| 亚洲男人的天堂视频网在线观看+720P | 亚洲秘无码一区二区三区欧美| 久久久久精| 中文字幕北条麻妃| 草逼免费视频| 欧美成人精品在线观看| 95四川乱子伦视频国产| 久久精品人妻| 久久超碰精品| 欧美试看| 91视频在线看| 久久国产黄色视频| 久久国产热| 成人精品| 国产性爱网址| 伊人青青操| 亚洲国产黄片| 夜夜爽久久精品91| 久久黄色的| 欧美成人精品A片免费一区99| 国产亚洲视频在线观看| 婷婷丁香五月亚洲| AV电影天堂网| www.超碰| 亚洲成人AV在线播放| 日本高清久久| 欧美一级黄色性爱视频| 一级黄色视频在线观看| 五月婷婷丁香网| 天堂无吗| 果冻传媒A片一二三区| 黄色大片免费在线观看| 九九九九九九精品视频| 九九九精品| 肉乳无码A片av| 亚洲XXXXX| 这里视频很精彩免费观看电视剧最新 | 伊人网成人| 男人的天堂亚洲| 97伊人大香蕉| 亚洲综合社区在线| 久久男人网| 丁香乱伦| 蜜桃传媒在线| 国产午夜福利电影| av资源网站| 韩国三级片在线| 茄子av| 人妻无码中文字幕免费视频蜜桃| 黄色A片一级| 91看片看婬黄大片Videos | 日韩在线中文字幕亚洲| 亚洲无码在线免费观看视频| 人人色人人操人人干| 国产女人18水真多18精品| 日皮做爱视频网站| 九九九久久久| 国产理论片在线观看| 视频一二三区| 中文字幕永久在线5| 国产在线视频你懂的| 懂色AV一区二区三区国产中文在线| 午夜激情操一操| 国产精品视频在线观看| 国产成人在线免费视频| 一级特黄录像免费播放下载软件 | 亚洲在线观看网站| 91成人片| 在线免费观看黄色电影| 综合久久中文字幕| 亚洲天堂一区在线观看| 91丨九色丨蝌蚪丨肥女| 99热亚洲| 无码白浆| 高清无码不卡在线观看| 国产精品色色色| 亚洲无码在线播放| 午夜黄色福利| 久久久久久综合| 国产免费久久久| 翔田千里无码视频| 欧美国产精品| 亚洲高清无码中文字幕| 久操视频免费在线观看| 少妇人妻一区二区三区| 好吊视频一区二区三区红桃视频you | 亚洲A级毛片| 麻豆视频免费观看| 日韩无码中文字| 强伦轩人妻一区二区三区70后| 中文字幕精品在线观看| 国产主播中文字幕| 亚洲中文AV在线| 无码中文字幕高清| 黄色免费在线观看视频| 中文字幕一区二区二三区四区| 日韩香蕉网| a片视频免费观看| 亚州成熟少妇视频在线观看| 免费视频一区二区三区四区| 天堂在线观看av| 久久精品性爱| 日韩中文字幕| 亚洲精品在线观看视频| 日韩美女在线| 黑人乱伦| 久久青草影院| www.cao| 精品国产91| 国产伦精一品二品三品app| 91人妻一区二区三区无不码超满| 三级视频网站| 日韩欧美在线免费观看| 免费乱伦视频| 免费手机av| 欧美一级A片免费看视频小说| 人人干人人操人人爱| 亚洲无码高清在线| 亚洲高清免费视频| 91最新网址| 国产在线拍揄自揄拍无码网站新闻 | 欧美综合精品| 日韩精品一区二区在线观看| 香蕉伊人视频| 国內精品久久久久久久| 成年人视频网| 操逼免费视频网站| 麻豆熟妇乱妇熟色A片在线看 | 五月av| 亚洲在线视频观看| 日韩无码激情| 男人天堂视频在线观看| 在线免费观看无码视频| 9热在线视频| www.日韩AV| 日韩无码链接| 九一国产在线| 在线视频A| 大香蕉青娱乐| 久久无码专区| 黄色大片中国一级片-免费看特一级片-亚洲黄色AV | 91视频www| 91国产视频在线观看| 五月天激情性爱| 蜜桃视频网站18| 日韩aaaaaa| 不卡的av在线| 成人精品久久| 91精品人妻一区二| 97人妻精品一区二区三区| 欧美成人无码片免费看A片秀色| 韩日一级片| 亚洲五月婷婷| 强波多野结衣黑人| 99久久精品一区二区成人| 色情片在线播放| 日韩无码福利| 日日干AV| 亚洲福利视频网站| 欧美在线免费观看| 午夜免费视频1000| 成人不卡| 青娱乐AV| 操逼大毛片| 欧美色图1| 日韩欧美亚洲一区二区三区| 日本边摸边吻奶边做爰| 亚洲免费一级| 日韩中文字幕不卡| www.av在线| 中文字幕你懂的在线三级| 国产AV大香蕉| 超碰97成人| 婷婷丁香色五月| 一区二区黄| 狠狠视频| 福利视频一区| 久久精品禁一区二区三区四区五区| 激情婷婷av| 四虎成人在线| 欧洲第一无人区观看| 亚洲视频中文字幕在线观看| 久久黄网| 福利视频网亚洲| 亚洲成人77777| 黄色国产网站| 欧美在线v| 亚洲夜夜撸| 国产成人在线视频| 亚洲在线视频网站| 精品伊人久久| 久操福利视频| 中文字幕第五页| 精品一区二区三区蜜桃臀www | 亚洲无码视频专区| A视频在线免费观看| 婷婷五月亚洲| A黄色绿像| 欧美熟女一区二区| 影音先锋三区| 91三级电影| 亚洲综合一区二区| 色AV高清| 国产精品在线免费| 免费A在线| 操少妇| 国产激情欧洲在线观看一区二区三区| 亚洲性爱大全| aaa国产| 午夜无码人妻AV| 亚洲男人天堂| 成年人免费公开视频| 成人免费视频网| 69人妻人人澡人人爽人人精品| 丁香婷婷男人天堂| 一起操在线视频| 婷婷丁香六月天| 国产AV中文字幕| 国产精品久久久久久久久久二区三区 | 91麻豆精品无码人妻| 蝌蚪窝视频在线| 亚洲精品字幕| 国产精品一区av| 亚洲区成人777777精品| 伊人网址| 国产黄色视频在线播放| 特级欧美AAAAAA| 久久丝袜| 伊人激情影院| 精品视频在线观看免费| 91av| 一道本视频在线免费观看| 亚洲无码av在线观看| 亚洲无码一区二区在线观看| 女人的天堂AAA| 五月天福利影院| 青青操逼视频| 亚洲精品色色| 日韩成人一级片| 国产丨熟女丨国产熟女视频| 久久久久人| 国产一级a毛一级a毛视频在线网站) | 人妻无码| 91精品婷婷国产综合| 黄色影片在线观看| 4080yy午夜理论片成人| 99热免费精品| 91丨九色丨东北熟女| 人人操人人看人人干| 乱子伦国产精品www| 午夜激情视频网站| 精品蜜桃一区内容| 激情免费网站| 国产免费黄色电影| 日本人妻在线播放| 能看的AV网站| 高清色色女网站| 在线观看视频你懂的| jizz99| 嫩草A片www在线观看| 探花视频在线观看| 韩国AV三级| 蜜臀av在线免费观看| 神马午夜福利视频| 国内自拍欧美| 日韩中文字幕不卡| 亚洲另类av| 国产精品欧美一区二区三区苍井空| 亚洲口味重一级黄片| 就要干就要操| 亚洲日韩AV在线| 久久亚洲AV成人无码国产野外| 超碰人人草| 中文字幕精品久久久久人妻红杏Ⅰ | 日本爱爱免费视频| 免费的AV网站| 国产精品爽爽久久久久| 91白丝在线观看| 自拍乱伦| 国产精品探花熟女AV| 亚洲日韩免费观看| 国产精品乱码毛片在线人与| 国产3级片| 国产剧情一区二区av在线观看| 黑人精品欧美一区二区蜜桃| 老骚老B老太太A片| 人人看AV| 成人网站在线看| 中文字幕第11页| 在线一区二区三区| 在线观看视频亚洲| 亚洲精品字幕| 加勒比日韩| 午夜成人福利视频在线观看| 豆花天天吃最新视频| 亚洲综合一二三区| 国产99久久九九精品无码免费| 久久精品视频观看| 日韩高清在线播放| 性饥渴欧美老妇XXXXX| 日本高清无码视频| 噜噜色av| 亚洲精品乱码久久久久久蜜桃91| 夜夜撸夜夜操| 亚洲日韩中文字幕在线| 青青草在线观看视频| 91国产爽黄在线相亲| 西西4444大胆无码视频| 影音先锋成人| 欧美一区二区三区成人片在线| 久久99久久视频| 大黑人荫蒂BBBBBBBBB| 人人艹人人艹| 丁香五月欧美激情| 国产成人精品毛片| 久久草在线| 欧美日韩日逼视频| 人妻人人操| 五月丁香狠狠爱| 国产伦子伦一级A片免费看老牛| 亚洲无码一级| 无码人妻久久一区二区三区蜜桃| 青草免费视频| 欧美激情视频一区二区| 夏目あきら被续侵犯7天| 免费亚洲无码| 免费在线观看亚洲| 日韩A片一级无码免费蜜桃| 超碰人人操在线| 国产女人18毛片水真多18 | 九九九在线视频| 亚洲av黄| 伊人久久婷婷| 无码人妻一区二区三区免水牛视频| 亚洲AV秘一区二区色盗战流出| 人妻人人澡| 91原创国产内射| 日本一级按摩片免费观看| 日本在线精品视频| 国语偷拍| 国产AV自拍-久| 波多野成人无码精品视频| aV一区二区三区| 久久九九99| 日韩性爱视频在线观看| 久久a视频| 插丰满少妇在线观看| 少妇bbw搡bbbb搡bbbb| 激情白浆| 青青操国产乱伦| 大香蕉伊人av| 永久精品| 亚洲日韩精品在线视频| 亚洲AV成人无码| 最新无码在线| 国产精品777777| 伊人色女操穴综合网| 国产性爱网址| 91西安站街老熟女露脸| 国产又黄又大又粗| 无码人妻一区二区一牛影视| 日本久久视频| 波多野结衣无码AV专区| 久久婷婷五月| 三级片小说| 黄色免费在线网站| 七区九区一区在线| 好吊一区二区三区| 91在线看片| 欧美在线免费视频| 午夜成人精品一区二区三区| 久久精品亚洲| 中文字幕视频在线播放| 波多野吉衣高清无码| 操逼免费观看视频| 中文字幕福利电影| 天天草天天射| 亚欧三级| 欧美内射在线| 久久99精品久久久久| 97精品视频| 翔田千里一区二区| 天堂一区二区三区18| 精品精品精品| 亚洲欧美日韩不卡| 免费一级片| 欧美色图15P| 亚州视频在线| 色国产视频| 中国免费视频高清观看| 国产伦精品一区二区三区妓女| 四川婬妇BBw搡BBBB搡| 黄网站在线免费| 日本特黄视频| 国产精品毛片A√一区| 在线观看亚洲视频| 51毛片| 蜜臀精品一区二区三区| 亚洲天堂影音先锋| 国产黄色视频在线播放| 亚洲无码久久飞鱼网站| 日韩高清在线| 91在线播放视频| 在线观看免费无码| anwuye官方网站| 国产成人AV一区二区三区在线观看| 日韩成人在线看| 日韩激情在线观看| 中文字幕一区二区三区人妻在线视频 | 国产3区| 亚洲午夜av| 欧美黄色成人视频| 特级西西444www| 日色色色| 国产清纯可爱美女自卫裸贷偷情 | 波多野结衣91| 婷婷丁香六月天| 高清视频无码| 无码日韩成人| 欧美性猛交一区二区三区精品| 成人视频网站在线观看| 亚洲精品AⅤ一区二| 人人澡人人爱| 欧美一区二区三区精品| 日本久久精品18| 婷婷激情视频| 中文字幕在线乱| 国产av日韩av| 国产又粗又大又爽| 人妻懂色av粉嫩av浪潮av| 国产成人精品a视频| 天堂素人约啪| 日韩国产欧美精品一区| 欧美成人精品一区二区| www.伊人| 亚洲日本欧美| 17c精品麻豆一区二区免费| 极品AV| 日韩一区二区免费视频| 污视频在线看| 69AV无码| 日本高清无码视频| 国产在线免费视频| 影音先锋国产AV| 做爰视频毛片下载蜜桃视频| 黄片无码视频| 国产精品久久免费| 三级黄色免费网站| 欧美成人网站免费在线观看| 成人影视在线免费观看| 亚洲欧美日韩中文字幕在线观看| 91丨PORN首页| PORNY九色视频9l自拍| 操逼黄视频| 在线高清无码视频| 国产av日韩av| 91精品婷婷国产综合| 日本午夜无码| 噜噜噜久久久| 久热免费视频在线观看| 停停六综合| 日韩无码123| 日本一区二区三区在线播放 | 人人看,人人摸| 国产精品扒开腿做爽爽爽视频|