Skip to content

Commit 1da99a2

Browse files
committed
[PERF] web_editor: cache applyModifications result
This commit caches the result of applyModifications. This results in greatly reduced loading times when applying any modification to images. task-3847470
1 parent f3e4e94 commit 1da99a2

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

addons/web_editor/static/src/js/editor/image_processing.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ const modifierFields = [
2424
];
2525
export const isGif = (mimetype) => mimetype === 'image/gif';
2626

27+
/**
28+
* applyModifications cache
29+
* @type {Object.<string, ApplyModificationsReturnType>}
30+
*/
31+
const applyModificationsCache = {};
32+
2733
// webgl color filters
2834
const _applyAll = (result, filter, filters) => {
2935
filters.forEach(f => {
@@ -199,14 +205,19 @@ const glFilters = {
199205
applyAll(filter, filters);
200206
},
201207
};
208+
209+
/**
210+
* @typedef {{dataURL: string, mimetype: string}} ApplyModificationsReturnType
211+
*/
202212
/**
203213
* Applies data-attributes modifications to an img tag and returns a dataURL
204214
* containing the result. This function does not modify the original image.
215+
* Caches results in memory for better performance.
205216
*
206217
* @param {HTMLImageElement} img the image to which modifications are applied
207218
* @param {boolean} returnResultWithMimetype false by default to not break
208219
* compatibility, *must* be set to true. TODO: remove in master
209-
* @returns {Promise<{dataURL: string, mimetype: string}>} dataURL of the image
220+
* @returns {Promise<ApplyModificationsReturnType>} dataURL of the image
210221
* with the applied modifications and the actual output mimetype.
211222
*/
212223
export async function applyModifications(img, dataOptions = {}, returnResultWithMimetype = false) {
@@ -216,6 +227,19 @@ export async function applyModifications(img, dataOptions = {}, returnResultWith
216227
quality: '75',
217228
forceModification: false,
218229
}, img.dataset, dataOptions);
230+
231+
const cacheKey = JSON.stringify(data);
232+
const cachedResult = applyModificationsCache[cacheKey];
233+
if (cachedResult) {
234+
235+
// TODO: remove in master, see jsdoc for returnResultWithMimetype parameter
236+
if (!returnResultWithMimetype) {
237+
return cachedResult.dataURL;
238+
}
239+
240+
return cachedResult;
241+
}
242+
219243
let {
220244
width,
221245
height,
@@ -359,18 +383,20 @@ export async function applyModifications(img, dataOptions = {}, returnResultWith
359383
: await _loadImageDataURL(originalSrc);
360384
}
361385

386+
let returnValue;
362387
if (isChanged || originalSize >= newSize) {
363-
return {
388+
returnValue = {
364389
dataURL: imageData.dataURL,
365390
mimetype: imageData.mimetype,
366391
};
367392
} else {
368393
const originalDataURL = await _loadImageDataURL(originalSrc);
369-
return {
394+
returnValue = {
370395
dataURL: originalDataURL,
371396
mimetype: extractMimetypeFromDataURL(originalDataURL),
372397
};
373398
}
399+
return (applyModificationsCache[cacheKey] = returnValue);
374400
}
375401

376402
/**

0 commit comments

Comments
 (0)