国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

一篇文章理解虛擬滾動(dòng)原理

這篇具有很好參考價(jià)值的文章主要介紹了一篇文章理解虛擬滾動(dòng)原理。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

1.為什么使用虛擬滾動(dòng)?

首先提到一個(gè)現(xiàn)象,前端的性能瓶頸那就是頁(yè)面的卡頓,當(dāng)然這種頁(yè)面的卡頓包含了多種原因。例如HTTP請(qǐng)求過(guò)多導(dǎo)致數(shù)據(jù)加載國(guó)漫,下載的靜態(tài)文件非常大導(dǎo)致頁(yè)面加載時(shí)間很長(zhǎng),js中一些算法響應(yīng)的時(shí)間過(guò)長(zhǎng)等。很多前端工程師都花費(fèi)很多的精力在dom渲染上來(lái)優(yōu)化頁(yè)面加載。

2.瀏覽器渲染原理

在我們討論今天的這個(gè)虛擬滾動(dòng)原理之前需要了解一下瀏覽器的渲染原理。

瀏覽器渲染頁(yè)面的過(guò)程分為以下幾步:

  1. 解析html文件并生成 Dom Tree。

  1. CSS解析生成CSS Rule Tree。

  1. 在渲染階段,瀏覽器會(huì)把DOM TreeCSS Rule TreeDOM Tree上的每個(gè)節(jié)點(diǎn)添加樣式,并生成Render Tree。

  1. Render Tree(layout/reflow),繪制元素尺寸、位置計(jì)算。

  1. 將計(jì)算好的信息發(fā)給GPU并顯示在頁(yè)面。

具體的瀏覽器原理在這篇文章不做過(guò)多的介紹,有興趣的話(huà)可以去看我的另一篇文章《一篇文章理解瀏覽器渲染原理和機(jī)制》。

3.瀏覽器渲染瓶頸

首先大家要明重繪回流(重排)的概念:

  • 重繪(repaint):當(dāng)Render Tree 中的一些元素需要更新元素本身的屬性,只影響外觀樣式和顏色等,不影響整個(gè)布局。

  • 回流(reflow):當(dāng)Render Tree 中的某些元素因?yàn)橐?guī)模、尺寸、位置等改變時(shí),會(huì)影響整個(gè)布局。

回流必定發(fā)生重繪重繪不一定發(fā)生回流,所以大家可以知道,回流所造成的影響是比較大的,如果頁(yè)面中頻繁的觸發(fā)回流的操作,那么最終造成頁(yè)面卡頓也是肯定的。

造成回流和重繪的操作有以下類(lèi)別:

  • 頁(yè)面初始化

  • 添加或者刪除頁(yè)面上的可視區(qū)DOM元素

  • 元素位置發(fā)生改變,定位和浮動(dòng),盒模型

  • 頁(yè)面文本內(nèi)容發(fā)生變化,影響輸入框的大小改變。

  • 圖片顯示加載,如果沒(méi)有加載圖片又會(huì)被替換成相應(yīng)提示文字信息。

  • 瀏覽器窗口尺寸大小變化(回流是根據(jù)視口大小來(lái)計(jì)算頁(yè)面元素的位置和大小)。

其實(shí)對(duì)于這些需要考慮的因素,一些瀏覽器也是做出了相應(yīng)的處理,因?yàn)槊看位亓骺赡軙?huì)造成巨大的影響,瀏覽器本身會(huì)實(shí)現(xiàn)一個(gè)隊(duì)列記錄每次回流時(shí)操作,當(dāng)存放的操作數(shù)量達(dá)到一定值或者達(dá)到一定時(shí)間后會(huì)對(duì)隊(duì)列中的操作進(jìn)行清空,并一次性進(jìn)行一次回流,讓多次回流操作壓縮成一次回流操作執(zhí)行,提高效率。

