current position:Home>How does the front end implement high-performance tables?

How does the front end implement high-performance tables?

2021-08-23 10:03:20 Tong ouba

Every front end wants to make a perfect table , The industry is also constantly exploring different ideas , Like nailing tables 、 Language bird form .

The data center team of the author also has high requirements for tables , Especially self-help analysis forms , Need to balance performance and interaction , This paper is the research and development idea of recording the high performance of self-service analysis form .

intensive reading

To make a table, first select based on DOM still Canvas, This is the first step in technology selection . For example, nailing tables is be based on Canvas Realized , Of course, that doesn't mean Canvas Implementation is better than DOM It's better to achieve , Technically, each has its own advantages and disadvantages :

  • Canvas Rendering efficiency ratio DOM high , This is caused by the browser implementation .
  • DOM Scalability ratio Canvas good , Rendering custom content is preferred DOM Instead of Canvas.

Technology selection depends on the specific business scenario , Nailing forms is actually online Excel,Excel This form determines that there must be simple text and some simple icons in the cell , So you don't have to consider rendering scenes with custom content , So choose Canvas Rendering will not encounter the trouble of bad expansion in the future .

The self-help analysis form may naturally expand the graphics 、 picture 、 Operate the button into the cell , The drag response interaction to the axis is also very complex , In order not to let Canvas Become the bottleneck of future expansion , Or choose DOM It is more appropriate to realize .

That's the question , since DOM Rendering efficiency is higher than natural Canvas low , How should we use DOM Implement a high-performance table ?

In fact, there are already many in the industry DOM Table optimization scheme , Mainly on-demand rendering 、 Virtual scrolling , That is, reserve some Buffer The area is used to fill when sliding , Tables render only visible areas and Buffer The regional part . But these schemes inevitably have the problem of white screen when sliding quickly , Through continuous attempts, the author finally found a perfect solution , Let's look down !

Cells use DIV Absolute positioning

That is, each cell is positioned absolutely DIV Realization , The whole table has independent calculation positions DIV Made by splicing :

The premise of this is :

  1. All cell positions are calculated in advance , It can be used here web worker Do parallel computing .
  2. Cell merging only produces a larger cell , Its positioning method is no different from that of small cells .

The benefits are :

  1. Rolling time , Cells can be reused to the greatest extent .
  2. For merged cells , It only makes the total number of cells rendered in the visual area smaller , More conducive to performance improvement , Not a performance burden .

As shown in the figure, there are 16 A cell , When we slide down one grid to the right , middle 3x3 namely 9 The area of a grid will not be re rendered at all , In this way, the scattered absolute positioning distribution can maintain the original position of the cell to the greatest extent . We can argue that , Any cell as long as it doesn't go beyond the screen , You won't re render with scrolling .

If you take React Framework to implement , Just put the... Of each grid key Set as unique , For example, the current row and column number .

Simulate scrolling instead of native scrolling

Generally speaking , Axis because of special logic , Its rendering logic and cells are maintained separately , So we divide the table into three areas : The horizontal axis 、 The vertical axis 、 Cell .

obviously , Common sense is that the horizontal axis can only roll vertically , The vertical axis can only roll laterally , Cells can scroll horizontally and vertically , Then the horizontal and vertical scroll bars can only appear in the cell area :

There are three problems :

  1. Cells use native scrolling , The horizontal and vertical axes can only be used after scrolling in the cell area , adopt .scroll Simulation scrolling , This will inevitably lead to a certain dislocation between the cell and the axis , That is, the rolling of the shaft has a lag of several milliseconds .
  2. Cannot scroll while the mouse is on the axis , Because only cells are overflow: auto Of , And the axis area overflow: hidden Unable to trigger scrolling .
  3. Quickly scroll to a white screen , Even if you stay Buffer Area , There's nothing you can do when scrolling fast , This is because rendering speed cannot keep up with scrolling .

After some thinking , We just need to make a slight adjustment to the plan , Can solve the above three problems at the same time : That is, don't use native scroll bars , But use .scroll Instead of scrolling , use mousewheel Listen for scrolling triggers :

What changes will this bring ?

  1. Axis 、 All cell ranges use .scroll Trigger scrolling , So that the axes and cells are not misaligned , Because both axes and cells use .scroll Triggered scrolling .
  2. Can monitor scrolling anywhere , So that the shaft can also roll , We no longer rely on overflow attribute .
  3. When you scroll quickly, you'll be surprised to find that the screen won't be white , The reason is to use js Controls that triggered scrolling occurs after rendering is complete , So the browser will finish rendering before scrolling occurs , It's quite interesting .

When simulating scrolling , In fact, the whole table is overflow: hidden Of , The browser will not give its own scroll bar , We need to use DIV Make a virtual scroll bar instead of , This is relatively easy .

zero buffer Area

When we use the simulated rolling scheme , It is equivalent to using “ High frequency rendering ” The plan , Therefore, there is no need to use interception , And don't use Buffer Area , Because the bigger Buffer Area means more rendering overhead .

When we put Buffer When the area is removed , Found the rendered cells in the whole screen in 1000 Within hours , Modern browsers even work with Windows Can quickly complete the refresh before scrolling , It doesn't affect the smoothness of scrolling .

Of course , Rolling too fast is still not a good thing , Since scrolling is controlled by us , You can control the rolling speed slightly , Control at each trigger mousewheel The displacement shall not exceed 200 Best left and right .

Precomputation

Like cell merging 、 Rows and columns are hidden 、 Cell formatting and other calculation logic , It's best to calculate in advance before rolling , Otherwise, real-time computing will inevitably bring additional computing costs and losses during fast rolling .

