Home > Back-end >  Make vanilla js html table load faster
Make vanilla js html table load faster

Time:12-03

I am trying to create an html table by fetching json from an api, but when it builds the table it takes a long time to populate, not because of the fetch request but because it is building a table with 600-1000 records and I want to speed it up. I don't have much experience with js or html so its super rough code I just want to be able to speed it up. I have seen answers about adding pagination but I am not quite sure how to approach this.

<meta name="viewport" content="width=device-width, initial-scale=1">

<head>
  <title>Example</title>
  
  <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css">
  <link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-balham.css">
</head>

<body>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.1/css/bootstrap.min.css"
    integrity="sha512-Ez0cGzNzHR1tYAv56860NLspgUGuQw16GiOOp/I2LuTmpSK9xDXlgJz3XN4cnpXWDmkNBKXR/VDMTCnAaEooxA=="
    crossorigin="anonymous" referrerpolicy="no-referrer" />


  <label>
    Select a nurse:
    <select  name="nurses">
      <option value="">Select One …</option>
      <option value="Om">Om</option>
      <option value="Reb">Reb</option>
      <option value="Man">Man</option>
      <option value="Gus">Gus</option>
    </select>
  </label>

  <div ></div>
  <table >
    <thead>
      <tr>
        <th scope="col">Bed</th>
        <th scope="col">Patient</th>
        <th scope="col">Status</th>
        <th scope="col">Assigned Nurse ID</th>
        <th scope="col">Need Urgency</th>
        <th scope="col">Need</th>
        <th scope="col">Nurse</th>
        <th scope="col">Req ID</th>
        <th scope="col">Time Created Epoch</th>
        <th scope="col">Patient ID</th>
        <th scope="col">Time</th>
        <th scope="col">Room</th>
      </tr>
    </thead>
    <tbody id="tbody">
    </tbody>
  </table>





  <script type="text/javascript" charset="utf-8">
    const selectElement = document.querySelector('.nurses');
    var x = '';
    selectElement.addEventListener('change', (event) => {
      const result = document.querySelector('.result');
      x = event.target.value;
      result.textContent = `You Chose ${event.target.value}`;

      getdata(x);
    });


    const tbody = document.querySelector('#tbody');

    const getdata = async () => {
      const endpoint = "https://my.api.here/beta?nurse=",
        response = await fetch(endpoint   x),
        data = await response.json(),
        Items = data.Items;
      tbody.innerHTML = "";
      Items.forEach(itemObj => {
        let { bed, patient_name, status, assigned_nurse_id, need_urgency, need, assigned_nurse, ID, timestamp_created_epoch, patient_id, timestamp_created, room } = itemObj;
        tbody.innerHTML  = `<tr>
        <td>${bed}</td>
        <td>${patient_name}</td>
        <td>${status}</td>
        <td>${assigned_nurse_id}</td>
        <td>${need_urgency}</td>
        <td>${need}</td>
        <td>${assigned_nurse}</td>
        <td>${ID}</td>
        <td>${timestamp_created_epoch}</td>
        <td>${patient_id}</td>
        <td>${timestamp_created}</td>
        <td>${room}</td>

    </tr>`;
      });

      const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;

      const comparer = (idx, asc) => (a, b) => ((v1, v2) =>
        v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
      )(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));

      // do the work...
      document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
        const table = th.closest('table');
        const tbody = table.querySelector('tbody');
        Array.from(tbody.querySelectorAll('tr'))
          .sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
          .forEach(tr => tbody.appendChild(tr));
      })));

    }
  
  </script>

</body>

</html>

CodePudding user response:

Doing innerHTML is a loop is one way to make your code render slow. Build a string and set that string one time.

const items = data.Items;
const rows = items.map(itemObj => {
        let { bed, patient_name, status, assigned_nurse_id, need_urgency, need, assigned_nurse, ID, timestamp_created_epoch, patient_id, timestamp_created, room } = itemObj;
        return `<tr>
        <td>${bed}</td>
        <td>${patient_name}</td>
        <td>${status}</td>
        <td>${assigned_nurse_id}</td>
        <td>${need_urgency}</td>
        <td>${need}</td>
        <td>${assigned_nurse}</td>
        <td>${ID}</td>
        <td>${timestamp_created_epoch}</td>
        <td>${patient_id}</td>
        <td>${timestamp_created}</td>
        <td>${room}</td>
    </tr>`;
});
tbody.innerHTML = rows.join("");

  • Related