I am filtering a list with javascript. My code works without issues but when the list const gets greater than 100 the browser freezes.
JavaScript
x
37
37
1
<div id="domList" class="flex flex-col p-8 space-y-4 bg-white shadow rounded-xl">
2
<?php foreach ($clients as $client): ?>
3
<a href="<?=base_url();?>/clients/<?=$client->id;?>" class="flex justify-between p-4 bg-gray-100 rounded item hover:bg-gray-200">
4
<div class="flex items-center"><span class="mr-2 text-xs text-gray-400"><?=$client->customernumber;?></span> <?=$client->fn;?> <?=$client->ln;?></div>
5
<div class="ml-2 py-1 px-2 text-xs flex-shrink-0 flex justify-center items-center text-white <?=$client->status_bg;?> rounded"><?=$client->status;?></div>
6
</a>
7
<?php endforeach;?>
8
</div>
9
10
<script type="text/javascript">
11
const list = <?=json_encode($clients);?>;
12
13
const filterEventHandler = (event) => {
14
const filterVal = event.target.value;
15
16
const domList = document.getElementById('domList');
17
18
domList.innerHTML = '';
19
20
const newList = list.filter((e) =>
21
e.customernumber.toLowerCase().includes(filterVal.toLowerCase()) ||
22
(e.fn + " " +e.ln).toLowerCase().includes(filterVal.toLowerCase())
23
);
24
25
newList.forEach(user => domList.innerHTML += buildItem(user));
26
}
27
28
const buildItem = (user) => {
29
const item = `
30
<a href="<?=base_url();?>/clients/${user.id}" class="flex justify-between p-4 bg-gray-100 rounded item hover:bg-gray-200">
31
<div class="flex items-center"><span class="mr-2 text-xs text-gray-400">${user.customernumber}</span> ${user.fn} ${user.ln}</div>
32
<div class="ml-2 py-1 px-2 text-xs flex-shrink-0 flex justify-center items-center text-white ${user.status_bg} rounded">${user.status}</div>
33
</a>`;
34
return item;
35
}
36
</script>
37
What am I doing wrong and how can I make this code working for a list of much more values (> 50.000).
Advertisement
Answer
See if this helps to begin with:
- Move lower-casing
filterVal
out of the.filter
loop. There’s no need to do that for each item inlist
. - Only write
innerHTML
once (instead of clearing it and then appending to it).
JavaScript
1
15
15
1
const filterEventHandler = (event) => {
2
const filterVal = event.target.value.toLowerCase();
3
const htmlFragments = list
4
.filter(
5
(e) =>
6
e.customernumber
7
.toLowerCase()
8
.includes(filterVal) ||
9
`${e.fn} ${e.ln}`.toLowerCase().includes(filterVal),
10
)
11
.map(buildItem);
12
const domList = document.getElementById("domList");
13
domList.innerHTML = htmlFragments.join("");
14
};
15
Going forward, you may want to think about a framework such as React (or something lighter-weight like Svelte or Mithril) instead of building your HTML by hand.
That is especially true since a customer named <script>alert("hello")</script>
will presently cause havoc on your site. 🙂