Optimize: reuse tab and smart polling for faster checks

- Keep tab open between checks (no create/close overhead)
- Poll for products every 500ms instead of fixed 10s wait
- Exit early as soon as products are found
- Max wait reduced to 8 seconds
- Should reduce check time from ~15-20s to ~3-8s

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-03-24 18:22:00 -04:00
parent 4fa50809dd
commit 8f526976bc
+55 -27
View File
@@ -15,6 +15,7 @@ const DEFAULT_CONFIG = {
// Store known products
let knownProducts = {};
let config = DEFAULT_CONFIG;
let persistentTabId = null; // Keep tab open for faster refreshes
// Initialize
chrome.runtime.onInstalled.addListener(() => {
@@ -129,53 +130,82 @@ async function runStockCheck() {
async function fetchAndParseProducts(url) {
return new Promise(async (resolve, reject) => {
try {
// Create a tab to load the page
const tab = await chrome.tabs.create({ url, active: false });
let tabId;
let isNewTab = false;
console.log(`Created tab ${tab.id} for ${url}`);
// Reuse existing tab or create new one
if (persistentTabId) {
try {
const tab = await chrome.tabs.get(persistentTabId);
tabId = tab.id;
console.log(`Reusing tab ${tabId}, refreshing...`);
await chrome.tabs.update(tabId, { url });
} catch (e) {
// Tab was closed, create new one
persistentTabId = null;
}
}
if (!persistentTabId) {
const tab = await chrome.tabs.create({ url, active: false });
tabId = tab.id;
persistentTabId = tabId;
isNewTab = true;
console.log(`Created new tab ${tabId}`);
}
// Wait for tab to finish loading
const waitForLoad = () => {
return new Promise((res) => {
const listener = (tabId, changeInfo) => {
if (tabId === tab.id && changeInfo.status === "complete") {
const listener = (tid, changeInfo) => {
if (tid === tabId && changeInfo.status === "complete") {
chrome.tabs.onUpdated.removeListener(listener);
res();
}
};
chrome.tabs.onUpdated.addListener(listener);
// Timeout after 30 seconds
setTimeout(() => {
chrome.tabs.onUpdated.removeListener(listener);
res();
}, 30000);
}, 20000);
});
};
await waitForLoad();
console.log(`Tab ${tab.id} loaded`);
console.log(`Tab ${tabId} loaded`);
// Give extra time for dynamic content to load
console.log("Waiting for dynamic content...");
await new Promise(r => setTimeout(r, 10000)); // 10 seconds for slow loads
// Send message to content script to extract products
// Smart wait: poll for products instead of fixed wait
let products = [];
const startTime = Date.now();
const maxWait = 8000; // Max 8 seconds
const pollInterval = 500; // Check every 500ms
while (Date.now() - startTime < maxWait) {
try {
// Inject content script if needed
try {
const response = await chrome.tabs.sendMessage(tab.id, { type: "extractProducts" });
products = response || [];
console.log(`Content script returned ${products.length} products`);
} catch (e) {
console.log("Content script not ready, injecting manually...");
// Inject content script if not already there
await chrome.scripting.executeScript({
target: { tabId: tab.id },
target: { tabId },
files: ["content.js"]
});
await new Promise(r => setTimeout(r, 500));
const response = await chrome.tabs.sendMessage(tab.id, { type: "extractProducts" });
} catch (e) { /* Already injected */ }
await new Promise(r => setTimeout(r, pollInterval));
const response = await chrome.tabs.sendMessage(tabId, { type: "extractProducts" });
products = response || [];
if (products.length > 0) {
console.log(`Found ${products.length} products after ${Date.now() - startTime}ms`);
break;
}
} catch (e) {
// Content script not ready yet
}
}
if (products.length === 0) {
console.log(`No products found after ${maxWait}ms`);
}
// Apply keyword filter
@@ -187,13 +217,11 @@ async function fetchAndParseProducts(url) {
console.log(`After keyword filter: ${products.length} products`);
}
// Close the tab
await chrome.tabs.remove(tab.id);
console.log(`Closed tab ${tab.id}`);
// Don't close tab - keep for reuse
resolve(products);
} catch (error) {
persistentTabId = null; // Reset on error
reject(error);
}
});