初级开发者咨询Chrome密码管理器扩展API调用优化方案
优化密码管理器Chrome扩展的Token同步与GraphQL调用方案
当前实现通过每秒轮询获取网站localStorage中的JWT令牌并调用GraphQL接口,存在性能冗余问题。以下是针对性的优化方案,兼顾性能与用户体验:
核心优化思路
- 监听Token变化而非定时轮询:仅在网站的
id_token发生变更时同步到扩展存储,避免每秒重复执行脚本 - 按需触发GraphQL请求:仅当令牌更新时才调用接口,减少不必要的网络请求
- 避免重复注入脚本:确保每个目标页面只注册一次监听逻辑,防止内存泄漏
优化后代码实现
1. 改造Token同步逻辑(替换原getBearerKey)
export const initTokenSync = async () => { const deployedSite = await chrome.tabs.query({ url: 'https://passwordmanager-zep7.onrender.com/*' }); const page = deployedSite[0]; if (page) { // 检查是否已注册过监听脚本,避免重复注入 const registeredScripts = await chrome.scripting.getRegisteredContentScripts({ ids: ['token-sync'] }); if (registeredScripts.length === 0) { await chrome.scripting.registerContentScripts([{ id: 'token-sync', matches: ['https://passwordmanager-zep7.onrender.com/*'], js: [{ code: ` // 初始同步一次Token const initialToken = localStorage.getItem('id_token'); chrome.storage.local.set({ bearerKey: initialToken }); // 监听跨页面的localStorage变化 window.addEventListener('storage', (e) => { if (e.key === 'id_token') { chrome.storage.local.set({ bearerKey: e.newValue }); } }); // 监听同页面内的Token修改(重写setItem) const originalSetItem = localStorage.setItem; localStorage.setItem = function(key, value) { originalSetItem.apply(this, arguments); if (key === 'id_token') { chrome.storage.local.set({ bearerKey: value }); } }; ` }], runAt: 'document_start' }]); } } };
2. 改造扩展启动与事件监听(替换原onInstalled逻辑)
import { checkAccounts } from "./api/checkAccounts.js" chrome.runtime.onInstalled.addListener(async () => { // 初始化Token同步 await initTokenSync(); // 监听扩展存储中的Token变化,按需触发接口请求 chrome.storage.local.onChanged.addListener((changes, areaName) => { if (areaName === 'local' && changes.bearerKey) { const newBearerKey = changes.bearerKey.newValue; checkLoginStatus(newBearerKey); checkAccounts(); } }); }); // 保留原checkLoginStatus逻辑,无需修改 export const checkLoginStatus = async (bearerKey) => { const graphqlEndpoint = 'https://passwordmanager-zep7.onrender.com/graphql'; const graphqlQuery = `query Me { me { _id username email password { _id text length uppercase lowercase number specialCharacter } accounts { _id username email websiteUrl notes created updated } } }`; try { const response = await fetch(graphqlEndpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${bearerKey}` }, body: JSON.stringify({ query: graphqlQuery }) }); const { data } = await response.json(); chrome.storage.local.set({ user: data }); } catch (error) { console.error('GraphQL Error:', error); } };
优化说明
- Token同步效率提升:通过
storage事件+重写localStorage.setItem,覆盖了跨页面和同页面的Token修改场景,仅在Token真正变化时同步,彻底消除每秒轮询的性能消耗 - 接口请求按需触发:GraphQL请求仅在Token更新时执行,避免了每秒重复请求,减轻服务器压力和扩展资源占用
- 避免重复脚本注入:通过
getRegisteredContentScripts检查已注册脚本,防止同一页面多次注入监听逻辑,避免内存泄漏
内容的提问来源于stack exchange,提问作者user21837583
相关产品推荐
相关产品推荐