本文章將著重講述關(guān)于滾動(dòng)事件scroll event造成的影響。滾動(dòng)事件本身不會(huì)造成太多的性能消耗,而是因?yàn)闈L動(dòng)事件伴隨有大量的元素參與進(jìn)來(lái)一起進(jìn)行回流的操作才會(huì)影響瀏覽器的性能。例如一個(gè)表格有上萬(wàn)行數(shù)據(jù),如果一次性展示在頁(yè)面中,并且在滾動(dòng)時(shí)顯示對(duì)應(yīng)偏移的數(shù)據(jù),那么每一次滾動(dòng)都會(huì)對(duì)這幾萬(wàn)個(gè)元素進(jìn)行回流,那么性能肯定會(huì)很差。

瀏覽器的瓶頸主要在于:

1.無(wú)法一次性渲染太多的DOM元素。

2.每次滾動(dòng)事件將會(huì)讓對(duì)應(yīng)的DOM中所有元素重新渲染。

針對(duì)于瀏覽器的瓶頸問(wèn)題,有三種解決辦法:數(shù)據(jù)分頁(yè)、無(wú)限滾動(dòng)、虛擬滾動(dòng)。

4.數(shù)據(jù)分頁(yè)

許多網(wǎng)頁(yè)和應(yīng)用程序都會(huì)用到這樣的方,對(duì)需要展示的大量數(shù)據(jù)進(jìn)行分割分頁(yè),后端已經(jīng)做好了分頁(yè),前端只需要調(diào)用后端的接口傳入相應(yīng)的第幾頁(yè)的參數(shù)就能獲取到,減少了一次性需要渲染的行數(shù),但是如果查詢(xún)的表列數(shù)非常多,還是可能會(huì)渲染很多元素,不是一個(gè)很穩(wěn)定的方法。

5.無(wú)限滾動(dòng)

該方法是在頁(yè)面渲染一次性所能成手最大范圍的數(shù)據(jù)量,當(dāng)滾動(dòng)條快接近底部時(shí),再去追加渲染下一批需要渲染的元素,但是該方法的明顯缺血在于,如果數(shù)據(jù)量過(guò)大,無(wú)限滾動(dòng)下去那么最終所造成渲染的元素越來(lái)越多,性能也不會(huì)很好。

6.虛擬滾動(dòng)

虛擬滾動(dòng)其實(shí)就是綜合數(shù)據(jù)分頁(yè)和無(wú)限滾動(dòng)的方法,在有限的視口中只渲染我們所能看到的數(shù)據(jù),超出視口之外的數(shù)據(jù)就不進(jìn)行渲染,可以通過(guò)計(jì)算可視范圍內(nèi)的但單元格,保證每一次滾動(dòng)渲染的DOM元素都是可以控制的,不會(huì)擔(dān)心像數(shù)據(jù)分頁(yè)一樣一次性渲染過(guò)多,也不會(huì)發(fā)生像無(wú)限滾動(dòng)方案那樣會(huì)存在數(shù)據(jù)堆積,是一種很好的解決辦法。

假設(shè)實(shí)際開(kāi)發(fā)中服務(wù)端一次響應(yīng)20萬(wàn)條列表數(shù)據(jù),此時(shí)設(shè)備屏幕只允許容納20條,那么用戶(hù)理論上只可以看見(jiàn)20條數(shù)據(jù),其他的數(shù)據(jù)不會(huì)進(jìn)行渲染加載。如果前端將20萬(wàn)條數(shù)據(jù)全部渲染成DOM元素,可能造成程序卡頓,占用較大資源,非常影響用戶(hù)體驗(yàn),那么虛擬滾動(dòng)技術(shù)就完美的解決了這一問(wèn)題。

一篇文章理解虛擬滾動(dòng)原理

如圖所示,當(dāng)我們進(jìn)行滾動(dòng)時(shí),可視區(qū)域大小不變,渲染的元素?cái)?shù)量也是可以控制的,合理的減少了不必要的DOM渲染,提高瀏覽器的性能。

可以計(jì)算:卷入行數(shù) = scrollTop(卷入高度) / 每行的高度(itemH)

黃色邊框內(nèi)為可視區(qū)域,可視區(qū)域內(nèi)的紅色行表示在頁(yè)面能展示的數(shù)據(jù),每次滾動(dòng)時(shí),計(jì)算scrollTop的值,可視區(qū)域內(nèi)的紅色渲染部分高度可以略大于黃色邊框可是高度,避免滾動(dòng)的時(shí)候直接替換。

