perf: Batched List Updates
* Perform batched list updates for a N documents made every second * list_update callbacks for doc refreshes maintained in cur_list.pending_document_refreshes
This commit is contained in:
parent
b3b846472e
commit
636c4701cf
1 changed files with 62 additions and 43 deletions
|
|
@ -1320,6 +1320,11 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
}
|
||||
|
||||
setup_realtime_updates() {
|
||||
this.pending_document_refreshes = [];
|
||||
setInterval(() => {
|
||||
this.process_document_refreshes();
|
||||
}, 1000);
|
||||
|
||||
if (this.list_view_settings && this.list_view_settings.disable_auto_refresh) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1333,28 +1338,42 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
return;
|
||||
}
|
||||
|
||||
const { doctype, name } = data;
|
||||
if (doctype !== this.doctype) return;
|
||||
this.pending_document_refreshes.push(data);
|
||||
});
|
||||
}
|
||||
|
||||
// filters to get only the doc with this name
|
||||
const call_args = this.get_call_args();
|
||||
call_args.args.filters.push([this.doctype, "name", "=", name]);
|
||||
call_args.args.start = 0;
|
||||
process_document_refreshes() {
|
||||
if (!this.pending_document_refreshes.length) return;
|
||||
|
||||
frappe.call(call_args).then(({ message }) => {
|
||||
if (!message) return;
|
||||
const data = frappe.utils.dict(message.keys, message.values);
|
||||
if (!(data && data.length)) {
|
||||
// this doc was changed and should not be visible
|
||||
// in the listview according to filters applied
|
||||
// let's remove it manually
|
||||
this.data = this.data.filter((d) => d.name !== name);
|
||||
this.render_list();
|
||||
return;
|
||||
}
|
||||
const names = this.pending_document_refreshes
|
||||
.filter((d) => d.doctype === this.doctype)
|
||||
.map((d) => d.name);
|
||||
this.pending_document_refreshes = this.pending_document_refreshes.filter(
|
||||
(d) => names.indexOf(d.name) === -1
|
||||
);
|
||||
|
||||
const datum = data[0];
|
||||
const index = this.data.findIndex((d) => d.name === datum.name);
|
||||
if (!names.length) return;
|
||||
|
||||
// filters to get only the doc with this name
|
||||
const call_args = this.get_call_args();
|
||||
call_args.args.filters.push([this.doctype, "name", "in", names]);
|
||||
call_args.args.start = 0;
|
||||
|
||||
frappe.call(call_args).then(({ message }) => {
|
||||
if (!message) return;
|
||||
const data = frappe.utils.dict(message.keys, message.values);
|
||||
|
||||
if (!(data && data.length)) {
|
||||
// this doc was changed and should not be visible
|
||||
// in the listview according to filters applied
|
||||
// let's remove it manually
|
||||
this.data = this.data.filter((d) => names.indexOf(d.name) === -1);
|
||||
this.render_list();
|
||||
return;
|
||||
}
|
||||
|
||||
data.forEach((datum) => {
|
||||
const index = this.data.findIndex((doc) => doc.name === datum.name);
|
||||
|
||||
if (index === -1) {
|
||||
// append new data
|
||||
|
|
@ -1363,31 +1382,31 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
// update this data in place
|
||||
this.data[index] = datum;
|
||||
}
|
||||
|
||||
this.data.sort((a, b) => {
|
||||
const a_value = a[this.sort_by] || "";
|
||||
const b_value = b[this.sort_by] || "";
|
||||
|
||||
let return_value = 0;
|
||||
if (a_value > b_value) {
|
||||
return_value = 1;
|
||||
}
|
||||
|
||||
if (b_value > a_value) {
|
||||
return_value = -1;
|
||||
}
|
||||
|
||||
if (this.sort_order === "desc") {
|
||||
return_value = -return_value;
|
||||
}
|
||||
return return_value;
|
||||
});
|
||||
this.toggle_result_area();
|
||||
this.render_list();
|
||||
if (this.$checks && this.$checks.length) {
|
||||
this.set_rows_as_checked();
|
||||
}
|
||||
});
|
||||
|
||||
this.data.sort((a, b) => {
|
||||
const a_value = a[this.sort_by] || "";
|
||||
const b_value = b[this.sort_by] || "";
|
||||
|
||||
let return_value = 0;
|
||||
if (a_value > b_value) {
|
||||
return_value = 1;
|
||||
}
|
||||
|
||||
if (b_value > a_value) {
|
||||
return_value = -1;
|
||||
}
|
||||
|
||||
if (this.sort_order === "desc") {
|
||||
return_value = -return_value;
|
||||
}
|
||||
return return_value;
|
||||
});
|
||||
if (this.$checks && this.$checks.length) {
|
||||
this.set_rows_as_checked();
|
||||
}
|
||||
this.toggle_result_area();
|
||||
this.render_list();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue