refactor: LRU cache images

This commit is contained in:
cha0s 2021-02-05 00:03:22 -06:00
parent 9e0e08e194
commit 4bd5aec2b8
3 changed files with 23 additions and 8 deletions

View File

@ -37,7 +37,8 @@
"@pixi/text": "^5.3.6", "@pixi/text": "^5.3.6",
"autoprefixer": "^9.8.6", "autoprefixer": "^9.8.6",
"debug": "4.3.1", "debug": "4.3.1",
"image-size": "^0.9.3" "image-size": "^0.9.3",
"lru-cache": "^6.0.0"
}, },
"devDependencies": { "devDependencies": {
"@neutrinojs/airbnb": "^9.4.0", "@neutrinojs/airbnb": "^9.4.0",

View File

@ -1,8 +1,17 @@
import {Resource} from '@avocado/resource'; import {Resource} from '@avocado/resource';
import {imageSize} from 'image-size'; import {imageSize} from 'image-size';
import LRU from 'lru-cache';
const cache = new LRU({
dispose: (url) => URL.revokeObjectURL(url),
max: 128,
maxAge: Infinity,
});
export class Image extends Resource { export class Image extends Resource {
#objectUrl;
constructor() { constructor() {
super(); super();
this.texture = { this.texture = {
@ -14,9 +23,6 @@ export class Image extends Resource {
destroy() { destroy() {
if (!this.texture.isFake) { if (!this.texture.isFake) {
if (this.objectUrl) {
URL.revokeObjectURL(this.objectUrl);
}
this.texture.destroy(); this.texture.destroy();
} }
} }
@ -25,14 +31,22 @@ export class Image extends Resource {
return this.texture.height; return this.texture.height;
} }
async load(buffer) { async load(buffer, uri) {
if (buffer) { if (buffer) {
if ('client' === process.env.SIDE) { if ('client' === process.env.SIDE) {
// eslint-disable-next-line global-require // eslint-disable-next-line global-require
const {Texture} = require('@pixi/core'); const {Texture} = require('@pixi/core');
this.objectUrl = URL.createObjectURL(new Blob([buffer])); let url;
if (cache.has(uri)) {
url = cache.get(uri);
}
else {
url = URL.createObjectURL(new Blob([buffer]));
cache.set(uri, url);
}
this.#objectUrl = url;
const native = window.document.createElement('img'); const native = window.document.createElement('img');
native.src = this.objectUrl; native.src = this.#objectUrl;
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
native.addEventListener('error', reject); native.addEventListener('error', reject);
native.addEventListener('load', () => { native.addEventListener('load', () => {

View File

@ -32,7 +32,7 @@ export default class Resource extends decorate(Class) {
const buffer = await this.read(uri); const buffer = await this.read(uri);
const resource = new this(); const resource = new this();
resource.uri = uri; resource.uri = uri;
await resource.load(buffer); await resource.load(buffer, uri);
return resource; return resource;
} }