throttle DOM updates in manager while importing (#950)

This commit is contained in:
tophf 2020-06-01 03:14:42 +03:00 committed by GitHub
parent d9f5ef138c
commit 39c62e684e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 10 deletions

View File

@ -1,11 +1,15 @@
/* global messageBox styleSectionsEqual API onDOMready /* global messageBox styleSectionsEqual API onDOMready
tryJSONparse scrollElementIntoView $ $$ API $create t animateElement tryJSONparse scrollElementIntoView $ $$ API $create t animateElement
styleJSONseemsValid */ styleJSONseemsValid */
/* exported bulkChangeQueue bulkChangeTime */
'use strict'; 'use strict';
const STYLISH_DUMP_FILE_EXT = '.txt'; const STYLISH_DUMP_FILE_EXT = '.txt';
const STYLUS_BACKUP_FILE_EXT = '.json'; const STYLUS_BACKUP_FILE_EXT = '.json';
let bulkChangeQueue = [];
let bulkChangeTime = 0;
onDOMready().then(() => { onDOMready().then(() => {
$('#file-all-styles').onclick = event => { $('#file-all-styles').onclick = event => {
event.preventDefault(); event.preventDefault();
@ -136,6 +140,8 @@ function importFromString(jsonString) {
items.push({info, item}); items.push({info, item});
} }
}); });
bulkChangeQueue.length = 0;
bulkChangeTime = performance.now();
return API.importManyStyles(items.map(i => i.item)) return API.importManyStyles(items.map(i => i.item))
.then(styles => { .then(styles => {
for (let i = 0; i < styles.length; i++) { for (let i = 0; i < styles.length; i++) {

View File

@ -8,6 +8,7 @@ global messageBox getStyleWithNoCode
URLS enforceInputRange t tWordBreak formatDate URLS enforceInputRange t tWordBreak formatDate
getOwnTab getActiveTab openURL animateElement sessionStorageHash debounce getOwnTab getActiveTab openURL animateElement sessionStorageHash debounce
scrollElementIntoView CHROME VIVALDI FIREFOX router scrollElementIntoView CHROME VIVALDI FIREFOX router
bulkChangeTime:true bulkChangeQueue
*/ */
'use strict'; 'use strict';
@ -16,6 +17,8 @@ let installed;
const ENTRY_ID_PREFIX_RAW = 'style-'; const ENTRY_ID_PREFIX_RAW = 'style-';
const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW; const ENTRY_ID_PREFIX = '#' + ENTRY_ID_PREFIX_RAW;
const BULK_THROTTLE_MS = 100;
const newUI = { const newUI = {
enabled: prefs.get('manage.newUI'), enabled: prefs.get('manage.newUI'),
favicons: prefs.get('manage.newUI.favicons'), favicons: prefs.get('manage.newUI.favicons'),
@ -62,11 +65,13 @@ function onRuntimeMessage(msg) {
switch (msg.method) { switch (msg.method) {
case 'styleUpdated': case 'styleUpdated':
case 'styleAdded': case 'styleAdded':
API.getStyle(msg.style.id, true)
.then(style => handleUpdate(style, msg));
break;
case 'styleDeleted': case 'styleDeleted':
handleDelete(msg.style.id); bulkChangeQueue.push(msg);
if (performance.now() - bulkChangeTime < BULK_THROTTLE_MS) {
debounce(handleBulkChange, BULK_THROTTLE_MS);
} else {
handleBulkChange();
}
break; break;
case 'styleApply': case 'styleApply':
case 'styleReplaceAll': case 'styleReplaceAll':
@ -529,6 +534,26 @@ Object.assign(handleEvent, {
}); });
function handleBulkChange() {
for (const msg of bulkChangeQueue) {
const {id} = msg.style;
if (msg.method === 'styleDeleted') {
handleDelete(id);
bulkChangeTime = performance.now();
} else {
handleUpdateForId(id, msg);
}
}
bulkChangeQueue.length = 0;
}
function handleUpdateForId(id, opts) {
return API.getStyle(id, true).then(style => {
handleUpdate(style, opts);
bulkChangeTime = performance.now();
});
}
function handleUpdate(style, {reason, method} = {}) { function handleUpdate(style, {reason, method} = {}) {
if (reason === 'editPreview' || reason === 'editPreviewEnd') return; if (reason === 'editPreview' || reason === 'editPreviewEnd') return;
let entry; let entry;
@ -677,15 +702,14 @@ function onVisibilityChange() {
// page restored without reloading via history navigation (currently only in FF) // page restored without reloading via history navigation (currently only in FF)
// the catch here is that DOM may be outdated so we'll at least refresh the just edited style // the catch here is that DOM may be outdated so we'll at least refresh the just edited style
// assuming other changes aren't important enough to justify making a complicated DOM sync // assuming other changes aren't important enough to justify making a complicated DOM sync
case 'visible': case 'visible': {
if (sessionStorage.justEditedStyleId) { const id = sessionStorage.justEditedStyleId;
API.getStyle(Number(sessionStorage.justEditedStyleId), true) if (id) {
.then(style => { handleUpdateForId(Number(id), {method: 'styleUpdated'});
handleUpdate(style, {method: 'styleUpdated'});
});
delete sessionStorage.justEditedStyleId; delete sessionStorage.justEditedStyleId;
} }
break; break;
}
// going away // going away
case 'hidden': case 'hidden':
history.replaceState({scrollY: window.scrollY}, document.title); history.replaceState({scrollY: window.scrollY}, document.title);