Emoji Rendering Efficiency (#35568)

This commit is contained in:
Echo 2025-07-31 19:30:14 +02:00 committed by GitHub
commit 6bca52453a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 954 additions and 333 deletions

View file

@ -0,0 +1,78 @@
import { createLimitedCache } from '../cache';
describe('createCache', () => {
test('returns expected methods', () => {
const actual = createLimitedCache();
expect(actual).toBeTypeOf('object');
expect(actual).toHaveProperty('get');
expect(actual).toHaveProperty('has');
expect(actual).toHaveProperty('delete');
expect(actual).toHaveProperty('set');
});
test('caches values provided to it', () => {
const cache = createLimitedCache();
cache.set('test', 'result');
expect(cache.get('test')).toBe('result');
});
test('has returns expected values', () => {
const cache = createLimitedCache();
cache.set('test', 'result');
expect(cache.has('test')).toBeTruthy();
expect(cache.has('not found')).toBeFalsy();
});
test('updates a value if keys are the same', () => {
const cache = createLimitedCache();
cache.set('test1', 1);
cache.set('test1', 2);
expect(cache.get('test1')).toBe(2);
});
test('delete removes an item', () => {
const cache = createLimitedCache();
cache.set('test', 'result');
expect(cache.has('test')).toBeTruthy();
cache.delete('test');
expect(cache.has('test')).toBeFalsy();
expect(cache.get('test')).toBeUndefined();
});
test('removes oldest item cached if it exceeds a set size', () => {
const cache = createLimitedCache({ maxSize: 1 });
cache.set('test1', 1);
cache.set('test2', 2);
expect(cache.get('test1')).toBeUndefined();
expect(cache.get('test2')).toBe(2);
});
test('retrieving a value bumps up last access', () => {
const cache = createLimitedCache({ maxSize: 2 });
cache.set('test1', 1);
cache.set('test2', 2);
expect(cache.get('test1')).toBe(1);
cache.set('test3', 3);
expect(cache.get('test1')).toBe(1);
expect(cache.get('test2')).toBeUndefined();
expect(cache.get('test3')).toBe(3);
});
test('logs when cache is added to and removed', () => {
const log = vi.fn();
const cache = createLimitedCache({ maxSize: 1, log });
cache.set('test1', 1);
expect(log).toHaveBeenLastCalledWith(
'Added %s to cache, now size %d',
'test1',
1,
);
cache.set('test2', 1);
expect(log).toHaveBeenLastCalledWith(
'Added %s and deleted %s from cache, now size %d',
'test2',
'test1',
1,
);
});
});

View file

@ -0,0 +1,60 @@
export interface LimitedCache<CacheKey, CacheValue> {
has: (key: CacheKey) => boolean;
get: (key: CacheKey) => CacheValue | undefined;
delete: (key: CacheKey) => void;
set: (key: CacheKey, value: CacheValue) => void;
clear: () => void;
}
interface LimitedCacheArguments {
maxSize?: number;
log?: (...args: unknown[]) => void;
}
export function createLimitedCache<CacheValue, CacheKey = string>({
maxSize = 100,
log = () => null,
}: LimitedCacheArguments = {}): LimitedCache<CacheKey, CacheValue> {
const cacheMap = new Map<CacheKey, CacheValue>();
const cacheKeys = new Set<CacheKey>();
function touchKey(key: CacheKey) {
if (cacheKeys.has(key)) {
cacheKeys.delete(key);
}
cacheKeys.add(key);
}
return {
has: (key) => cacheMap.has(key),
get: (key) => {
if (cacheMap.has(key)) {
touchKey(key);
}
return cacheMap.get(key);
},
delete: (key) => cacheMap.delete(key) && cacheKeys.delete(key),
set: (key, value) => {
cacheMap.set(key, value);
touchKey(key);
const lastKey = cacheKeys.values().toArray().shift();
if (cacheMap.size > maxSize && lastKey) {
cacheMap.delete(lastKey);
cacheKeys.delete(lastKey);
log(
'Added %s and deleted %s from cache, now size %d',
key,
lastKey,
cacheMap.size,
);
} else {
log('Added %s to cache, now size %d', key, cacheMap.size);
}
},
clear: () => {
cacheMap.clear();
cacheKeys.clear();
},
};
}

View file

@ -0,0 +1,19 @@
//
// Tools for performance debugging, only enabled in development mode.
// Open up Chrome Dev Tools, then Timeline, then User Timing to see output.
import * as marky from 'marky';
import { isDevelopment } from './environment';
export function start(name: string) {
if (isDevelopment()) {
marky.mark(name);
}
}
export function stop(name: string) {
if (isDevelopment()) {
marky.stop(name);
}
}