如何計(jì)算可視區(qū)域渲染的元素以及實(shí)現(xiàn)虛擬滾動(dòng),步驟如下:

  • 統(tǒng)一設(shè)置每一行的高度需要相同,方便計(jì)算。

  • 需要計(jì)算渲染數(shù)據(jù)數(shù)量(數(shù)組的長(zhǎng)度),根據(jù)每行的高度以及元素的總量計(jì)算整個(gè)DOM渲染容器的高度。

  • 獲取可視區(qū)域的高度

  • 觸發(fā)滾動(dòng)事件后,計(jì)算偏移量(滾動(dòng)條據(jù)頂距離),再根據(jù)可視區(qū)域高度計(jì)算本次偏移的截止量,得到需要渲染的具體數(shù)據(jù)。

  • 對(duì)于與表格的列來(lái)說(shuō),需要做虛擬滾動(dòng)的話(huà),在x軸同樣可以根據(jù)以上步驟執(zhí)行,實(shí)現(xiàn)橫向虛擬滾動(dòng)。

7.自定義封裝一個(gè)虛擬滾動(dòng)組件:

子組件:

<template>
  <!-- 可視區(qū)盒子 -->
  <div :style="`height:${viewH}px;overflow-y:scroll`"
       @scroll="handleScroll"
       class="container">
    <div :style="`height:${scrollH}px`"
         class="list">
      <div class="item_box"
           :style="`transform:translateY(${offsetY}px)`">
        <div class="item"
             :style="`height:${itemH}px`"
             v-for="(item,index) in list"
             :key="index">
          {{ item }}
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ScrollComponent',
  props: {
    data: Array,   // 列表總數(shù)據(jù)
    viewH: Number, // 外部高度
    itemH: Number, // 單項(xiàng)高度
  },
  data () {
    return {
      scrollH: '', // 整個(gè)滾動(dòng)列表高度(總高度)
      list: [],    // 每次顯示的數(shù)據(jù)
      showNum: '', // 頁(yè)面需要顯示的數(shù)量
      offsetY: '',// 動(dòng)態(tài)偏移量- 外層的盒子進(jìn)行滾動(dòng)設(shè)置
      lastTime: '', //最新的時(shí)間
    }
  },
  mounted () {
    // 初始化計(jì)算
    this.scrollH = this.data.length * this.itemH
    // 計(jì)算可視化高度中能存幾個(gè)列表,可以略多余可視化高度能存放的列表數(shù)量避免滾動(dòng)時(shí)被替換
    this.showNum = Math.floor(this.viewH / this.itemH) + 1
    // 默認(rèn)展示的幾個(gè)數(shù)據(jù)
    this.list = this.data.slice(0, this.showNum)
    this.lastTime = new Date().getTime()
  },
  methods: {
    // handleScroll 滾動(dòng)時(shí)候觸發(fā)回調(diào)
    handleScroll (e) {
      // 控制滾動(dòng)時(shí)間間隔
      if (new Date().getTime() - this.lastTime > 10) {
        let scrollTop = e.target.scrollTop //滾動(dòng)條高度
        // 每一次滾動(dòng)后 根據(jù)scrollTop值獲取一個(gè)可以整除itemH結(jié)果進(jìn)行偏移
        // 例如:scrollTop = 1220,1220 % this.itemH = 20 offsetY = 1220-20 = 1200
        this.offsetY = scrollTop - (scrollTop % this.itemH)
        console.log('卷入scrollTop值:', scrollTop, '卷入的行數(shù):', scrollTop % this.itemH);
        this.list = this.data.slice(
          Math.floor(scrollTop / this.itemH), // 計(jì)算卷入了多少行
          Math.floor(scrollTop / this.itemH) + this.showNum
        )
        this.lastTime = new Date().getTime() //更新最新時(shí)間
      }
    }
  }
}
</script>

<style scoped>
.container {
  position: relative;
  top: 200px;
  left: 500px;
  border: 1px solid red;
  width: 500px;
}
.item {
  border: 1px solid pink;
}
</style>

?

父組件:

<template>
  <div id="app">
    <ScrollComponent :data="dataList"
                     :viewH="viewH"
                     :itemH="itemH" />
  </div>
