perf: cache userSettings, improve #1013

This commit is contained in:
Anthony Fu 2023-01-14 10:55:09 +01:00
parent 55aff4778b
commit d2ef57bcfa
3 changed files with 36 additions and 17 deletions

View file

@ -1,6 +1,6 @@
import { createClient, fetchV1Instance } from 'masto' import { createClient, fetchV1Instance } from 'masto'
import type { mastodon } from 'masto' import type { mastodon } from 'masto'
import type { Ref } from 'vue' import type { EffectScope, Ref } from 'vue'
import type { MaybeComputedRef, RemovableRef } from '@vueuse/core' import type { MaybeComputedRef, RemovableRef } from '@vueuse/core'
import type { ElkMasto, UserLogin } from '~/types' import type { ElkMasto, UserLogin } from '~/types'
import { import {
@ -266,18 +266,34 @@ export function checkLogin() {
return true return true
} }
interface UseUserLocalStorageCache {
scope: EffectScope
value: Ref<Record<string, any>>
}
/** /**
* Create reactive storage for the current user * Create reactive storage for the current user
*/ */
export function useUserLocalStorage<T extends object>(key: string, initial: () => T) { export function useUserLocalStorage<T extends object>(key: string, initial: () => T) {
const all = useLocalStorage<Record<string, T>>(key, {}, { deep: true }) // @ts-expect-error bind value to the function
return computed(() => { const map: Map<string, UseUserLocalStorageCache> = useUserLocalStorage._ = useUserLocalStorage._ || new Map()
const id = currentUser.value?.account.id
? currentUser.value.account.acct if (!map.has(key)) {
: '[anonymous]' const scope = effectScope(true)
all.value[id] = Object.assign(initial(), all.value[id] || {}) const value = scope.run(() => {
return all.value[id] const all = useLocalStorage<Record<string, T>>(key, {}, { deep: true })
}) return computed(() => {
const id = currentUser.value?.account.id
? currentUser.value.account.acct
: '[anonymous]'
all.value[id] = Object.assign(initial(), all.value[id] || {})
return all.value[id]
})
})
map.set(key, { scope, value: value! })
}
return map.get(key)!.value
} }
/** /**
@ -290,10 +306,12 @@ export function clearUserLocalStorage(account?: mastodon.v1.Account) {
return return
const id = `${account.acct}@${currentInstance.value?.uri || currentServer.value}` const id = `${account.acct}@${currentInstance.value?.uri || currentServer.value}`
// @ts-expect-error bind value to the function // @ts-expect-error bind value to the function
;(useUserLocalStorage._ as Map<string, Ref<Record<string, any>>> | undefined)?.forEach((storage) => { const cacheMap = useUserLocalStorage._ as Map<string, UseUserLocalStorageCache> | undefined
if (storage.value[id]) cacheMap?.forEach(({ value }) => {
delete storage.value[id] if (value.value[id])
delete value.value[id]
}) })
} }

View file

@ -11,6 +11,9 @@ const errorCodes: Record<number, string> = {
404: 'Page not found', 404: 'Page not found',
} }
if (process.dev)
console.error(error)
const defaultMessage = 'Something went wrong' const defaultMessage = 'Something went wrong'
const message = error.message ?? errorCodes[error.statusCode!] ?? defaultMessage const message = error.message ?? errorCodes[error.statusCode!] ?? defaultMessage

View file

@ -11,15 +11,13 @@ export default defineNuxtPlugin(() => {
innerHTML: ` innerHTML: `
;(function() { ;(function() {
const handle = localStorage.getItem('${STORAGE_KEY_CURRENT_USER_HANDLE}') const handle = localStorage.getItem('${STORAGE_KEY_CURRENT_USER_HANDLE}')
if (!handle) if (!handle) { return }
return
const allSettings = JSON.parse(localStorage.getItem('${STORAGE_KEY_SETTINGS}') || '{}') const allSettings = JSON.parse(localStorage.getItem('${STORAGE_KEY_SETTINGS}') || '{}')
const settings = allSettings[handle] const settings = allSettings[handle]
if (!settings) if (!settings) { return }
return
const html = document.querySelector('html') const html = document.querySelector('html')
${process.dev ? 'console.log(\'settings\', settings)' : ''} ${process.dev ? 'console.log({ settings })' : ''}
const { fontSize, language } = settings || {} const { fontSize, language } = settings || {}