Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 性视频一区二区三区免费,中文字幕日韩精品中文区,日韩一级精品视频在线观看

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          你知道HTML、CSS、JS文件在瀏覽器中是如何轉(zhuǎn)化成頁面的嗎?

          前面一篇文章:「高頻面試題」瀏覽器從輸入url到頁面展示中間發(fā)生了什么 中,我們有對瀏覽器的渲染流程做了一個(gè)概括性的介紹,今天這篇文章我們將深入學(xué)習(xí)這部分內(nèi)容。

          對于很多前端開發(fā)來說,平常做工主要專注于業(yè)務(wù)開發(fā),對瀏覽器的渲染階段可能不是很了解。實(shí)際上這個(gè)階段很重要,了解瀏覽器的渲染過程,能讓我們知道我們寫的HTML、CSS、JS代碼是如何被解析,并最終渲染成一個(gè)頁面的,在頁面性能優(yōu)化的時(shí)候有相應(yīng)的解決思路。

          我們先來看一個(gè)問題:

          HTML、CSS、JS文件在瀏覽器中是如何轉(zhuǎn)化成頁面的?

          如果你回答不上來,那就往下看吧。

          按照渲染的時(shí)間順序,渲染過程可以分為下面幾個(gè)子階段:構(gòu)建DOM樹、樣式計(jì)算、布局階段、分層、柵格化和合成顯示。

          下面詳細(xì)看下每個(gè)階段都做了哪些事情。

          1. 構(gòu)建DOM樹

          HTML文檔描述一個(gè)頁面的結(jié)構(gòu),但是瀏覽器無法直接理解和使用HTML,所以需要通過HTML解析器將HTML轉(zhuǎn)換成瀏覽器能夠理解的結(jié)構(gòu)——DOM樹。

          HTML文檔中所有內(nèi)容皆為節(jié)點(diǎn),各節(jié)點(diǎn)之間有層級關(guān)系,彼此相連,構(gòu)成DOM樹。

          構(gòu)建過程:讀取HTML文檔的字節(jié)(Bytes),將字節(jié)轉(zhuǎn)換成字符(Chars),依據(jù)字符確定標(biāo)簽(Tokens),將標(biāo)簽轉(zhuǎn)換成節(jié)點(diǎn)(Nodes),以節(jié)點(diǎn)為基準(zhǔn)構(gòu)建DOM樹。參考下圖:

          打開Chrome的開發(fā)者工具,在控制臺(tái)輸入 document 后回車,就能看到一個(gè)完整的DOM樹結(jié)構(gòu),如下圖所示:

          在控制臺(tái)打印出來的DOM結(jié)構(gòu)和HTML內(nèi)容幾乎一樣,但和HTML不同的是,DOM是保存在內(nèi)存中的樹狀結(jié)構(gòu),可以通過JavaScript來查詢或修改其內(nèi)容。

          2. 樣式計(jì)算

          樣式計(jì)算這個(gè)階段,是為了計(jì)算出DOM節(jié)點(diǎn)中每個(gè)元素的表現(xiàn)樣式。

          2.1 解析CSS

          CSS樣式可以通過下面三種方式引入:

          • 通過link引用外部的CSS文件
          • style 標(biāo)簽內(nèi)的CSS
          • 元素的style屬性內(nèi)嵌的CSS

          和HTML一樣,瀏覽器無法直接理解純文本的CSS樣式,需要通過CSS解析器將CSS解析成 styleSheets 結(jié)構(gòu),也就是我們常說的 CSSOM樹

          styleSheets結(jié)構(gòu)同樣具備查詢和修改功能:

          document.styleSheets

          2.2 屬性值標(biāo)準(zhǔn)化

          屬性值標(biāo)準(zhǔn)化看字面意思有點(diǎn)不好理解,我們通過下面一個(gè)例子來看看什么是屬性值標(biāo)準(zhǔn)化:

          在寫CSS樣式的時(shí)候,我們在設(shè)置color屬性值的時(shí)候,經(jīng)常會(huì)用white、red等,但是這種值瀏覽器的渲染引擎不容易理解,所以需要將所有值轉(zhuǎn)換成渲染引擎容易理解的、標(biāo)準(zhǔn)化的計(jì)算值,這個(gè)過程就是屬性值標(biāo)準(zhǔn)化。

          white標(biāo)準(zhǔn)化后的值為 rgb(255, 255, 255)

          2.3 計(jì)算DOM樹中每個(gè)節(jié)點(diǎn)的樣式

          完成樣式的屬性值標(biāo)準(zhǔn)化后,就需要計(jì)算每個(gè)節(jié)點(diǎn)的樣式屬性,這個(gè)階段CSS有兩個(gè)規(guī)則我們需要清楚:

          • 繼承規(guī)則:每個(gè)DOM節(jié)點(diǎn)都包含有父節(jié)點(diǎn)的樣式
          • 層疊規(guī)則:層疊是CSS的一個(gè)基本特征,是一個(gè)定義了如何合并來自多個(gè)源的屬性值的算法。

          樣式計(jì)算階段是為了計(jì)算出DOM節(jié)點(diǎn)中每個(gè)元素的具體樣式,在計(jì)算過程中需要遵守CSS的繼承和層疊兩個(gè)規(guī)則。

          該階段最終輸出的內(nèi)容是每個(gè)DOM節(jié)點(diǎn)的樣式,并被保存在 ComputedStyle 的結(jié)構(gòu)中。

          3. 布局階段

          經(jīng)過上面的兩個(gè)步驟,我們已經(jīng)拿到了DOM樹和DOM樹中元素的樣式,接下來需要計(jì)算DOM樹中可見元素的幾何位置,這個(gè)計(jì)算過程就是布局。

          3.1 創(chuàng)建布局樹

          在DOM樹中包含了一些不可見的元素,例如 head 標(biāo)簽,設(shè)置了 display:none 屬性的元素,所以我們需要額外構(gòu)建一棵只包含可見元素的布局樹。

          構(gòu)建過程:從DOM樹的根節(jié)點(diǎn)開始遍歷,將所有可見的節(jié)點(diǎn)加到布局樹中,忽略不可見的節(jié)點(diǎn)。

          3.2 布局計(jì)算

          到這里我們就有了一棵構(gòu)建好的布局樹,就可以開始計(jì)算布局樹節(jié)點(diǎn)的坐標(biāo)位置了。從根節(jié)點(diǎn)開始遍歷,結(jié)合上面計(jì)算得到的樣式,確定每個(gè)節(jié)點(diǎn)對象在頁面上的具體大小和位置,將這些信息保存在布局樹中。

          布局階段的輸出是一個(gè)盒子模型,它會(huì)精確地捕獲每個(gè)元素在屏幕內(nèi)的確切位置與大小。

          4. 分層

          現(xiàn)在我們已經(jīng)有了布局樹,也知道了每個(gè)元素的具體位置信息,但是還不能開始繪制頁面,因?yàn)轫撁嬷袝?huì)有像3D變換、頁面滾動(dòng)、或者用 z-index 進(jìn)行z軸排序等復(fù)雜效果,為了更方便實(shí)現(xiàn)這些效果,渲染引擎還需要為特定的節(jié)點(diǎn)生成專用的圖層,并生成一棵對應(yīng)的圖層樹(LayerTree)。

          在Chrome瀏覽器中,我們可以打開開發(fā)者工具,選擇 Elements-Layers 標(biāo)簽,就可以看到頁面的分層情況,如下圖所示:

          瀏覽器的頁面實(shí)際上被分成了很多圖層,這些圖層疊加后合成了最終的頁面。

          到這里,我們構(gòu)建了兩棵樹:布局樹和圖層樹。下面我們來看下這兩棵樹之間的關(guān)系:

          正常情況下,并不是布局樹的每個(gè)節(jié)點(diǎn)都包含一個(gè)圖層,如果一個(gè)節(jié)點(diǎn)沒有對應(yīng)的圖層,那么這個(gè)節(jié)點(diǎn)就從屬于父節(jié)點(diǎn)的圖層。

          那節(jié)點(diǎn)要滿足什么條件才會(huì)被提升為一個(gè)單獨(dú)的圖層?只要滿足下面其中一個(gè)條件即可:

          • 擁有層疊上下文屬性的元素會(huì)被提升為單獨(dú)的一個(gè)圖層
          • 需要剪裁(clip)的地方也會(huì)被創(chuàng)建為圖層。

          5. 圖層繪制

          構(gòu)建好圖層樹之后,渲染引擎就會(huì)對圖層樹中的每個(gè)圖層進(jìn)行繪制。

          渲染引擎實(shí)現(xiàn)圖層繪制,會(huì)把一個(gè)圖層的繪制拆分成很多小的繪制指令,然后將這些指令按照順序組成一個(gè)繪制列表。

          6. 柵格化(raster)操作

          繪制一個(gè)圖層時(shí)會(huì)生成一個(gè)繪制列表,這只是用來記錄繪制順序和繪制指令的列表,實(shí)際上繪制操作是由渲染引擎中的合成線程來完成的。

          通過下圖來看下渲染主線程和合成線程之間的關(guān)系:

          當(dāng)圖層的繪制列表準(zhǔn)備好后,主線程會(huì)把該繪制列表提交給合成線程,合成線程開始工作。

          首先合成線程會(huì)將圖層劃分為圖塊(tile),圖塊大小通常是 256256 或者 512512。

          然后合成線程會(huì)按照視口附近的圖塊來優(yōu)先生成位圖,實(shí)際生成位圖的操作是由柵格化來執(zhí)行的。所謂柵格化,是指將圖塊轉(zhuǎn)換為位圖。而圖塊是柵格化執(zhí)行的最小單位。渲染進(jìn)程維護(hù)了一個(gè)柵格化的線程池,所有的圖塊柵格化都是在線程池內(nèi)執(zhí)行的,運(yùn)行方式如下圖所示:

          7. 合成和顯示

          一旦所有圖塊都被光柵化,合成線程就會(huì)生成一個(gè)繪制圖塊的命令——“DrawQuad”,然后將該命令提交給瀏覽器進(jìn)程。

          瀏覽器進(jìn)程里面有一個(gè)名字叫做 viz 的組件,用來接收合成線程發(fā)過來的 DrawQuad 命令,然后根據(jù)命令執(zhí)行。 DrawQuad 命令,將其頁面內(nèi)容繪制到內(nèi)存中,最后再將內(nèi)存顯示在屏幕上。

          多年開發(fā)老碼農(nóng)福利贈(zèng)送:網(wǎng)頁制作,網(wǎng)站開發(fā),web前端開發(fā),從最零基礎(chǔ)開始的的HTML+CSS+JavaScript。jQuery,Vue、React、Ajax,node,angular框架等到移動(dòng)端小程序項(xiàng)目實(shí)戰(zhàn)【視頻+工具+電子書+系統(tǒng)路線圖】都有整理,需要的伙伴可以私信我,發(fā)送“前端”等3秒后就可以獲取領(lǐng)取地址,送給每一位對編程感興趣的小伙伴

          8. 總結(jié)

          一個(gè)完整的渲染流程可以總結(jié)如下:

          • 1、渲染進(jìn)程將HTML內(nèi)容轉(zhuǎn)換為瀏覽器能夠讀懂的DOM樹結(jié)構(gòu)。
          • 2、渲染引擎將CSS樣式表轉(zhuǎn)化為瀏覽器可以理解的styleSheets,計(jì)算出DOM節(jié)點(diǎn)的樣式。
          • 3、創(chuàng)建布局樹,并計(jì)算所需元素的布局信息。
          • 4、對布局樹進(jìn)行分層,并生成分層樹。
          • 5、為每個(gè)圖層生成繪制列表,并將其提交到合成線程。
          • 6、合成線程將圖層分圖塊,并柵格化將圖塊轉(zhuǎn)換成位圖。
          • 7、合成線程發(fā)送繪制圖塊命令給瀏覽器進(jìn)程。瀏覽器進(jìn)程根據(jù)指令生成頁面,并顯示到顯示器上。

          渲染過程中還有兩個(gè)我們經(jīng)常聽到的概念:重排和重繪。在這篇文章中就不細(xì)說了,下一篇文章再詳細(xì)介紹。

          家好,很高興又見面了,我是"高級前端?進(jìn)階?",由我?guī)е蠹乙黄痍P(guān)注前端前沿、深入前端底層技術(shù),大家一起進(jìn)步,也歡迎大家關(guān)注、點(diǎn)贊、收藏、轉(zhuǎn)發(fā)!

          高級前端?進(jìn)階

          前言

          本文主要和大家介紹將 JavaScript 轉(zhuǎn)化為 WebAssembly的工具鏈 javy。在年初,我也確實(shí)使用 WebAssembly 將客戶端應(yīng)用成功移植到了 Web,這也是為什么我一直對 WebAssembly 充滿好奇的原因。我甚至在頭條上開了一個(gè)合集《WebAssembly 前沿技術(shù)》來專門探討 WebAssembly ,并將持續(xù)關(guān)注 WebAssembly 的最新動(dòng)態(tài)。

          下面是已發(fā)布部分文章傳送門:

          • 《 2023 年讓 WebAssembly 大火的 10+應(yīng)用!》
          • 《 萬字長文!2023 年 WebAssembly 各個(gè)運(yùn)行時(shí)性能對比!》
          • 《 讓 JavaScript 在 WebAssembly 上加速運(yùn)行!》

          正如大家所看到的,當(dāng)我們還在遲疑是否要在日常開發(fā)中引入 WebAssembly 的時(shí)候,很多優(yōu)秀的應(yīng)用、工具已經(jīng)開始吃 WebAssembly 的紅利了,而且取得了不錯(cuò)的成就,這可能也是為什么各個(gè)瀏覽器廠商、開發(fā)者如此熱衷 WebAssembly 的原因吧。

          WebAssembly 中的 JavaScript 是最近技術(shù)圈發(fā)展的產(chǎn)物,但是將 JavaScript 編譯成 WebAssembly 不同于使用 JavaScript 與 WebAssembly 模塊通信。本文重點(diǎn)介紹如何獲取 JavaScript 代碼并將其構(gòu)建到 WebAssembly 模塊中。

          話不多說,直接開始進(jìn)入正題!

          1.如何將 JavaScript 編譯為 WebAssembly

          1.1 構(gòu)建環(huán)境準(zhǔn)備

          • rustup
          • 穩(wěn)定的 Rust 環(huán)境(rustup install stable && rustup default stable)
          • wasm32-wasi,可以通過 rustup target add wasm32-wasi 安裝
          • cmake,根據(jù)操作系統(tǒng)和體系結(jié)構(gòu),默認(rèn)情況下可能不會(huì)安裝它。 在 Mac 上,可以通過 brew install cmake 與 homebrew 一起安裝
          • Rosetta 2 如果在 Apple Silicon 上運(yùn)行 MacOS,可以通過 softwareupdate --install-rosetta 安裝
          • 通過運(yùn)行 make download-wasi-sdk 安裝 wasi-sdk

          1.2 開發(fā)環(huán)境準(zhǔn)備

          • wasmtime-cli,可以通過 cargo install wasmtime-cli 安裝(cargo-wasi 需要)
          • cargo-wasi,可以通過 cargo install cargo-wasi
          • 安裝 wizer,可以通過 cargo install wizer --all-features 安裝

          1.3 開始使用 Javy

          安裝所有依賴項(xiàng)后運(yùn)行 make,現(xiàn)在應(yīng)該可以訪問 target/release/javy 中的可執(zhí)行文件。或者可以運(yùn)行 make && cargo install --path crates/cli, 運(yùn)行命令后,將獲得可執(zhí)行文件的全局安裝。

          Javy 底層基于 QuickJS, 用于在 WebAssembly 上運(yùn)行 JavaScript 代碼。 Javy 獲取 JavaScript 代碼,并在 WebAssembly 嵌入式 JavaScript 運(yùn)行時(shí)中執(zhí)行它。下面是官方對 Javy 的定位:

          Javy: A JavaScript to WebAssembly toolchain

          Javy 生成的模塊僅設(shè)計(jì)為 WASI 并遵循命令模式, 任何輸入都必須通過 stdin 傳遞,任何輸出都將放在 stdout 中,這在從自定義嵌入調(diào)用 Javy 模塊時(shí)尤為重要。

          在像 Wasmtime 這樣的運(yùn)行時(shí)中,wasmtime-wasi 可用于設(shè)置輸入和檢索輸出。比如下面的 JS 代碼:

          //從標(biāo)準(zhǔn)輸入讀取輸入
          const input = readInput();
          //使用輸入調(diào)用函數(shù)
          const result = foo(input);
          // 將結(jié)果寫入標(biāo)準(zhǔn)輸出
          writeOutput(result);
          // 入口函數(shù)
          function foo(input) {
            return { foo: input.n + 1, newBar: input.bar + '!' };
          }
          // Read input from stdin
          function readInput() {
            const chunkSize = 1024;
            const inputChunks = [];
            let totalBytes = 0;
          
            //讀取所有可用字節(jié)
            while (1) {
              const buffer = new Uint8Array(chunkSize);
              // 標(biāo)準(zhǔn)輸入文件描述符
              const fd = 0;
              const bytesRead = Javy.IO.readSync(fd, buffer);
              totalBytes += bytesRead;
              if (bytesRead === 0) {
                break;
              }
              inputChunks.push(buffer.subarray(0, bytesRead));
            }
            // 將輸入組裝成單個(gè) Uint8Array
            const { finalBuffer } = inputChunks.reduce(
              (context, chunk) => {
                context.finalBuffer.set(chunk, context.bufferOffset);
                context.bufferOffset += chunk.length;
                return context;
              },
              { bufferOffset: 0, finalBuffer: new Uint8Array(totalBytes) }
            );
            return JSON.parse(new TextDecoder().decode(finalBuffer));
          }
          //將輸出寫入標(biāo)準(zhǔn)輸出
          function writeOutput(output) {
            const encodedOutput = new TextEncoder().encode(JSON.stringify(output));
            const buffer = new Uint8Array(encodedOutput);
            // 標(biāo)準(zhǔn)輸出文件描述符
            const fd = 1;
            Javy.IO.writeSync(fd, buffer);
          }

          通過以下方式從 JavaScript 創(chuàng)建 WebAssembly 二進(jìn)制文件:

          javy compile index.js -o destination/index.wasm

          然后,可以使用 WebAssembly 引擎執(zhí)行 WebAssembly 二進(jìn)制文件:

          $ echo '{ "n": 2, "bar": "baz" }' | wasmtime index.wasm
          {"foo":3,"newBar":"baz!"}%

          2. 創(chuàng)建和使用動(dòng)態(tài)鏈接模塊

          在某些情況下,開發(fā)者可能希望或需要使用 Javy 生成更小的 Wasm 模塊。 在調(diào)用 Javy 時(shí)使用 -d 標(biāo)志將創(chuàng)建一個(gè)動(dòng)態(tài)鏈接模塊,該模塊的文件大小比靜態(tài)鏈接模塊小得多。 靜態(tài)鏈接模塊將 JS 引擎嵌入模塊內(nèi)部,而動(dòng)態(tài)鏈接模塊依賴 Wasm 導(dǎo)入來提供 JS 引擎。 動(dòng)態(tài)鏈接模塊有特殊要求,靜態(tài)鏈接模塊沒有也不會(huì)在不滿足這些要求的 WebAssembly 運(yùn)行時(shí)中執(zhí)行

          要成功實(shí)例化和運(yùn)行動(dòng)態(tài)鏈接的 Javy 模塊,執(zhí)行環(huán)境必須提供一個(gè) javy_quickjs_provider_v1 命名空間,用于導(dǎo)入該鏈接到 javy_quickjs_provider.wasm 模塊提供的導(dǎo)出。 在不提供此導(dǎo)入的環(huán)境中無法實(shí)例化動(dòng)態(tài)鏈接的模塊。

          動(dòng)態(tài)鏈接的 Javy 模塊與 QuickJS 綁定,因?yàn)樗鼈兪褂?QuickJS 的字節(jié)碼表示。

          javy_quickjs_provider.wasm 模塊在使用的 Javy 版本中作為資產(chǎn)提供,也可以通過運(yùn)行 javy emit-provider -o <path> 將模塊寫入 <path> 來獲取。

          $ echo 'console.log("hello world!");' > my_code.js
          $ javy compile -d -o my_code.wasm my_code.js
          $ javy emit-provider -o provider.wasm
          $ wasmtime run --preload javy_quickjs_provider_v1=provider.wasm my_code.wasm
          hello world!

          3.使用 quickjs-wasm-rs 構(gòu)建自己的工具鏈

          作為該項(xiàng)目一部分的 quickjs-wasm-rs crate 可以用作針對 Wasm 的 Rust crate 的一部分,以自定義 Rust crate 如何與 QuickJS 交互。

          當(dāng)嘗試在 Wasm 模塊中使用 JavaScript 而 Javy 不滿足您的需求時(shí),這可能很有用,因?yàn)?quickjs-wasm-rs 包含序列化程序,可以更輕松地在主機(jī)代碼和 Wasm 代碼之間發(fā)送結(jié)構(gòu)化數(shù)據(jù)(例如,字符串或?qū)ο螅?/span>

          4.其他相關(guān)討論

          • 《知乎:JavaScript 能不能編譯成 WebAssembly ?》
          • 《使用 Javy 和 msgpack-tools 將 JavaScript 編譯為 WebAssembly》
          • 《讓 JavaScript 在 WebAssembly 上加速運(yùn)行!》

          5.本文總結(jié)

          本文主要和大家介紹將 JavaScript 轉(zhuǎn)化為 WebAssembly的工具鏈 javy。因?yàn)槠邢蓿恼虏]有過多展開,如果有興趣,可以在我的主頁繼續(xù)閱讀,同時(shí)文末的參考資料提供了大量優(yōu)秀文檔以供學(xué)習(xí)。最后,歡迎大家點(diǎn)贊、評論、轉(zhuǎn)發(fā)、收藏!


          參考資料

          https://www.fermyon.com/wasm-languages/javascript

          https://blog.csdn.net/tzllxya/article/details/90675984

          https://github.com/Shopify/javy

          https://www.wasm.builders/gunjan_0307/compiling-javascript-to-wasm-34lk

          https://surma.dev/things/compile-js/

          https://www.wasm.builders/deepanshu1484/javascript-and-wasi-24k8

          https://github.com/ludocode/msgpack-tools

          https://www.linkedin.com/pulse/differences-between-static-dynamic-libraries-sergio-monroy

          封面圖:Navdeep Singh Gill | 13 October 2022的《WebAssembly vs JavaScript | The Ultimate Guide》

          我們在網(wǎng)上發(fā)現(xiàn)一篇好文章的時(shí)候,將網(wǎng)頁下載到了桌面,但是為了方便編輯,想要將其轉(zhuǎn)換一下格式,如Word格式。網(wǎng)頁轉(zhuǎn)換成Word文檔怎么做?其實(shí)很多朋友們都想要知道,下面小編就來告訴大家。



          針對網(wǎng)頁轉(zhuǎn)換成Word文檔怎么做這個(gè)話題,下面小編以WPS2019為例給大家分享步驟:

          第一步:打開WPS軟件,然后在菜單欄里點(diǎn)擊“文件”,然后在下拉菜單選擇“打開”:


          第二步:在打開的對話框中,我們點(diǎn)擊下面“文件類型”旁邊下拉列表,選擇“網(wǎng)頁文件(*.html;*.htm)”:


          第三步:找到目標(biāo)文件,并點(diǎn)擊打開:


          第三步:選擇菜單欄“文件”,然后點(diǎn)擊下拉菜單“另存為”。在“文件類型”里選擇Word格式,然后點(diǎn)擊保存即可轉(zhuǎn)換完畢:


          看完上面的介紹,相信朋友們對于網(wǎng)頁轉(zhuǎn)換成Word文檔怎么做都會(huì)有所了解。這個(gè)操作是比較實(shí)用的,大家可以多學(xué)習(xí)一下。


          主站蜘蛛池模板: 国产精品久久久久久麻豆一区| 亚洲欧洲一区二区三区| 亚洲综合一区国产精品| 精品中文字幕一区二区三区四区| 爆乳熟妇一区二区三区| 国产成人av一区二区三区不卡| 色一乱一伦一图一区二区精品| 国产欧美色一区二区三区| 国产福利微拍精品一区二区| 精品国产AⅤ一区二区三区4区 | 国产精品亚洲一区二区三区在线观看 | 久久久精品一区二区三区 | 国产福利一区二区三区在线观看 | 亚洲综合国产一区二区三区| 精品人妻一区二区三区四区在线| 在线电影一区二区三区| 亚洲av无码一区二区三区四区| 亚洲制服丝袜一区二区三区 | 免费高清av一区二区三区| 亚洲综合一区二区| 少妇精品久久久一区二区三区| 国产一区二区三区高清在线观看 | 一区二区三区在线免费| 国产精品一区二区三区99 | 国产免费一区二区三区| 国产对白精品刺激一区二区| 一区二区精品在线| 亚洲一区二区女搞男| 亚洲福利视频一区| 亚洲制服丝袜一区二区三区| 久久久久人妻一区精品性色av| 天堂Aⅴ无码一区二区三区| 鲁丝片一区二区三区免费| 色欲精品国产一区二区三区AV| 亚洲日本一区二区| 亚洲av无一区二区三区| 男插女高潮一区二区| 国产精品一区二区无线| 亚洲福利精品一区二区三区| 中文字幕一区日韩在线视频| 无码人妻精品一区二区三区66 |