fix: Improve performance of most hit APIs in widget (#11089)

- Cache campaigns for better performance
- Fix N+1 queries in inbox members
- Remove unused related articles
This commit is contained in:
Pranav
2025-03-14 17:37:36 -07:00
committed by GitHub
parent ed970ee190
commit 46ec92c86e
6 changed files with 47 additions and 31 deletions

View File

@@ -7,6 +7,7 @@ import {
const state = {
records: [],
uiFlags: {
hasFetched: false,
isError: false,
},
activeCampaign: {},
@@ -30,6 +31,7 @@ const resetCampaignTimers = (
export const getters = {
getCampaigns: $state => $state.records,
getUIFlags: $state => $state.uiFlags,
getActiveCampaign: $state => $state.activeCampaign,
};
@@ -53,15 +55,21 @@ export const actions = {
}
},
initCampaigns: async (
{ getters: { getCampaigns: campaigns }, dispatch },
{ getters: { getCampaigns: campaigns, getUIFlags: uiFlags }, dispatch },
{ currentURL, websiteToken, isInBusinessHours }
) => {
if (!campaigns.length) {
dispatch('fetchCampaigns', {
websiteToken,
currentURL,
isInBusinessHours,
});
// This check is added to ensure that the campaigns are fetched once
// On high traffic sites, if the campaigns are empty, the API is called
// every time the user changes the URL (in case of the SPA)
// So, we need to ensure that the campaigns are fetched only once
if (!uiFlags.hasFetched) {
dispatch('fetchCampaigns', {
websiteToken,
currentURL,
isInBusinessHours,
});
}
} else {
resetCampaignTimers(
campaigns,
@@ -127,6 +135,7 @@ export const actions = {
export const mutations = {
setCampaigns($state, data) {
$state.records = data;
$state.uiFlags.hasFetched = true;
},
setActiveCampaign($state, data) {
$state.activeCampaign = data;

View File

@@ -63,15 +63,37 @@ describe('#actions', () => {
};
it('sends correct actions if campaigns are empty', async () => {
await actions.initCampaigns(
{ dispatch, getters: { getCampaigns: [] } },
{
dispatch,
getters: { getCampaigns: [], getUIFlags: { hasFetched: false } },
},
actionParams
);
expect(dispatch.mock.calls).toEqual([['fetchCampaigns', actionParams]]);
expect(campaignTimer.initTimers).not.toHaveBeenCalled();
});
it('do not refetch if the campaigns are fetched once', async () => {
await actions.initCampaigns(
{
dispatch,
getters: { getCampaigns: [], getUIFlags: { hasFetched: true } },
},
actionParams
);
expect(dispatch.mock.calls).toEqual([]);
expect(campaignTimer.initTimers).not.toHaveBeenCalled();
});
it('resets time if campaigns are available', async () => {
await actions.initCampaigns(
{ dispatch, getters: { getCampaigns: campaigns } },
{
dispatch,
getters: {
getCampaigns: campaigns,
getUIFlags: { hasFetched: true },
},
},
actionParams
);
expect(dispatch.mock.calls).toEqual([]);

View File

@@ -7,9 +7,10 @@ vi.mock('widget/store/index.js', () => ({
describe('#mutations', () => {
describe('#setCampaigns', () => {
it('set campaign records', () => {
const state = { records: [] };
const state = { records: [], uiFlags: {} };
mutations.setCampaigns(state, campaigns);
expect(state.records).toEqual(campaigns);
expect(state.uiFlags.hasFetched).toEqual(true);
});
});