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:
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user