But this pre calculation also has disadvantages , When the number of cells exceeds 10w when , The calculation time will generally exceed 1 second , The number of cells exceeds 100w when , The calculation time will generally exceed 10 second , Trade precomputed sacrifice for rolling fluency , There are still some regrets , We can think about the following , Can the pre calculated loss be reduced ?

Local precomputation

Local precomputing is a solution , Even if there are 10 million cells , But if we only calculate the front 1w A cell ? No matter how much data there is , There will be no Caton .

But local pre calculation has obvious disadvantages , That is, during table rendering , Local results are not always equivalent to global results , Typical column widths 、 Row height 、 Calculated fields across rows and columns .

We need targeted solutions , For cell width and height calculation , Local calculations must be used , Because the loss of full quantity calculation is very large . But the local calculation is certainly inaccurate , As shown in the figure below :

But for performance reasons , We may only be able to calculate the height of the first three lines , here , We need to do two things when scrolling :

  1. When scrolling fast , towards web worker Send the expected position to scroll to , Incrementally calculate the text width at these locations , And the total column width is corrected in real time .( Because the total column width is calculated, as long as the maximum value is stored , So the calculated order of magnitude will be compressed to O(1)).
  2. After calculating the width , Quickly refresh the current screen cell width , But while the width is calibrated , Maintain the left alignment in the visible area , As shown in the figure below :

In this way, although the cells will be suddenly opened during scrolling , But the position does not produce relative movement , The visual content is the same as that after full opening in advance , Therefore, the user experience will not have a practical impact , But the calculation time is determined by O(row * column) Down to O(1), Just calculate the number of cells in the order of a constant .

The same is true for calculated fields , You can pre calculate by slice while scrolling , However, it should be noted that the calculation can only be carried out when local cells are involved , If the calculation is global , Like ranking , Then the ranking of local ranking must be wrong , We must make a full calculation .

Fortunately , Even a full calculation , We only need to consider part of the data , Suppose the number of rows and columns is n, The computational complexity can be reduced from O(n²) Reduced to O(n):

This processing of calculated fields cannot guarantee the support of unlimited orders of data , But it can greatly reduce the calculation time , hypothesis 1000w The time cost of cell calculation is 60s, This is an almost unbearable time , hypothesis 1000w The cell is 1w That's ok * 1k Columns form , The overhead of our local computation is 1w That's ok (100ms) + 1k Column (10ms) = 0.1s, It's almost impossible for users to feel 1000w Cell Caton .

stay 10w That's ok * 10w In the case of columns , The waiting time is 1+1 = 2s, Users will feel the explicit Caton , But the total number of cells is amazing 100 Billion , Light data may be a few TB 了 , It is impossible to aggregate data on this scale .

Map Reduce

Front end computing can also use multiple web worker Speed up , In short, don't let the user's computer CPU idle . We can go through window.navigator.hardwareConcurrency Get the maximum number that hardware parallelism can support web worker Number , We instantiate the same amount of web worker Parallel computing .

Take the example of ranking just now , Again 1000w Number of cells , What if there is only one column ? That line number is solid 1000w, In this case , Even if O(n) Complexity and computing time may also break through 60s, At this point, we can calculate in segments . My computer hardwareConcurrency The value is 8, Then instantiate 8 individual web worker, Parallel computing the second 0 ~ 125w, 125w ~ 250w ..., 875w ~ 1000w Segment data are sorted separately , Finally get 8 An ordered sequence , In the main worker Merge in thread .

We can use divide and conquer and merge , That is, for the sorting results received in turn x1, x2, x3, x4..., Combine the results received into x12, x34, ..., Merge again into x1234 Until merged into an array .

Of course ,Map Reduce It doesn't solve all the problems , hypothesis 1000w Data calculation takes time 60s, We are divided into 8 Segment parallelism , The average time of each section 7.5s, Then the total time for the first round of sorting is 7.5s. The time complexity of divide and conquer is O(kn logk), among k Is the number of segments , Here is 8 paragraph ,logk About equal to 3, Length of each section 125w yes n, So one 125w Order of magnitude binary sorting takes about 4.5s, The time complexity is O(n logn), So the equivalent is logn = 4.5s, k x logk Equal to several ? Here because k Far less than n, So the time consumption will be much less than 4.5s, It won't take more than 10s.

summary

If you want to build high-performance tables ,DIV Enough performance , Just pay attention to the implementation with a little skill . You can use it. DIV Achieve a performance balance 、 An expansive form , It's time to believe again DOM 了 !

I suggest you read this article , Follow this idea to make a small Demo, Think at the same time , What are the general functions of such a table that can be abstracted ? How to design API Can become the base of all kinds of business forms ? How to design functions to meet the expansion demands of the business layer ?

official account : Front end canteen

You know : Tong ouba

Nuggets : Tong ouba

This is a lifelong learning man , He's sticking to what he loves , Welcome to the front end canteen , Get fat with this man ~

“ If you think you can gain from reading this article, you can click here and let me see . Any questions during reading 、 Thoughts or feelings are also welcome to leave a message below , You can also reply to the communication group of the canteen in the background . Communication creates value , Sharing brings happiness . You are also welcome to share with the students in need , Altruism is the best self-interest . ”

This article is from WeChat official account. - Front end canteen (webcanteen)

The source and reprint of the original text are detailed in the text , If there is any infringement , Please contact the [email protected] Delete .

Original publication time : 2021-08-09

Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .

copyright notice
author[Tong ouba],Please bring the original link to reprint, thank you.
https://en.qdmana.com/2021/08/20210823100308555d.html

Random recommended