javascriptfunctionperformancefull-text-search

Is there a way to limit the long list of search results in my live javascript search bar so it responds faster on desktop browsers?


I have a javascript live search bar, it reads a .js file that holds the records. I added about 20,000 records to the original and an equal amount of corresponding links for those records. On my mobile device it is fast, works perfectly, no issues at all. Why? On desktop it slows down the browser quite a bit; possibly as much as :15 seconds after the first key stroke. I was looking for a way to limit the returned search results per keystroke, to 25 or so, instead of a giant list of all the results. My thought is, the html rendering of such a long list is the bottleneck on my desktop; but I don't really know. So far I am only using Firefox for desktop testing. Thank you all in advance for any ideas you may have to find a solution.

I am not a coding expert, I have limited experience with basic Javascript and searched all over, found some tips that I tried to no avail...

removed and replaced this line:

for (i = 0; i < listItems.length; i++)

for (i = 0; i < 25; i++) ---- didn't work, was expecting the entire list to still be searched, but the displayed results would be limited to 25. It would only search the first 25 lines in the file.

Added this:

let list = document.getElementById('list').max = "25"; ---- didn't work, had to remove because the search wouldn't work at all after.

Here is the code from my .js file; products and links reduced to 17 each.

function search() {

let listContainer = document.getElementById('list');
let listItems = document.getElementsByClassName('listItem');
let input = document.getElementById('searchbar').value
input = input.toLowerCase();
let noResults = true;
for (i = 0; i < listItems.length; i++) { 
    if (!listItems[i].innerHTML.toLowerCase().includes(input) || input === "") {
        listItems[i].style.display="none";
        continue;
    }
    else {
        listItems[i].style.display="flex";
        noResults = false; 
    }

listContainer.style.display = noResults ? "none" : "block";

}

}

function loadSearchData() {
  // Data to be used in the searchbar
let parts = [
    '102-305 Air Filter for Kohler 25 083 01-S',
    '120-485 Oil Filter for Briggs & Stratton 492932S',
    '100-780 Inner Air Filter for Kohler 25 083 04-S',
    '120-380 Transmission Filter for Exmark 1-513211',
    '120-712 Fuel Filter for John Deere AT17387',
    '102-604 Air Filter for John Deere AT171853',
    '102-600 Air Filter for John Deere AT20728',
    '102-077 Inner Air Filter for Toro 108-3816',
    '102-608 Inner Air Filter for John Deere AT171854',
    '102-073 Air Filter for Toro 108-3814',
    '435-221 Electric Starter for Kubota 1G772-63010',
    '120-764 Oil Filter for Bobcat 6511730',
    '079-2657 20" Laminate Sprocket Nose Bar .325 pitch .050 gauge 78 DL',
    '435-954 Alternator for John Deere SE501843',
    '075-1847 18" Replaceable Sprocket Nose Bar .325 pitch .058 gauge 72 DL',
    '075-4377 16" Replaceable Sprocket Nose Bar .325 pitch .050 gauge 66 DL',
    '435-922 Electric Starter for John Deere TY6615'


  ];

let links = [
    '/102-305/',
    '/120-485/',
    '/100-780/',
    '/120-380/',
    '/120-712/',
    '/102-604/',
    '/102-600/',
    '/102-077/',
    '/102-608/',
    '/102-073/',
    '/435-221/',
    '/120-764/',
    '/079-2657/',
    '/435-954/',
    '/075-1847/',
    '/075-4377/',
    '/435-922/'


  ];

// Get the HTML element of the list
let list = document.getElementById('list');
// Add each data item as an <a> tag
    parts.forEach((country, index)=>{
    const link = links[index];
    let a = document.createElement("a");
    a.innerText = country;
    a.href = `stens${link}`;
    a.classList.add("listItem");
    list.appendChild(a);
})


}

Solution

  • You don't actually need to render all the data at the first time,just filter out the useful data,then render them at once using innerHTML instead of appendChild.

    <style>
      .listItem {
        display: block;
      }
    </style>
    <input id="searchbar" type="text">
    <button onclick="search()">search</button>
    <div id="list"></div>
    
    <script>
      function search() {
        let listContainer = document.getElementById('list');
        let input = document.getElementById('searchbar').value;
        let listItem = ''
        if (input) {
          input = input.toLowerCase();
          let num = 0;
          parts.find((country, index) => {
            if (country.toLowerCase().includes(input)) {
              const link = links[index];
              listItem += `<a class="listItem" href="stens${link}">${country}</a>`
              num++;
            }
            //limit 25 stop the Loop 
            return num === 25
          })
        }
        if (!listItem) listItem = 'noResults !';
       // render all listItem at once
        listContainer.innerHTML = listItem;
      }
      // Data to be used in the searchbar
      let parts = [
        '102-305 Air Filter for Kohler 25 083 01-S',
        '120-485 Oil Filter for Briggs & Stratton 492932S',
        '100-780 Inner Air Filter for Kohler 25 083 04-S',
        '120-380 Transmission Filter for Exmark 1-513211',
        '120-712 Fuel Filter for John Deere AT17387',
        '102-604 Air Filter for John Deere AT171853',
        '102-600 Air Filter for John Deere AT20728',
        '102-077 Inner Air Filter for Toro 108-3816',
        '102-608 Inner Air Filter for John Deere AT171854',
        '102-073 Air Filter for Toro 108-3814',
        '435-221 Electric Starter for Kubota 1G772-63010',
        '120-764 Oil Filter for Bobcat 6511730',
        '079-2657 20" Laminate Sprocket Nose Bar .325 pitch .050 gauge 78 DL',
        '435-954 Alternator for John Deere SE501843',
        '075-1847 18" Replaceable Sprocket Nose Bar .325 pitch .058 gauge 72 DL',
        '075-4377 16" Replaceable Sprocket Nose Bar .325 pitch .050 gauge 66 DL',
        '435-922 Electric Starter for John Deere TY6615'
      ];
      let links = [
        '/102-305/',
        '/120-485/',
        '/100-780/',
        '/120-380/',
        '/120-712/',
        '/102-604/',
        '/102-600/',
        '/102-077/',
        '/102-608/',
        '/102-073/',
        '/435-221/',
        '/120-764/',
        '/079-2657/',
        '/435-954/',
        '/075-1847/',
        '/075-4377/',
        '/435-922/'
      ];
    </script>