The final result

preface

It is the weekend ~ wake up in the morning, embrace ☀️ sun, so start to do homework ~

A well-known interview question: What do you do with 10W + data returned from the back end? For this kind of problem a lot of people want to shake the hammer 🔨, threatened to blow the back end, but also don’t say, there really will be such a scene, such as processing Excel tables, do big data analysis, database data management, don’t say there are 10W + data, but if the front-end direct rendering, this magnitude is enough to let the browser stuck, Until it freezes (see the.csv file in my source code).

Therefore, facing this problem, we should consider from the following aspects:

  1. On the server side, start with the server side first. Can the back end paginate the data?

  2. Think from the server side, if the back end does not process, can the front end do a node middle layer to process the data?

  3. Finally, the front end can only offer a killer, virtual rolling!

What is virtual scrolling

scenario

In GENERAL, in H5, the display of the list page is very common, and if the list data is very large and the list is pulled down infinitely, then a lot of DOM rendering will cause the page to stall. However, on the PC side, if big data is often rendered by tables or a large tree, such as the Tree component using Element UI, once a bit more data needs to be rendered, the tree component will recursively generate DOM and then render to the page, resulting in page lag.

The characteristics of

Know the scene, naturally derived from a more general solution – virtual scroll, virtual scroll is only apply colours to a drawing of the current viewport dom elements (of course also can render three pages as a buff cache, let the user experience better ~), virtual rolling core is on-demand rendering, not in the viewing area element does not require rendering, so also called viewing area rendering. Features are as follows:

  1. Scroll to the containerFor example, a window can be rolled throughoverflowThrough the layout of the way to achieve scrolling, thus throughonScrollThe event scrolllistens for elements in the container to know their position relative to the container.
  2. Scrollable area:How many areas inside the container can I scroll, say, 1,000 elements,width60, so the scrollable area is 1000 by 60 px.
  1. Viewable area: The area that is visible, such as the size of the screen in H5 or the size of the browser’s visual window.

Virtual scroll implementation

Therefore, the principle of virtual scrolling is that when the user slides in the scrollable area, the container can listen for changes in scrollTop and scrollLeft to know which elements should be rendered into the visible area.

The idea of implementing a table component that supports horizontal virtual scrolling is as follows:

  1. Calculating the viewable areawidth;
  2. On the basis ofscrollLeftFigure out which columns to display in the viewable area;
  1. During scrolling, real-time monitor step 2 of scrolling calculation;
  2. Calculate the total width of the table contents and passtransformHide unrendered parts

Direct to the code: github.com/AutumnWhj/v…

Table component – Horizontal virtual scroll implementation

Explicit final call

The table can be divided into the data part of the table header and the table body, namely header and body. Therefore, the interface of the table component can be as follows: It realizes its own logic according to the data.

<acho-virtual-table
  :columns="columns"
  :dataSource="dataSource"
/>
Copy the code

Scrollable table layout

According to the characteristics of virtual scrolling, you can make the following layout, the layout is reasonable on the success of more than half, the need to do behind is not to do some calculation of the monitoring of scrolling.

Computationwindow renderable columns -columns

To calculate the columns of the visible window, calculate which column can be seen according to the scrollLeft, i.e. the distance to the right of the window relative to the scroll container, as follows:

handleBodyScrollLeft(event) {
  const scrollLeft = event.target.scrollLeft
  let start = Math.floor(scrollLeft / this.itemWidth)

  this.start = Math.max(start, 0)
  //this.visibleCount = Math.max(Math.ceil(width / this.itemWidth), 10)
  this.end = this.start + this.visibleCount

  this.transform = `translate3d(The ${this.itemWidth * this.start}` px, 0, 0)
}
Copy the code

Start is calculated by dividing the width of each column by scrollLeft and rounding down. End is the width of the visible area divided by the width of each column and rounding up. After knowing the two Pointers of Start and end, we can intercept the data columns of the table head column.

Use computed in VUE to calculate the values of elements in the visible area:

computed: {
  visibleColumns({ columns }) {
    return columns.slice(
      Math.max(this.start, 0),
      Math.min(this.end, columns.length)
    )
  }
},
Copy the code

Note: The width of each column is not necessarily the same width, in this case, you can maintain a decreasing value to obtain the final start and end pointer coordinates (here mainly experience the principle of virtual scrolling), such as:

let startX = scrollLeft
let endX = scrollLeft + this.$el.clientWidth

const start = columns.findIndex((col) = > {
  const colW = col.width || 100
  startX = startX - colW
  return startX < colW
})

const end = columns.findIndex((col) = > {
  const colW = col.width || 100
  endX = endX - colW
  return endX < colW
})
Copy the code

How to optimize virtual scrolling

  1. Throttling: encounterscrollFor rolling scenarios, throttling allows events to be triggered in order according to delay events.
  2. requestAnimationFrameThe: scroll callback can be usedrequestAnimationFrameCan ensure that the screen does not drop the frame to the maximum extent, because setTimeout cannot guarantee the execution time, andrequestAnimationFrameCallbacks are executed after frames are rendered.
  1. transform: For window displacement, most people usepadding-leftProcess, but this will constantly redraw and reflow, according to the render Tree rendering layer to composite layer process, as soon as the elements of the same layer are changed, the layer will be reprocessed. So it can be usedtransformAnd specify the CSSwill-change: transform;To tell the GUI process to render it on a separate layer.
  2. Vue “update in place” strategy – render with key attribute etc……

expand

The table component can be used to search, sort, and select the table. The table component can be used to select the table. The table component can be used to search, sort, and select the table. Such as

Source:

Making the dev/AutumnWhj/v…

The last

Virtual list is an almost perfect solution for large data and dom node Rendering. After using it, open Chrome performance page and test, you will find that the Rendering time is greatly reduced, so you can use it quickly

Above is the personal study opinion, corner view, welcome exchange study!