</template>

<script>
import ScrollComponent from './components/ScrollComponent.vue'

export default {
  name: 'App',
  components: {
    ScrollComponent
  },
  data () {
    return {
      dataList: [1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1],
      viewH: 200,
      itemH: 40
    }
  },
  mounted () {

  }
}
</script>

<style>
* {
  margin: 0;
  padding: 0;
}
</style>

?

瀏覽器顯示結(jié)果:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-452332.html

一篇文章理解虛擬滾動(dòng)原理

到了這里,關(guān)于一篇文章理解虛擬滾動(dòng)原理的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Java】還不理解繼承?一篇文章看懂繼承|繼承入門(mén)

    【Java】還不理解繼承?一篇文章看懂繼承|繼承入門(mén)

    作者: 努力學(xué)習(xí)的大一在校計(jì)算機(jī)專(zhuān)業(yè)學(xué)生,熱愛(ài)學(xué)習(xí)和創(chuàng)作。目前在學(xué)習(xí)和分享:算法、數(shù)據(jù)結(jié)構(gòu)、Java等相關(guān)知識(shí)。 博主主頁(yè): @是瑤瑤子啦 所屬專(zhuān)欄: Java島冒險(xiǎn)記【從小白到大佬之路】;該專(zhuān)欄專(zhuān)注于Java相關(guān)知識(shí),持續(xù)更新,每一篇內(nèi)容優(yōu)質(zhì),淺顯易懂,不失深度!

    2024年02月01日
    瀏覽(23)
  • C++初階之一篇文章讓你掌握vector(理解和使用)

    C++初階之一篇文章讓你掌握vector(理解和使用)

    在C++中,std::vector是標(biāo)準(zhǔn)模板庫(kù)(STL)中的一種動(dòng)態(tài)數(shù)組容器,它可以存儲(chǔ)任意類(lèi)型的元素,并且能夠自動(dòng)調(diào)整大小。std::vector提供了許多方便的成員函數(shù),使得對(duì)數(shù)組的操作更加簡(jiǎn)單和高效。 vector聲明 : template class T, class Alloc = allocatorT ; 這是 std::vector 的一般模板定義。它

    2024年02月14日
    瀏覽(29)
  • MapReduce的工作原理這篇文章就夠了

    MapReduce是一種分布式計(jì)算模型,用于處理大規(guī)模數(shù)據(jù)集。它將大規(guī)模數(shù)據(jù)集分成小的數(shù)據(jù)塊,然后在分布式計(jì)算集群上并行處理這些數(shù)據(jù)塊。MapReduce模型由Google公司提出,并在Hadoop等開(kāi)源框架中得到了廣泛應(yīng)用。 MapReduce模型包含兩個(gè)階段:Map階段和Reduce階段。 Map階段 在Map階

    2024年02月06日
    瀏覽(30)
  • 【無(wú)標(biāo)題】一篇文章帶你徹底理解Java ArrayList數(shù)據(jù)結(jié)構(gòu)詳解

    【無(wú)標(biāo)題】一篇文章帶你徹底理解Java ArrayList數(shù)據(jù)結(jié)構(gòu)詳解

    基本概念: ? **之前創(chuàng)建數(shù)組的時(shí)候,需要聲明提前聲明數(shù)組的大小,**ArrayList是一個(gè)可以動(dòng)態(tài)修改的數(shù)組,與普通數(shù)組的區(qū)別就是沒(méi)有固定大小的限制,它會(huì)動(dòng)態(tài)調(diào)整長(zhǎng)度。 ? **ArrayList繼承了AbstractList,并實(shí)現(xiàn)了List接口。**如下圖: **ArrayList 類(lèi)位于 java.util 包中,**使用前

    2024年02月14日
    瀏覽(28)
  • 一篇文章帶你了解-selenium工作原理詳解

    一篇文章帶你了解-selenium工作原理詳解

    前言 Selenium是一個(gè)用于Web應(yīng)用程序自動(dòng)化測(cè)試工具。Selenium測(cè)試直接運(yùn)行在瀏覽器中,就像真正的用戶(hù)在操作一樣。支持的瀏覽器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。 主要功能包括:測(cè)試與瀏覽器的兼容性——測(cè)試你的應(yīng)用程序看是否能夠很好得

    2024年02月10日
    瀏覽(26)
  • 一篇文章掌握WebService服務(wù)、工作原理、核心組件、主流框架

    目錄 1、WebService定義 解決問(wèn)題: 2、WebService的工作原理 2.1 實(shí)現(xiàn)一個(gè)完整的Web服務(wù)包括以下步驟 2.2 調(diào)用方式 3、Web Service的核心組件 3.1 XML 3.2 SOAP 3.3 WSDL 3.4 UDDI 4、主流框架 4.1 AXIS(已淘汰) 4.2 XFire 4.3 CXF 5、Soap協(xié)議詳解 1.Soap協(xié)議是什么 2.認(rèn)識(shí)Soap 3.結(jié)論 4.SOAP小總結(jié) 6、WSDL詳解

    2024年01月18日
    瀏覽(33)
  • RabbitMQ如何保證消息可靠性,看完這篇文章佬會(huì)有新的理解

    RabbitMQ如何保證消息可靠性,看完這篇文章佬會(huì)有新的理解

    前言:大家好,我是小威,24屆畢業(yè)生,在一家滿(mǎn)意的公司實(shí)習(xí)。本篇文章將詳細(xì)介紹RabbitMQ的消息可靠性機(jī)制,如消息丟失,消息重復(fù)性消費(fèi),消息積壓等問(wèn)題。 如果文章有什么需要改進(jìn)的地方還請(qǐng)大佬不吝賜教 ????。 小威在此先感謝各位大佬啦~~???? ??個(gè)人主頁(yè):小

    2024年02月03日
    瀏覽(29)
  • 一篇文章讓你徹底了解vuex的使用及原理(上)

    文章講解的 Vuex 的版本為 4.1.0 ,會(huì)根據(jù)一些 api 來(lái)深入源碼講解,幫助大家更快掌握 vuex 的使用。 使用 Vue 實(shí)例的 use 方法把 Vuex 實(shí)例注入到 Vue 實(shí)例中。 use 方法執(zhí)行的是插件的中的 install 方法 src/store.js 從上面可以看到 Vue 實(shí)例通過(guò) provide 方法把 store 實(shí)例 provide 到了根實(shí)例

    2023年04月23日
    瀏覽(27)
  • 一篇文章帶你從入門(mén)都入土 Kafka 消息中間件(原理+代碼)

    一篇文章帶你從入門(mén)都入土 Kafka 消息中間件(原理+代碼)

    目錄 一、Kafka定義 二、消息隊(duì)列 三、Kafka基礎(chǔ)架構(gòu)圖 四、安裝Kafka 4.1 為每臺(tái)服務(wù)器下載Kafka并解壓 4.2 查看目錄結(jié)構(gòu) 4.3 為每臺(tái)服務(wù)器修改配置文件server.properties 4.4 為每臺(tái)服務(wù)器配置Kafka環(huán)境變量 4.5 啟動(dòng)zookeeper集群 4.6 啟動(dòng)Kafka集群 4.7 關(guān)閉Kafka集群的注意事項(xiàng) 五、Topic命令

    2024年02月04日
    瀏覽(22)
  • 【Spring框架】一篇文章帶你徹底搞懂Spring解決循環(huán)依賴(lài)的底層原理

    【Spring框架】一篇文章帶你徹底搞懂Spring解決循環(huán)依賴(lài)的底層原理

    目錄 一、前言 二、什么是循環(huán)依賴(lài) 三、Spring Bean 的循環(huán)依賴(lài)問(wèn)題 3.1 Bean 的創(chuàng)建步驟 3.2 為什么 Spring Bean 會(huì)產(chǎn)生循環(huán)依賴(lài)問(wèn)題? 3.3 什么情況下循環(huán)依賴(lài)可以被處理? 四、Spring 如何解決循環(huán)依賴(lài)問(wèn)題? 4.0 什么是三級(jí)緩存 4.1 簡(jiǎn)單的循環(huán)依賴(lài)(沒(méi)有AOP) 4.1.0 創(chuàng)建Bean的前期流

    2024年04月17日
    瀏覽(31)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包