diff --git a/src/util/dateFormat.ts b/src/util/dateFormat.ts index c833c81e6..7d37c34c3 100644 --- a/src/util/dateFormat.ts +++ b/src/util/dateFormat.ts @@ -1,4 +1,5 @@ import { LangFn } from '../hooks/useLang'; +import withCache from './withCache'; const WEEKDAYS_FULL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; const MONTHS_FULL = [ @@ -246,18 +247,8 @@ export function formatVoiceRecordDuration(durationInMs: number) { return `${parts.join(':')},${String(milliseconds).padStart(2, '0')}`; } -// `toLocaleString` is slow so we use cache -const dateFormatCache = new Map(); - -export function formatDateToString(datetime: Date | number, locale = 'en-US') { - const date = typeof datetime === 'number' ? new Date(datetime) : datetime; - const cacheKey = `${locale}_${getDayStartAt(date)}`; - const cached = dateFormatCache.get(cacheKey); - if (cached) { - return cached; - } - - const newValue = date.toLocaleString( +const formatDayToStringWithCache = withCache((dayStartAt: number, locale: string) => { + return new Date(dayStartAt).toLocaleString( locale, { year: 'numeric', @@ -265,10 +256,13 @@ export function formatDateToString(datetime: Date | number, locale = 'en-US') { day: 'numeric', }, ); +}); - dateFormatCache.set(cacheKey, newValue); +export function formatDateToString(datetime: Date | number, locale = 'en-US') { + const date = typeof datetime === 'number' ? new Date(datetime) : datetime; + const dayStartAt = getDayStartAt(date); - return newValue; + return formatDayToStringWithCache(dayStartAt, locale); } export function formatDateTimeToString(datetime: Date | number, locale = 'en-US') { diff --git a/src/util/textFormat.ts b/src/util/textFormat.ts index 3ee9b6b66..798b648e4 100644 --- a/src/util/textFormat.ts +++ b/src/util/textFormat.ts @@ -1,5 +1,6 @@ import EMOJI_REGEX from '../lib/twemojiRegex'; import { fixNonStandardEmoji } from './emoji'; +import withCache from './withCache'; export function formatInteger(value: number) { return String(value).replace(/\d(?=(\d{3})+$)/g, '$& '); @@ -26,7 +27,7 @@ export function formatIntegerCompact(views: number) { return `${formatFixedNumber(views / 1e6)}M`; } -export function getFirstLetters(phrase: string, count = 2) { +export const getFirstLetters = withCache((phrase: string, count = 2) => { return phrase .replace(/[.,!@#$%^&*()_+=\-`~[\]/\\{}:"|<>?]+/gi, '') .trim() @@ -42,4 +43,4 @@ export function getFirstLetters(phrase: string, count = 2) { return word.match(/./u)![0].toUpperCase(); }) .join(''); -} +}); diff --git a/src/util/withCache.ts b/src/util/withCache.ts new file mode 100644 index 000000000..5041a5862 --- /dev/null +++ b/src/util/withCache.ts @@ -0,0 +1,24 @@ +const cache = new WeakMap>(); + +export default function withCache(fn: T) { + return (...args: Parameters): ReturnType => { + let fnCache = cache.get(fn); + const cacheKey = args.map(String).join('_'); + + if (fnCache) { + const cached = fnCache.get(cacheKey); + if (cached) { + return cached; + } + } else { + fnCache = new Map(); + cache.set(fn, fnCache); + } + + const newValue = fn(...args); + + fnCache.set(cacheKey, newValue); + + return newValue; + }; +}