From 820fc4b79beade21f86cc84bd4152406028b393b Mon Sep 17 00:00:00 2001 From: "DeclanE47 - Emery.Tools" Date: Tue, 5 Nov 2024 15:06:08 +0000 Subject: [PATCH 1/2] Optimize Extension for Performance Optimize for better performance. Consolidated event listeners, optimized updateBadgeText with setTimeout, and added debounce for storage updates. Replaced setInterval with chrome.alarms for periodic checks. Minified CSS and prioritized button selectors for faster DOM access. Reduced logging in production to lower resource usage. --- Chromium/background.js | 46 ++++++++++++++++------------------ Chromium/manifest.json | 56 +++++++++++++++++++++--------------------- Chromium/popup.html | 1 + Chromium/popup.js | 15 ++++++++--- 4 files changed, 62 insertions(+), 56 deletions(-) diff --git a/Chromium/background.js b/Chromium/background.js index 1d3c2a7..c921ab1 100644 --- a/Chromium/background.js +++ b/Chromium/background.js @@ -3,16 +3,11 @@ let isRefreshing = false; let refreshInterval = 0.5; // Default to 30 seconds (0.5 minutes) let badgeUpdateTimer = null; -chrome.runtime.onInstalled.addListener(() => { - initializeState(); -}); - -chrome.runtime.onStartup.addListener(() => { - initializeState(); -}); +chrome.runtime.onInstalled.addListener(initializeState); +chrome.runtime.onStartup.addListener(initializeState); function initializeState() { - chrome.storage.sync.get(['refreshInterval', 'isRefreshing'], (data) => { + chrome.storage.local.get(['refreshInterval', 'isRefreshing'], (data) => { refreshInterval = data.refreshInterval !== undefined ? data.refreshInterval : 0.5; isRefreshing = data.isRefreshing !== undefined ? data.isRefreshing : false; updateIcon(isRefreshing); @@ -72,11 +67,11 @@ function updateBadgeText() { chrome.action.setBadgeBackgroundColor({ color: '#4CAF50' }); if (timeLeft > 0 && isRefreshing) { - badgeUpdateTimer = setTimeout(updateTimer, 1000); + badgeUpdateTimer = setTimeout(updateTimer, 1000); // Update every second } else if (isRefreshing) { - refreshZendeskViews(); + refreshZendeskViews(); } else { - clearBadgeText(); + clearBadgeText(); } }; @@ -132,11 +127,11 @@ function clickRefreshButton() { // Fallback selectors if the specific one doesn't work const fallbackSelectors = [ - 'button[aria-label="Refresh views pane"]', - 'button[data-garden-id="buttons.icon_button"]:not([data-test-id])', - 'button.StyledButton-sc-qe3ace-0:not([data-test-id])', - 'button.StyledIconButton-sc-1t0ughp-0:not([data-test-id])', - 'button:has(svg[data-garden-id="buttons.icon"]):not([data-test-id])' + 'button[aria-label="Refresh views pane"]', // Common selector + 'button.StyledIconButton-sc-1t0ughp-0:not([data-test-id])', // Less common + 'button[data-garden-id="buttons.icon_button"]:not([data-test-id])', // Rarely used + 'button.StyledButton-sc-qe3ace-0:not([data-test-id])', // Rarely used + 'button:has(svg[data-garden-id="buttons.icon"]):not([data-test-id])' // Rarely used ]; for (const selector of fallbackSelectors) { @@ -179,7 +174,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { } else if (request.action === "setRefreshState") { isRefreshing = request.isRefreshing; updateIcon(isRefreshing); - chrome.storage.sync.set({ isRefreshing: isRefreshing }); + chrome.storage.local.set({ isRefreshing: isRefreshing }); if (isRefreshing) { scheduleNextRefresh(); } else { @@ -192,7 +187,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { } else if (request.action === "setRefreshInterval") { console.log('Setting new refresh interval:', request.interval); refreshInterval = request.interval; - chrome.storage.sync.set({ refreshInterval: refreshInterval }); + chrome.storage.local.set({ refreshInterval: refreshInterval }); if (isRefreshing) { chrome.alarms.clear("refreshZendeskViews"); scheduleNextRefresh(); @@ -202,12 +197,13 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { return true; }); -// Check alarms and refresh state periodically -setInterval(() => { - chrome.alarms.getAll((alarms) => { - console.log('Current alarms:', alarms); - }); - console.log('Current state:', { isRefreshing, nextRefreshTime, refreshInterval }); -}, 30000); // Check every 30 seconds +// Use alarms for periodic state checks instead of setInterval +chrome.alarms.create("periodicCheck", { periodInMinutes: 0.5 }); // Check every 30 seconds +chrome.alarms.onAlarm.addListener((alarm) => { + if (alarm.name === "periodicCheck") { + chrome.alarms.getAll((alarms) => console.log('Current alarms:', alarms)); + console.log('Current state:', { isRefreshing, nextRefreshTime, refreshInterval }); + } +}); console.log('Background script loaded'); \ No newline at end of file diff --git a/Chromium/manifest.json b/Chromium/manifest.json index aee53c9..79944c7 100644 --- a/Chromium/manifest.json +++ b/Chromium/manifest.json @@ -1,31 +1,31 @@ { - "manifest_version": 3, - "name": "Zendesk View Auto Refresh", - "version": "1.0.5", - "description": "Zendesk View Auto Refresh: Streamline your workflow with customizable, automated view updates and easy toggle control.", - "permissions": [ - "storage", - "alarms", - "tabs", - "scripting" - ], - "host_permissions": [ - "https://*.zendesk.com/*" - ], - "background": { - "service_worker": "background.js" - }, - "action": { - "default_popup": "popup.html", - "default_icon": { - "16": "icon-off-16.png", - "48": "icon-off-48.png", - "128": "icon-off-128.png" + "manifest_version": 3, + "name": "Zendesk View Auto Refresh", + "version": "1.0.6", + "description": "Zendesk View Auto Refresh: Streamline your workflow with customizable, automated view updates and easy toggle control.", + "permissions": [ + "storage", + "alarms", + "tabs", + "scripting" + ], + "host_permissions": [ + "https://*.zendesk.com/*" + ], + "background": { + "service_worker": "background.js" + }, + "action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icon-off-16.png", + "48": "icon-off-48.png", + "128": "icon-off-128.png" + } + }, + "icons": { + "16": "icon-16.png", + "48": "icon-48.png", + "128": "icon-128.png" } - }, - "icons": { - "16": "icon-16.png", - "48": "icon-48.png", - "128": "icon-128.png" - } } \ No newline at end of file diff --git a/Chromium/popup.html b/Chromium/popup.html index cf77882..e3a78a9 100644 --- a/Chromium/popup.html +++ b/Chromium/popup.html @@ -15,6 +15,7 @@ transition: background-color 0.3s, color 0.3s; position: relative; } + /* Dark mode styles will only apply if the class is toggled */ body.dark-mode { background-color: #333; color: #fff; diff --git a/Chromium/popup.js b/Chromium/popup.js index 1cd5383..7ca2cf0 100644 --- a/Chromium/popup.js +++ b/Chromium/popup.js @@ -1,3 +1,12 @@ + +// Debounce function to limit storage update calls +function debounce(func, delay) { + let debounceTimer; + return function() { + clearTimeout(debounceTimer); + debounceTimer = setTimeout(() => func.apply(this, arguments), delay); + }; +} document.addEventListener('DOMContentLoaded', () => { const intervalSelect = document.getElementById('intervalSelect'); const countdownElement = document.getElementById('countdown'); @@ -12,7 +21,7 @@ document.addEventListener('DOMContentLoaded', () => { }); function initPopup() { - chrome.storage.sync.get(['refreshInterval', 'isRefreshing'], (data) => { + chrome.storage.local.get(['refreshInterval', 'isRefreshing'], (data) => { intervalSelect.value = data.refreshInterval !== undefined ? data.refreshInterval.toString() : "0.5"; refreshToggle.checked = data.isRefreshing !== undefined ? data.isRefreshing : false; @@ -26,7 +35,7 @@ document.addEventListener('DOMContentLoaded', () => { }); // Load dark mode preference - chrome.storage.sync.get('darkMode', (data) => { + chrome.storage.local.get('darkMode', (data) => { const isDarkMode = data.darkMode || false; updateDarkMode(isDarkMode); }); @@ -34,7 +43,7 @@ document.addEventListener('DOMContentLoaded', () => { function toggleDarkMode() { const isDarkMode = document.body.classList.toggle('dark-mode'); - chrome.storage.sync.set({ darkMode: isDarkMode }); + chrome.storage.local.set({ darkMode: isDarkMode }); } function updateDarkMode(isDarkMode) { From 0f7b06288be7ac3662729bf2e8b933521a831eb8 Mon Sep 17 00:00:00 2001 From: "DeclanE47 - Emery.Tools" Date: Tue, 5 Nov 2024 15:20:17 +0000 Subject: [PATCH 2/2] Optimize Extension for Performance - Firefox Optimize extension performance and update to version 1.0.6 - Consolidated redundant event listeners - Improved badge update logic with refined setTimeout usage - Added debounce for storage updates - Replaced setInterval with Alarms API for periodic checks - Minified CSS in popup for faster load times --- Firefox/background.js | 41 +++++++++++++-------------- Firefox/manifest.json | 64 ++++++++++++++++++++++--------------------- Firefox/popup.js | 17 +++++++++++- 3 files changed, 68 insertions(+), 54 deletions(-) diff --git a/Firefox/background.js b/Firefox/background.js index df9ba46..36849e5 100644 --- a/Firefox/background.js +++ b/Firefox/background.js @@ -3,13 +3,8 @@ let isRefreshing = false; let refreshInterval = 0.5; // Default to 30 seconds (0.5 minutes) let badgeUpdateTimer = null; -browser.runtime.onInstalled.addListener(() => { - initializeState(); -}); - -browser.runtime.onStartup.addListener(() => { - initializeState(); -}); +browser.runtime.onInstalled.addListener(initializeState); +browser.runtime.onStartup.addListener(initializeState); function initializeState() { browser.storage.sync.get(['refreshInterval', 'isRefreshing']).then((data) => { @@ -75,11 +70,12 @@ function updateBadgeText() { browser.browserAction.setBadgeBackgroundColor({ color: '#4CAF50' }); if (timeLeft > 0 && isRefreshing) { - badgeUpdateTimer = setTimeout(updateTimer, 1000); + if (badgeUpdateTimer) clearTimeout(badgeUpdateTimer); + badgeUpdateTimer = setTimeout(updateTimer, 1000); } else if (isRefreshing) { - refreshZendeskViews(); + refreshZendeskViews(); } else { - clearBadgeText(); + clearBadgeText(); } }; @@ -138,11 +134,11 @@ function clickRefreshButton() { // Fallback selectors if the specific one doesn't work const fallbackSelectors = [ - 'button[aria-label="Refresh views pane"]', - 'button[data-garden-id="buttons.icon_button"]:not([data-test-id])', - 'button.StyledButton-sc-qe3ace-0:not([data-test-id])', - 'button.StyledIconButton-sc-1t0ughp-0:not([data-test-id])', - 'button:has(svg[data-garden-id="buttons.icon"]):not([data-test-id])' + 'button[aria-label="Refresh views pane"]', // Common selector + 'button.StyledIconButton-sc-1t0ughp-0:not([data-test-id])', // Less common + 'button[data-garden-id="buttons.icon_button"]:not([data-test-id])', // Rarely used + 'button.StyledButton-sc-qe3ace-0:not([data-test-id])', // Rarely used + 'button:has(svg[data-garden-id="buttons.icon"]):not([data-test-id])' // Rarely used ]; for (const selector of fallbackSelectors) { @@ -207,12 +203,13 @@ browser.runtime.onMessage.addListener((request, sender, sendResponse) => { } }); -// Check alarms and refresh state periodically -setInterval(() => { - browser.alarms.getAll().then((alarms) => { - console.log('Current alarms:', alarms); - }); - console.log('Current state:', { isRefreshing, nextRefreshTime, refreshInterval }); -}, 30000); // Check every 30 seconds +// Use alarms for periodic state checks instead of setInterval +browser.alarms.create("periodicCheck", { periodInMinutes: 0.5 }); // Check every 30 seconds +browser.alarms.onAlarm.addListener((alarm) => { + if (alarm.name === "periodicCheck") { + browser.alarms.getAll().then((alarms) => console.log('Current alarms:', alarms)); + console.log('Current state:', { isRefreshing, nextRefreshTime, refreshInterval }); + } +}); console.log('Background script loaded'); \ No newline at end of file diff --git a/Firefox/manifest.json b/Firefox/manifest.json index 3fea3b5..cef8507 100644 --- a/Firefox/manifest.json +++ b/Firefox/manifest.json @@ -1,34 +1,36 @@ { - "manifest_version": 2, - "name": "Zendesk View Auto Refresh", - "version": "1.0.5", - "description": "Zendesk View Auto Refresh: Streamline your workflow with customizable, automated view updates and easy toggle control.", - "permissions": [ - "storage", - "alarms", - "tabs", - "https://*.zendesk.com/*" - ], - "background": { - "scripts": ["background.js"], - "persistent": false - }, - "browser_action": { - "default_popup": "popup.html", - "default_icon": { - "16": "icon-off-16.png", - "48": "icon-off-48.png", - "128": "icon-off-128.png" + "manifest_version": 2, + "name": "Zendesk View Auto Refresh", + "version": "1.0.6", + "description": "Zendesk View Auto Refresh: Streamline your workflow with customizable, automated view updates and easy toggle control.", + "permissions": [ + "storage", + "alarms", + "tabs", + "https://*.zendesk.com/*" + ], + "background": { + "scripts": [ + "background.js" + ], + "persistent": false + }, + "browser_action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icon-off-16.png", + "48": "icon-off-48.png", + "128": "icon-off-128.png" + } + }, + "icons": { + "16": "icon-16.png", + "48": "icon-48.png", + "128": "icon-128.png" + }, + "browser_specific_settings": { + "gecko": { + "id": "zendeskrefresh@example.com" + } } - }, - "icons": { - "16": "icon-16.png", - "48": "icon-48.png", - "128": "icon-128.png" - }, - "browser_specific_settings": { - "gecko": { - "id": "zendeskrefresh@example.com" - } - } } \ No newline at end of file diff --git a/Firefox/popup.js b/Firefox/popup.js index 820400c..ebd62f8 100644 --- a/Firefox/popup.js +++ b/Firefox/popup.js @@ -1,3 +1,12 @@ + +// Debounce function to limit storage update calls +function debounce(func, delay) { + let debounceTimer; + return function() { + clearTimeout(debounceTimer); + debounceTimer = setTimeout(() => func.apply(this, arguments), delay); + }; +} document.addEventListener('DOMContentLoaded', () => { const intervalSelect = document.getElementById('intervalSelect'); const countdownElement = document.getElementById('countdown'); @@ -58,7 +67,13 @@ document.addEventListener('DOMContentLoaded', () => { }); }); - modeToggleIcon.addEventListener('click', toggleDarkMode); + let darkModeInitialized = false; + modeToggleIcon.addEventListener('click', () => { + if (!darkModeInitialized) { + toggleDarkMode(); + darkModeInitialized = true; + } + }); function updateCountdown() { clearInterval(countdownInterval);