mirror of
https://github.com/0xMarcio/cve.git
synced 2026-10-27 16:51:03 +00:00
Stop searching the index on every keystroke
A pass over 104,043 entries costs 25-125ms, which is fast enough to feel instant once but not nine times in a row while a word is typed. Coalesce a burst at 160ms, skip single-character queries that match most of the index without narrowing anything, and total the PoC count during the scan rather than walking the matches again to display it.
This commit is contained in:
1 parent
4ec2802cf5
commit
79da26dd45
1 file changed
+18
-4
+18
-4
@@ -4,6 +4,7 @@ const REPLACE_STRINGS = ['HackTheBox - ', 'VulnHub - ', 'UHC - '];
|
||||
const PAGE_SIZE = 50;
|
||||
const POC_PREVIEW = 5;
|
||||
const TREND_ROWS = 20;
|
||||
const MIN_QUERY = 2;
|
||||
|
||||
const state = {
|
||||
query: '',
|
||||
@@ -210,6 +211,7 @@ function runSearch(query) {
|
||||
.filter(Boolean);
|
||||
|
||||
const results = [];
|
||||
results.pocTotal = 0;
|
||||
for (const entry of dataset) {
|
||||
let score = 0;
|
||||
let matched = true;
|
||||
@@ -233,6 +235,7 @@ function runSearch(query) {
|
||||
// at the weakest tier, where newest-first is meaningless. How many of the
|
||||
// linked PoCs carry the term says far more than which CVE is newer.
|
||||
entry._hits = describes ? 0 : countLinkHits(entry, matchers);
|
||||
results.pocTotal += (entry.poc || []).length;
|
||||
results.push(entry);
|
||||
}
|
||||
|
||||
@@ -392,7 +395,7 @@ function renderResults(elapsed) {
|
||||
}
|
||||
|
||||
const shown = results.slice(0, state.shown);
|
||||
const pocTotal = results.reduce((sum, r) => sum + (r.poc || []).length, 0);
|
||||
const pocTotal = results.pocTotal;
|
||||
const remaining = results.length - shown.length;
|
||||
const footer = remaining > 0
|
||||
? `<button type="button" class="poc-more" data-more-results>+ ${formatCount(remaining)} more matching CVEs</button>`
|
||||
@@ -460,7 +463,7 @@ function idleStatus() {
|
||||
}
|
||||
|
||||
function render() {
|
||||
if (!state.query) {
|
||||
if (state.query.length < MIN_QUERY) {
|
||||
el.status.textContent = state.ready ? idleStatus() : 'loading index…';
|
||||
renderTrending();
|
||||
return;
|
||||
@@ -482,10 +485,21 @@ function render() {
|
||||
|
||||
/* ---- wiring ------------------------------------------------------------ */
|
||||
|
||||
// A full pass over the index costs ~200ms, so one per keystroke makes typing
|
||||
// stutter. 160ms covers an ordinary typing cadence without the wait being felt;
|
||||
// clearing the field stays instant.
|
||||
let searchTimer = null;
|
||||
el.input.addEventListener('input', () => {
|
||||
state.query = el.input.value.trim();
|
||||
const next = el.input.value.trim();
|
||||
if (next === state.query) return;
|
||||
state.query = next;
|
||||
state.shown = PAGE_SIZE;
|
||||
render();
|
||||
clearTimeout(searchTimer);
|
||||
if (next.length < MIN_QUERY) {
|
||||
render();
|
||||
return;
|
||||
}
|
||||
searchTimer = setTimeout(render, 160);
|
||||
});
|
||||
|
||||
document.querySelector('.search').addEventListener('submit', event => event.preventDefault());
|
||||
|
||||
Reference in new issue
Block a user