Think I speak good, please help point a like, thank you. Hee hee
scenario
Kangxi picking up brides
It was the 53th year of The Reign of Emperor Kangxi, and the world was at peace. No one in the world could not help but sigh at the “flourishing time of Emperor Kangxi”. Emperor Kangxi himself was very happy.
- Kangxi: heng Chen (heng Chen is zhang Tingyu’s word), how is this Kangxi prosperous time
- Zhang Tingyu: Your Majesty niubi, your Majesty Niubi, long live your Majesty
- Kangxi: but I am old, but I cannot accept old, I want to prove to the world to see
- Zhang Tingyu: The emperor is in the prime of life
- Kangxi: I don’t care, I want to choose fei, I want to choose fei, I want to choose fei!!
- Zhang Tingyu: I tm… You’re 60 fucking years old? Can you handle it? The eldest brother!
- Kangxi: I don’t care, you give me to find, find ten thousand young women into the palace, I want to choose the concubine
- Zhang Tingyu: choose a hair, you can’t move – Kangxi: I don’t care, I have deer blood, a cup of deer blood, the magic power is endless
- Zhang Tingyu: No, you can’t.
- Kangxi: will you go or not?
- Zhang Tingyu: No
- Kangxi: are you going
- Zhang Tingyu: I’m not going
- Kangxi: do you still want to enjoy the Imperial Temple?
- Zhang Tingyu: long live the emperor, I must go up of saint tuo
A month later, 10,000 young women entered the palace. But here comes the problem. So many women, impossible one-time let Kang Xi choose, that must not spend his eye.
Zhang Tingyu had an idea: can let the women enter the hall in batches to let the emperor choose. Here’s how to do it:
- To choose a concubine under the emperor
The hall
External, set againTwo house
- The ladies went into the hall in batches for the emperor to see
- Have seen the palace maids into the left side of the palace to wait for the results of the selection of imperial concubines, haven’t row to the palace maids waiting in the right side of the hall
This improves draft efficiency already, can make emperor more relaxed again. The benefits of this are:
- The emperor does not need to see ten thousand maids of honor at a time
- If the emperor is tired after half of the selection, he can rest and choose again the next day. Anyway, he has chosen the first batch, which has been recorded
- If the emperor one day recall which ladies in waiting is good, you can also check back
Multi-data rendering
When it comes to multi-data rendering, you might think of paging, bottom-loading, lazy loading, etc., but virtual lists are also an important solution for high-performance multi-data loading.
The concept of virtual lists
Virtual scrolling is to monitor the user’s sliding or scrolling events according to the number of list volume in the container’s visible area, dynamically intercept part of the data in the long list and render it to the page, dynamically fill the contents of the container’s scrolling area with blank station, and simulate the original scrolling effect
- Browser rendering === Kangxi show: rendering 10,000 at a time will definitely make the browser stress, resulting in poor user experience
- Container viewable area === screen hall: 10000 queued to render, say 10 at a time
- Upper and lower areas === left and right side of the hall: it is not your turn to render, you obediantly into the blank area to stay
implementation
Basic implementation
- The height of the visible area
- The height of a list item
- Number of list items that can be displayed in the visual area = ~~(Height of the visual area/height of the list item) + 2
- The starting index
- The ending index
- Preloading (to prevent scrolling too fast, causing temporary white screen)
- According to the start index and end index, intercept data to display in the visual area
- Scroll throttle
- The upper and lower white Spaces are implemented using padding
- Slide to the bottom, request data again and splice
<template>
<div class="v-scroll" @scroll.passive="doScroll" ref="scrollBox">
<div :style="blankStyle" style="height: 100%">
<div v-for="item in tempSanxins" :key="item.id" class="scroll-item">
<span>{{ item.msg }}</span>
<img :src="item.src" />
</div>
</div>
</div>
</template>
<script>
import { throttle } from ".. /.. /utils/tools";
export default {
data() {
return {
allSanxins: [].// All data
itemHiehgt: 150.// The width of each item in the list
boxHeight: 0.// The height of the visible area
startIndex: 0.// Start the element index
};
},
created() {
// Simulate the request data
this.getAllSanxin(30);
},
mounted() {
// In Mounted, obtain the height of the visible region
this.getScrollBoxHeight();
// Listen for screen changes and rotation, both to regain the height of the visible area
window.onresize = this.getScrollBoxHeight;
window.onorientationchange = this.getScrollBoxHeight;
},
methods: {
getAllSanxin(count) {
// Simulate the data
const length = this.allSanxins.length;
for (let i = 0; i < count; i++) {
this.allSanxins.push({
id: `sanxin${length + i}`.msg: 'I am three hearts${length + i}No. `.// Just choose a random picture here
src: require(".. /.. /src/asset/images/sanxin.jpg").default, }); }},// Use throttling to improve performance
doScroll: throttle(function () {
// Listen for scrolling events in the visible area
// The formula: ~~(scrolling distance/list item), to calculate how many list items have been rolled, and to know what the startIndex is now
// For example, if I scroll past 160px, the index will be 1, because the first item in the list has been rolled up, and the index of the first item in the visible area is 1
const index = ~~(this.$refs.scrollBox.scrollTop / this.itemHiehgt);
if (index === this.startIndex) return;
this.startIndex = index;
if (this.startIndex + this.itemNum > this.allSanxins.length - 1) {
this.getAllSanxin(30); }},200),
getScrollBoxHeight() {
// Get the height of the visible area
this.boxHeight = this.$refs.scrollBox.clientHeight; }},computed: {
itemNum() {
// How many list items can be displayed in the visual area? Calculation formula: ~~(height of visual area/height of list item) + 2
// ~~ is a downward integer operator, equivalent to math.floor (). Why +2? It's possible that the top and bottom elements are only partially displayed
return~ ~ (this.boxHeight / this.itemHiehgt) + 2;
},
endIndex() {
// endIndex = (start index + how many list items can be displayed in the visual area * 2)
If startIndex is 0, endIndex will be 0 + 8 * 2 = 16; if startIndex is 1, endIndex will be 1 + 8 * 2 = 17; and so on
// Why do you want to multiply it by 2, because it will preload a page of data and prevent scrolling too fast and causing a temporary white screen
let index = this.startIndex + this.itemNum * 2;
if (!this.allSanxins[index]) {
If startIndex is 99995, then endIndex should be 99995 + 8 * 2 = 10011
EndIndex = (list length -1) endIndex = (list length -1)
index = this.allSanxins.length - 1;
}
return index;
},
tempSanxins() {
// The slice method of the array can be used to intercept data without changing the original array
let startIndex = 0;
if (this.startIndex <= this.itemNum) {
startIndex = 0;
} else {
startIndex = this.startIndex - this.itemNum;
}
return this.allSanxins.slice(startIndex, this.endIndex + 1);
},
blankStyle() {
// Use the padding for the upper and lower Spaces
let startIndex = 0;
if (this.startIndex <= this.itemNum) {
startIndex = 0;
} else {
startIndex = this.startIndex - this.itemNum;
}
return {
// calculate the height of the top blank :(start index * list item height)
// For example, if you roll over 3 items, the height of the top blank space will be 3 * 150 = 450, so as to pretend that 10000 items are scrolling
paddingTop: startIndex * this.itemHiehgt + "px".// the formula for calculating the height of the blank at the bottom is :(number of data - end index - 1) * the height of the list item
// for example, if the end index is now 100, then the lower blank height is :(10000-100-1) * 150 = 1,484,850
paddingBottom:
(this.allSanxins.length - this.endIndex - 1) * this.itemHiehgt + "px".// Don't forget to add px}; ,}}};</script>
<style lang="scss" scoped>
.v-scroll {
height: 100%;
/* padding-bottom: 500px; * /
overflow: auto;
.scroll-item {
height: 148px;
/* width: 100%; * /
border: 1px solid black;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
img {
height: 100%; }}}</style>
Copy the code