1111 */
1212
1313import {
14+ type AllStorageData ,
1415 clearState ,
1516 getUrlDetection ,
17+ loadAll ,
1618 loadState ,
1719 saveState ,
1820 setUrlDetection ,
@@ -194,17 +196,20 @@ async function findExistingAgentTab(
194196 * 3. Update that tab's URL and focus it
195197 * 4. Close the source tab
196198 *
199+ * PERFORMANCE: Accepts pre-loaded state to avoid redundant storage reads.
200+ * The caller loads state once via loadAll() and passes it through.
201+ *
197202 * @param sourceTabId - Tab ID that initiated the navigation
198203 * @param sourceUrl - URL being navigated to
199204 * @param match - Matched route details
205+ * @param state - Pre-loaded storage state (to minimize API calls)
200206 */
201207async function handleNavigation (
202208 sourceTabId : number ,
203209 _sourceUrl : string ,
204210 match : RouteMatch ,
211+ state : AllStorageData [ "state" ] ,
205212) : Promise < void > {
206- const state = await loadState ( ) ;
207-
208213 // Find existing LIVE agent tab for this subdomain (not the source tab)
209214 const existingTab = await findExistingAgentTab ( match . subdomain , sourceTabId , state . zendeskTabs ) ;
210215
@@ -239,14 +244,18 @@ async function handleNavigation(
239244}
240245
241246/**
242- * Track a tab as a Zendesk agent tab in state.
247+ * Track a tab as a Zendesk agent tab using pre-loaded state.
248+ * PERFORMANCE: Accepts pre-loaded state to avoid redundant storage reads.
243249 *
244250 * @param tabId - Tab ID to track
245251 * @param url - Current URL of the tab
252+ * @param state - Pre-loaded storage state (to minimize API calls)
246253 */
247- async function trackTab ( tabId : number , url : string ) : Promise < void > {
248- const state = await loadState ( ) ;
249-
254+ async function trackTabWithState (
255+ tabId : number ,
256+ url : string ,
257+ state : AllStorageData [ "state" ] ,
258+ ) : Promise < void > {
250259 // Extract subdomain from URL
251260 const match = matchZendeskUrl ( url ) ;
252261 if ( ! match ) {
@@ -355,16 +364,18 @@ export default defineBackground(() => {
355364 // Deduplication: Skip if we recently processed this exact navigation
356365 if ( isDuplicateNavigation ( details . tabId , details . url ) ) return ;
357366
358- const detection = await getUrlDetection ( ) ;
359- if ( detection === "noUrls" ) return ;
367+ // PERFORMANCE: Load ALL storage data in ONE API call
368+ // This batches getUrlDetection + loadState into a single chrome.storage.local.get()
369+ const { mode, state } = await loadAll ( ) ;
370+ if ( mode === "noUrls" ) return ;
360371
361372 const match = matchZendeskUrl ( details . url ) ;
362373 if ( ! match ) return ;
363374
364375 // For ticketUrls mode, only intercept ticket routes
365- if ( detection === "ticketUrls" && match . type !== "ticket" ) return ;
376+ if ( mode === "ticketUrls" && match . type !== "ticket" ) return ;
366377
367- await handleNavigation ( details . tabId , details . url , match ) ;
378+ await handleNavigation ( details . tabId , details . url , match , state ) ;
368379 } ,
369380 { url : [ { hostSuffix : "zendesk.com" } ] } ,
370381 ) ;
@@ -389,16 +400,17 @@ export default defineBackground(() => {
389400 // Deduplication: Skip if we recently processed this exact navigation
390401 if ( isDuplicateNavigation ( details . tabId , details . url ) ) return ;
391402
392- const detection = await getUrlDetection ( ) ;
393- if ( detection === "noUrls" ) return ;
403+ // PERFORMANCE: Load ALL storage data in ONE API call
404+ const { mode, state } = await loadAll ( ) ;
405+ if ( mode === "noUrls" ) return ;
394406
395407 const match = matchZendeskUrl ( details . url ) ;
396408 if ( ! match ) return ;
397409
398410 // For ticketUrls mode, only intercept ticket routes
399- if ( detection === "ticketUrls" && match . type !== "ticket" ) return ;
411+ if ( mode === "ticketUrls" && match . type !== "ticket" ) return ;
400412
401- await handleNavigation ( details . tabId , details . url , match ) ;
413+ await handleNavigation ( details . tabId , details . url , match , state ) ;
402414 } ,
403415 { url : [ { hostSuffix : "zendesk.com" } ] } ,
404416 ) ;
@@ -410,20 +422,25 @@ export default defineBackground(() => {
410422 * OPTIMIZATION: Only updates the SINGLE tab's icon instead of all tabs.
411423 * This is critical for performance when DLP extensions (like Incydr) are
412424 * monitoring chrome.* API calls - reduces O(N) to O(1) API calls per navigation.
425+ *
426+ * PERFORMANCE: Uses loadAll() to batch storage reads into single API call.
413427 */
414428 chrome . webNavigation . onDOMContentLoaded . addListener (
415429 async ( details ) => {
416430 // Only handle main frame
417431 if ( details . frameId !== 0 ) return ;
418432
419- // Track this tab
420- await trackTab ( details . tabId , details . url ) ;
433+ // PERFORMANCE: Load ALL storage data in ONE API call
434+ // This replaces: trackTab() + getUrlDetection() which was 3 separate reads
435+ const { mode, state } = await loadAll ( ) ;
436+
437+ // Track this tab (using pre-loaded state)
438+ await trackTabWithState ( details . tabId , details . url , state ) ;
421439
422440 // Enable action icon for this tab
423441 chrome . action . enable ( details . tabId ) ;
424442
425443 // Set icon state for THIS tab only (not all tabs)
426- const mode = await getUrlDetection ( ) ;
427444 await setTabIcon ( details . tabId , mode ) ;
428445 } ,
429446 { url : [ { urlContains : "zendesk.com/agent" } ] } ,
0 commit comments