perf: HTTP cache list view counts when count is >1000 (#29871)
This allows for caching the count which are frequently requested but rarely change and even if they changed, UI doesn't show accurate value to begin with. After this change any filters that result in "1,000+" response will be just cached by client and won't be requested again and again (for at least 30 minutes, it's SWR after that so UI should still be snappy)
This commit is contained in:
parent
e4a2b8db38
commit
930d006f4c
4 changed files with 28 additions and 15 deletions
|
|
@ -67,6 +67,9 @@ def get_count() -> int:
|
|||
args.fields = [fieldname]
|
||||
partial_query = execute(**args, run=0)
|
||||
count = frappe.db.sql(f"""select count(*) from ( {partial_query} ) p""")[0][0]
|
||||
|
||||
if count == args.limit:
|
||||
frappe.response.can_cache = True
|
||||
else:
|
||||
args.fields = [f"count({fieldname}) as total_count"]
|
||||
count = execute(**args)[0].get("total_count")
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ frappe.db = {
|
|||
frappe.call("frappe.client.delete", { doctype, name }, (r) => resolve(r.message));
|
||||
});
|
||||
},
|
||||
count: function (doctype, args = {}) {
|
||||
count: function (doctype, args = {}, cache = false) {
|
||||
let filters = args.filters || {};
|
||||
let limit = args.limit;
|
||||
|
||||
|
|
@ -115,13 +115,18 @@ frappe.db = {
|
|||
|
||||
const fields = [];
|
||||
|
||||
return frappe.xcall("frappe.desk.reportview.get_count", {
|
||||
doctype,
|
||||
filters,
|
||||
fields,
|
||||
distinct,
|
||||
limit,
|
||||
});
|
||||
return frappe.xcall(
|
||||
"frappe.desk.reportview.get_count",
|
||||
{
|
||||
doctype,
|
||||
filters,
|
||||
fields,
|
||||
distinct,
|
||||
limit,
|
||||
},
|
||||
cache ? "GET" : "POST",
|
||||
{ cache }
|
||||
);
|
||||
},
|
||||
get_link_options(doctype, txt = "", filters = {}) {
|
||||
return new Promise((resolve) => {
|
||||
|
|
|
|||
|
|
@ -1008,10 +1008,14 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
let count_without_children = this.data.uniqBy((d) => d.name).length;
|
||||
|
||||
return frappe.db
|
||||
.count(this.doctype, {
|
||||
filters: this.get_filters_for_args(),
|
||||
limit: this.count_upper_bound,
|
||||
})
|
||||
.count(
|
||||
this.doctype,
|
||||
{
|
||||
filters: this.get_filters_for_args(),
|
||||
limit: this.count_upper_bound,
|
||||
},
|
||||
Boolean(this.count_upper_bound)
|
||||
)
|
||||
.then((total_count) => {
|
||||
this.total_count = total_count || current_count;
|
||||
this.count_without_children =
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ frappe.request.ajax_count = 0;
|
|||
frappe.request.waiting_for_ajax = [];
|
||||
frappe.request.logs = {};
|
||||
|
||||
frappe.xcall = function (method, params, type) {
|
||||
frappe.xcall = function (method, params, type, opts = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
frappe.call({
|
||||
method: method,
|
||||
|
|
@ -22,6 +22,7 @@ frappe.xcall = function (method, params, type) {
|
|||
error: (r) => {
|
||||
reject(r?.message);
|
||||
},
|
||||
...opts,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -118,11 +119,11 @@ frappe.call = function (opts) {
|
|||
freeze_message: opts.freeze_message,
|
||||
headers: opts.headers || {},
|
||||
error_handlers: opts.error_handlers || {},
|
||||
// show_spinner: !opts.no_spinner,
|
||||
async: opts.async,
|
||||
silent: opts.silent,
|
||||
api_version: opts.api_version,
|
||||
url,
|
||||
cache: opts.cache,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -268,7 +269,7 @@ frappe.request.call = function (opts) {
|
|||
},
|
||||
opts.headers
|
||||
),
|
||||
cache: window.dev_server ? false : true,
|
||||
cache: window.dev_server ? false : opts.cache || false,
|
||||
};
|
||||
|
||||
if (opts.args && opts.args.doctype) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue