🔍 Offload search functionality to a web worker for improved UI responsiveness and performance
This commit is contained in:
@@ -625,6 +625,9 @@ const onSearchInput = debounce(async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize worker if needed
|
||||||
|
initSearchWorker();
|
||||||
|
|
||||||
// Show progress for long searches
|
// Show progress for long searches
|
||||||
const searchTerm = searchQuery.value.toLowerCase();
|
const searchTerm = searchQuery.value.toLowerCase();
|
||||||
operationProgress.value = {
|
operationProgress.value = {
|
||||||
@@ -634,54 +637,19 @@ const onSearchInput = debounce(async () => {
|
|||||||
complete: false
|
complete: false
|
||||||
};
|
};
|
||||||
|
|
||||||
await perfMonitor('Search', async () => {
|
// Offload search to worker to avoid blocking UI
|
||||||
const results = [];
|
searchWorkerRequestId++;
|
||||||
const device = getDevicePerformance();
|
const requestId = searchWorkerRequestId;
|
||||||
const chunkSize = device.recommendedChunkSize;
|
|
||||||
|
searchWorker.postMessage({
|
||||||
// Search through ALL fileLines, not just displayLines
|
lines: fileLines.value,
|
||||||
for (let i = 0; i < fileLines.value.length; i += chunkSize) {
|
searchTerm: searchTerm,
|
||||||
const chunk = fileLines.value.slice(i, i + chunkSize);
|
id: requestId
|
||||||
|
|
||||||
chunk.forEach((lineContent, idx) => {
|
|
||||||
const actualIndex = i + idx;
|
|
||||||
const matches = lineContent.toLowerCase().includes(searchTerm);
|
|
||||||
|
|
||||||
// Only update displayLines if it's within the visible range
|
|
||||||
const displayIndex = displayLines.value.findIndex(
|
|
||||||
l => l.lineNumber === actualIndex + 1
|
|
||||||
);
|
|
||||||
if (displayIndex !== -1) {
|
|
||||||
displayLines.value[displayIndex].hasMatch = matches;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (matches) {
|
|
||||||
results.push(actualIndex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update progress
|
|
||||||
operationProgress.value.percent = Math.min(
|
|
||||||
((i + chunkSize) / fileLines.value.length) * 100,
|
|
||||||
100
|
|
||||||
);
|
|
||||||
|
|
||||||
// Yield to browser
|
|
||||||
if (i % (chunkSize * 3) === 0) {
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
searchResults.value = results;
|
|
||||||
currentResultIndex.value = 0;
|
|
||||||
|
|
||||||
// Complete animation
|
|
||||||
operationProgress.value.complete = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
operationProgress.value.active = false;
|
|
||||||
}, 500);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Store current request ID to ignore stale results
|
||||||
|
searchWorkerRequestId = requestId;
|
||||||
|
|
||||||
// Add to search history
|
// Add to search history
|
||||||
searchHistory.addToHistory(searchQuery.value);
|
searchHistory.addToHistory(searchQuery.value);
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|||||||
Reference in New Issue
Block a user