chore: Improve perf of new tab loading by caching team policy in localStorage (#2351)

This commit is contained in:
Tom Moor
2021-07-21 18:53:57 -04:00
committed by GitHub
parent 140b04c126
commit 3090c2cfa3
2 changed files with 21 additions and 6 deletions

View File

@ -14,6 +14,12 @@ import { getCookieDomain } from "utils/domains";
const AUTH_STORE = "AUTH_STORE"; const AUTH_STORE = "AUTH_STORE";
const NO_REDIRECT_PATHS = ["/", "/create", "/home"]; const NO_REDIRECT_PATHS = ["/", "/create", "/home"];
type PersistedData = {
user?: User,
team?: Team,
policies?: Policy[],
};
type Provider = {| type Provider = {|
id: string, id: string,
name: string, name: string,
@ -30,6 +36,7 @@ export default class AuthStore {
@observable user: ?User; @observable user: ?User;
@observable team: ?Team; @observable team: ?Team;
@observable token: ?string; @observable token: ?string;
@observable policies: Policy[] = [];
@observable lastSignedIn: ?string; @observable lastSignedIn: ?string;
@observable isSaving: boolean = false; @observable isSaving: boolean = false;
@observable isSuspended: boolean = false; @observable isSuspended: boolean = false;
@ -41,7 +48,7 @@ export default class AuthStore {
this.rootStore = rootStore; this.rootStore = rootStore;
// attempt to load the previous state of this store from localstorage // attempt to load the previous state of this store from localstorage
let data = {}; let data: PersistedData = {};
try { try {
data = JSON.parse(localStorage.getItem(AUTH_STORE) || "{}"); data = JSON.parse(localStorage.getItem(AUTH_STORE) || "{}");
} catch (_) { } catch (_) {
@ -63,7 +70,9 @@ export default class AuthStore {
// signin/signout events in other tabs and follow suite. // signin/signout events in other tabs and follow suite.
window.addEventListener("storage", (event) => { window.addEventListener("storage", (event) => {
if (event.key === AUTH_STORE) { if (event.key === AUTH_STORE) {
const data = JSON.parse(event.newValue); // data may be null if key is deleted in localStorage
const data: ?PersistedData = JSON.parse(event.newValue);
if (!data) return;
// if there is no user on the new data then we know the other tab // if there is no user on the new data then we know the other tab
// signed out and we should do the same. Otherwise, if we're not // signed out and we should do the same. Otherwise, if we're not
@ -78,22 +87,25 @@ export default class AuthStore {
} }
@action @action
rehydrate(data: { user: User, team: Team }) { rehydrate(data: PersistedData) {
this.user = new User(data.user); this.user = new User(data.user);
this.team = new Team(data.team); this.team = new Team(data.team);
this.token = getCookie("accessToken"); this.token = getCookie("accessToken");
this.lastSignedIn = getCookie("lastSignedIn"); this.lastSignedIn = getCookie("lastSignedIn");
this.addPolicies(data.policies);
if (this.token) { if (this.token) {
setImmediate(() => this.fetch()); setImmediate(() => this.fetch());
} }
} }
addPolicies = (policies: Policy[]) => { addPolicies(policies?: Policy[]) {
if (policies) { if (policies) {
// cache policies in this store so that they are persisted between sessions
this.policies = policies;
policies.forEach((policy) => this.rootStore.policies.add(policy)); policies.forEach((policy) => this.rootStore.policies.add(policy));
} }
}; }
@computed @computed
get authenticated(): boolean { get authenticated(): boolean {
@ -105,6 +117,7 @@ export default class AuthStore {
return JSON.stringify({ return JSON.stringify({
user: this.user, user: this.user,
team: this.team, team: this.team,
policies: this.policies,
}); });
} }
@ -210,6 +223,7 @@ export default class AuthStore {
JSON.stringify({ JSON.stringify({
user: null, user: null,
team: null, team: null,
policies: [],
}) })
); );

View File

@ -39,6 +39,8 @@ export default class RootStore {
toasts: ToastsStore; toasts: ToastsStore;
constructor() { constructor() {
// PoliciesStore must be initialized before AuthStore
this.policies = new PoliciesStore(this);
this.apiKeys = new ApiKeysStore(this); this.apiKeys = new ApiKeysStore(this);
this.auth = new AuthStore(this); this.auth = new AuthStore(this);
this.collections = new CollectionsStore(this); this.collections = new CollectionsStore(this);
@ -50,7 +52,6 @@ export default class RootStore {
this.memberships = new MembershipsStore(this); this.memberships = new MembershipsStore(this);
this.notificationSettings = new NotificationSettingsStore(this); this.notificationSettings = new NotificationSettingsStore(this);
this.presence = new DocumentPresenceStore(); this.presence = new DocumentPresenceStore();
this.policies = new PoliciesStore(this);
this.revisions = new RevisionsStore(this); this.revisions = new RevisionsStore(this);
this.shares = new SharesStore(this); this.shares = new SharesStore(this);
this.ui = new UiStore(); this.ui = new UiStore();