From 8f526976bcd44b463eb4b47a171a59a91cdef4ac Mon Sep 17 00:00:00 2001 From: Mike McGhen Date: Tue, 24 Mar 2026 18:22:00 -0400 Subject: [PATCH] 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 --- chrome-extension/background.js | 92 ++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 32 deletions(-) diff --git a/chrome-extension/background.js b/chrome-extension/background.js index dbf2907..fda5394 100644 --- a/chrome-extension/background.js +++ b/chrome-extension/background.js @@ -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 = []; - 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 }, - files: ["content.js"] - }); - await new Promise(r => setTimeout(r, 500)); - const response = await chrome.tabs.sendMessage(tab.id, { type: "extractProducts" }); - products = response || []; + 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 { + await chrome.scripting.executeScript({ + target: { tabId }, + files: ["content.js"] + }); + } 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); } });