Skip to content

Commit

Permalink
perf: cache google/bunny font metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
danielroe committed Feb 21, 2024
1 parent 80a5a57 commit ca2ddb1
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
21 changes: 21 additions & 0 deletions src/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createStorage } from 'unstorage'
import fsDriver from 'unstorage/drivers/fs'

import type { Awaitable } from './types'

// TODO: refactor to use nitro storage when possible
const storage = createStorage({
driver: fsDriver({
base: 'node_modules/.cache/nuxt-fonts',
})
})

export async function cachedData<T = unknown> (key: string, fetcher: () => Awaitable<T>, ttl = 1000 * 60 * 60 * 24 * 7) {
const cached = await storage.getItem<null | { expires: number, data: T }>(key)
if (!cached || cached.expires < Date.now()) {
const data = await fetcher()
await storage.setItem(key, { expires: Date.now() + ttl, data })
return data
}
return cached.data
}
10 changes: 7 additions & 3 deletions src/providers/bunny.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { $fetch } from 'ofetch'
import { hash } from 'ohash'

import type { FontProvider, ResolveFontFacesOptions } from '../types'
import { extractFontFaceData, addLocalFallbacks } from '../css/parse'
import { cachedData } from '../cache'

export default {
async setup () {
Expand All @@ -10,11 +13,13 @@ export default {
if (!isBunnyFont(fontFamily)) { return }

return {
fonts: await getFontDetails(fontFamily, defaults)
fonts: await cachedData(`bunny:${fontFamily}-${hash(defaults)}-data.json`, () => getFontDetails(fontFamily, defaults))
}
},
} satisfies FontProvider

/** internal */

const fontAPI = $fetch.create({
baseURL: 'https://fonts.bunny.net'
})
Expand All @@ -34,9 +39,8 @@ interface BunnyFontMeta {
let fonts: BunnyFontMeta
const familyMap = new Map<string, string>()

// TODO: Fetch and cache
async function initialiseFontMeta () {
fonts = await fontAPI<BunnyFontMeta>('/list', { responseType: 'json' })
fonts = await cachedData('bunny:meta.json', () => fontAPI<BunnyFontMeta>('/list', { responseType: 'json' }))
for (const id in fonts) {
familyMap.set(fonts[id]!.familyName!, id)
}
Expand Down
17 changes: 11 additions & 6 deletions src/providers/google.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { $fetch } from 'ofetch'
import { hash } from 'ohash'

import type { FontProvider, ResolveFontFacesOptions } from '../types'
import { extractFontFaceData, addLocalFallbacks } from '../css/parse'
import { cachedData } from '../cache'

export default {
async setup () {
Expand All @@ -11,7 +13,7 @@ export default {
if (!isGoogleFont(fontFamily)) { return }

return {
fonts: await getFontDetails(fontFamily, defaults)
fonts: await cachedData(`google:${fontFamily}-${hash(defaults)}-data.json`, () => getFontDetails(fontFamily, defaults))
}
},
} satisfies FontProvider
Expand All @@ -27,14 +29,17 @@ interface FontIndexMeta {
}>
}

/** internal */

let fonts: FontIndexMeta[]

// TODO: Fetch and cache possible Google fonts
async function fetchFontMetadata () {
return await $fetch<{ familyMetadataList: FontIndexMeta[] }>('https://fonts.google.com/metadata/fonts')
.then(r => r.familyMetadataList)
}

async function initialiseFontMeta () {
const { familyMetadataList } = await $fetch<{ familyMetadataList: FontIndexMeta[] }>('/metadata/fonts', {
baseURL: 'https://fonts.google.com'
})
fonts = familyMetadataList
fonts = await cachedData('google:meta.json', fetchFontMetadata)
}

function isGoogleFont (family: string) {
Expand Down

0 comments on commit ca2ddb1

Please sign in to comment.