How to lazyload a standard html table that has many rows?
Asked Answered
I

3

8

Instead of using a table plugin by someone else, I choose to do it the standard HTML way of making Tables and rows etc etc. I would fetch data from a database to fill the rows. But when the number of rows exceeded 10,000, I realized I needed to lazy_load the rows otherwise the website would be incredibly slow. I've looked for ways to lazy load rows of a table, but I can't seem to find it anywhere, so my question is simply does the lazyloading plug-in or for rows even exist?

Hope some guru can answer this. Thanks in advance!

Background as to what I'm trying to do: I'm creating the rough sketch of the table in the html code, then during runtime, I will add rows to the table through DOM when the user searches for particular things. When they search it, there will be thousands of results, and I want to lazyload the result into the table.

jQuery provides lazyload for images and containers of images.

Some other plug-ins allowed for lazyloading of divs.

Lazyloading for table rows however seemed to be non-existant.

Some sample code for context:

HTML:

        <fieldset>
        <legend>PhotoViewer v1.6</legend>
        <h4 id = "albumName"><i>Photos</i></h4>
        <table cellspacing="1" border="2" id = "photoTable" class = "lazyProgressiveLoad">
            <tr style="font-style: italic; font-size: small; font-family: Segoe UI Light; color: Red">
                <th>--Photo--</th>
                <th>--Label--</th>
                <th>--Path--</th>
                <th><input type="button" value="Add Photo" onclick="addPhoto()" id = "addPhoto"/></th>
            </tr>
        </table>
    </fieldset>

Looking for some code that will allow the same functionality as the code below for table rows.

Javascript:

$(function() {
      $("img").lazyload({
          effect : "fadeIn"
          /*
          ,appear : function(elements_left, settings) {
              console.log("appear");
              console.log(elements_left);
              //console.log(this, elements_left, settings);
          },
          load : function(elements_left, settings) {
              console.log("load");
              console.log(elements_left);
              //console.log(this, elements_left, settings);
          }
          */
      });
  });
Indiscerptible answered 24/9, 2012 at 22:17 Comment(1)
I have answer a very similar question, with original code, including the project, take a look, it may help you: https://mcmap.net/q/1328241/-virtual-listview-for-asp-netRojas
T
8

Having thousands of rows of data in the DOM is an awful idea for one simple reason: the DOM is slow.

Instead, only render the rows that need to be visible. When a row goes out of view, remove it from the DOM.

My favorite library for displaying a grid of data is SlickGrid. By only rendering DOM elements for the data in the viewport, it can display effectively unlimited amounts data with astounding performance. (That example displays a half-million rows!)

There are more examples that show off SlickGrid's features, but you'll be especially interested in the AJAX loading example, where small chunks of rows are streamed from the server as you scroll.

Turn answered 24/9, 2012 at 22:49 Comment(1)
is there any other or new library nowadays? SlickGrid last commit is from 2016Animality
J
1

I haven't heard of a plugin that can do something like this, but I mostly avoid fancy JS "libraries". That being said conceptually, you can use an AJAX request to select for example images where m>id>n, then in your javascript when you want to load more images, do another ajax request, but increment m and n by 100 for example.

Lots of open source gallery frameworks exist that operate on this principle, but usually, they generate the page using php, instead of dynamically altering the inner html using AJAX.

Here is how to get database data out of AJAX and into JS. http://www.w3schools.com/ajax/ajax_database.asp

Joscelin answered 24/9, 2012 at 22:26 Comment(1)
The link is brokenAnimality
Z
1

A simple way of lazy loading a table would be to make all <tr> elements have display: none set when the table is first populated, and then only load more rows when the last visible row is within n screens of the viewport:

let bufferRows = 200;

function lazyLoadNext(numRows) {
    numRows = Math.min(numRows, tableBody.childNodes.length);

    let rowsLoaded = 0;
    for (let i = 0; i < tableBody.childNodes.length; i++) {
        if (tableBody.childNodes[i].style.display != "none")
            continue;

        tableBody.childNodes[i].style = "";

        rowsLoaded++;
        if (rowsLoaded >= numRows)
            break;
    }
}

function lazyLoadBuffer() {
    for (let i = tableBody.childNodes.length - 1; i >= 0; i--) {
        if (tableBody.childNodes[i].style.display == "none")
            continue;

        let rect = tableBody.childNodes[i].getBoundingClientRect();
        let viewHeight = window.innerHeight || document.documentElement.clientHeight;

        // If we are within 3 screens of the viewport, lazy load more rows
        if (rect.bottom <= viewHeight * 3) {
            console.log(`Lazy loading ${bufferRows} more rows...`)
            lazyLoadNext(bufferRows);
        }

        break;
    }
}

lazyLoadNext(bufferRows);
window.onscroll = lazyLoadBuffer; // optionally debounce

Example JSFiddle: https://jsfiddle.net/0hgtmjk4/1/

Zinazinah answered 9/2, 2023 at 15:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.