From 2b8a1ece05619c2edd53d24026d1377328ea3a55 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 14 Mar 2013 11:14:22 +0530 Subject: [PATCH] speed hack: store pages and doctypes in localstorage --- public/js/legacy/widgets/form/form.js | 24 +++--------------- public/js/wn/app.js | 18 ++++++++++++++ public/js/wn/model/model.js | 35 +++++++++++++++++++-------- public/js/wn/model/sync.js | 2 ++ public/js/wn/request.js | 2 +- public/js/wn/views/pageview.js | 11 ++++++++- webnotes/boot.py | 4 +-- webnotes/db.py | 2 ++ webnotes/widgets/form/load.py | 28 ++++++--------------- 9 files changed, 71 insertions(+), 55 deletions(-) diff --git a/public/js/legacy/widgets/form/form.js b/public/js/legacy/widgets/form/form.js index 0b37c609b3..4b49de1f99 100644 --- a/public/js/legacy/widgets/form/form.js +++ b/public/js/legacy/widgets/form/form.js @@ -903,27 +903,11 @@ _f.Frm.prototype.reload_doc = function() { me.refresh(); } - if(me.doc.__islocal) { - wn.call({ - method: "webnotes.widgets.form.load.getdoctype", - args: { - doctype: me.doctype - }, - callback: function(r) { - me.refresh(); - } + if(!me.doc.__islocal) { + wn.model.remove_from_locals(me.doctype, me.docname); + wn.model.with_doc(me.doctype, me.docname, function() { + me.refresh(); }) - } else { - wn.call({ - method: "webnotes.widgets.form.load.getdoc", - args: { - doctype: me.doctype, - name: me.docname - }, - callback: function(r) { - me.refresh(); - } - }); } } diff --git a/public/js/wn/app.js b/public/js/wn/app.js index a0213d29c2..12ef61a387 100644 --- a/public/js/wn/app.js +++ b/public/js/wn/app.js @@ -78,6 +78,8 @@ wn.Application = Class.extend({ if(wn.boot) { wn.control_panel = wn.boot.control_panel; this.set_globals(); + this.sync_pages(); + } else { this.set_as_guest(); } @@ -92,6 +94,22 @@ wn.Application = Class.extend({ user_email = profile.email; sys_defaults = wn.boot.sysdefaults; }, + sync_pages: function() { + // clear cached pages if timestamp is not found + if(localStorage["page_info"]) { + wn.boot.allowed_pages = []; + page_info = JSON.parse(localStorage["page_info"]); + $.each(wn.boot.page_info, function(name, modified) { + if(page_info[name]!=modified) { + delete localStorage["_page:" + name]; + } + wn.boot.allowed_pages.push(name); + }); + } else { + wn.boot.allowed_pages = keys(wn.boot.page_info); + } + localStorage["page_info"] = JSON.stringify(wn.boot.page_info); + }, set_as_guest: function() { // for backward compatibility profile = {name:'Guest'}; diff --git a/public/js/wn/model/model.js b/public/js/wn/model/model.js index c64e5ec62f..682c31382a 100644 --- a/public/js/wn/model/model.js +++ b/public/js/wn/model/model.js @@ -61,30 +61,45 @@ $.extend(wn.model, { if(locals.DocType[doctype]) { callback(); } else { + var cached_timestamp = null; + if(localStorage["_doctype:" + doctype]) { + var cached_doclist = JSON.parse(localStorage["_doctype:" + doctype]); + cached_timestamp = cached_doclist[0].modified; + } wn.call({ method:'webnotes.widgets.form.load.getdoctype', type: "GET", args: { doctype: doctype, - with_parent: 1 + with_parent: 1, + cached_timestamp: cached_timestamp }, callback: function(r) { - var meta = locals.DocType[doctype]; - if(meta.__list_js) { - eval(meta.__list_js); - } - if(meta.__calendar_js) { - eval(meta.__calendar_js); - } - if(meta.__map_js) { - eval(meta.__map_js); + if(r.message=="use_cache") { + wn.model.sync(cached_doclist); + } else { + localStorage["_doctype:" + doctype] = JSON.stringify(r.docs); } + wn.model.init_doctype(doctype); callback(r); } }); } }, + init_doctype: function(doctype) { + var meta = locals.DocType[doctype]; + if(meta.__list_js) { + eval(meta.__list_js); + } + if(meta.__calendar_js) { + eval(meta.__calendar_js); + } + if(meta.__map_js) { + eval(meta.__map_js); + } + }, + with_doc: function(doctype, name, callback) { if(!name) name = doctype; // single type if(locals[doctype] && locals[doctype][name]) { diff --git a/public/js/wn/model/sync.js b/public/js/wn/model/sync.js index 59db79bda5..bf7cf0ecf5 100644 --- a/public/js/wn/model/sync.js +++ b/public/js/wn/model/sync.js @@ -54,6 +54,8 @@ $.extend(wn.model, { delete sync_in[d.doctype][d.localname]; } }); + + return doclist; }, expand: function(data) { diff --git a/public/js/wn/request.js b/public/js/wn/request.js index e59305396f..a40ca93b9e 100644 --- a/public/js/wn/request.js +++ b/public/js/wn/request.js @@ -173,7 +173,7 @@ wn.request.cleanup = function(opts, r) { } if(r.docs) { - wn.model.sync(r.docs); + r.docs = wn.model.sync(r.docs); } if(r.__messages) { $.extend(wn._messages, r.__messages); diff --git a/public/js/wn/views/pageview.js b/public/js/wn/views/pageview.js index 3e2fb3bc4f..70fc99fdb4 100644 --- a/public/js/wn/views/pageview.js +++ b/public/js/wn/views/pageview.js @@ -15,12 +15,21 @@ wn.views.pageview = { } if((locals.Page && locals.Page[name]) || name==window.page_name) { + // already loaded + callback(); + } if(localStorage["_page:" + name]) { + // cached in local storage + wn.model.sync(JSON.parse(localStorage["_page:" + name])); callback(); } else { + // get fresh wn.call({ method: 'webnotes.widgets.page.getpage', args: {'name':name }, - callback: callback + callback: function(r) { + localStorage["_page:" + name] = JSON.stringify(r.docs); + callback(); + } }); } }, diff --git a/webnotes/boot.py b/webnotes/boot.py index d72c8165b6..ac925d7804 100644 --- a/webnotes/boot.py +++ b/webnotes/boot.py @@ -87,8 +87,8 @@ def load_country_and_currency(bootinfo, doclist): where ifnull(enabled,0)=1""", as_dict=1, update={"doctype":":Currency"}) def add_allowed_pages(bootinfo): - bootinfo.allowed_pages = [p[0] for p in webnotes.conn.sql("""select distinct parent from `tabPage Role` - where role in ('%s')""" % "', '".join(webnotes.get_roles()))] + bootinfo.page_info = dict(webnotes.conn.sql("""select distinct parent, modified from `tabPage Role` + where role in ('%s')""" % "', '".join(webnotes.get_roles()))) def load_translations(bootinfo): try: diff --git a/webnotes/db.py b/webnotes/db.py index b20dd9aa8d..1aebbab59a 100644 --- a/webnotes/db.py +++ b/webnotes/db.py @@ -406,6 +406,8 @@ class Database: def exists(self, dt, dn=None): if isinstance(dt, basestring): + if dt==dn: + return True # single always exists (!) try: return self.sql('select name from `tab%s` where name=%s' % (dt, '%s'), dn) except: diff --git a/webnotes/widgets/form/load.py b/webnotes/widgets/form/load.py index 3d1c41f336..ae8fe713dc 100644 --- a/webnotes/widgets/form/load.py +++ b/webnotes/widgets/form/load.py @@ -42,40 +42,31 @@ def getdoc(doctype, name, user=None): # single doclist = load_single_doc(doctype, name, user or webnotes.session.user) - # load doctype along with the doc - if webnotes.form_dict.get('getdoctype'): - import webnotes.model.doctype - doclist += webnotes.model.doctype.get(doctype, processed=True) - webnotes.response['docs'] = doclist @webnotes.whitelist() -def getdoctype(): +def getdoctype(doctype, with_parent=False, cached_timestamp=None): """load doctype""" import webnotes.model.doctype import webnotes.model.meta doclist = [] - dt = webnotes.form_dict.get('doctype') - with_parent = webnotes.form_dict.get('with_parent') - # with parent (called from report builder) if with_parent: - parent_dt = webnotes.model.meta.get_parent_dt(dt) + parent_dt = webnotes.model.meta.get_parent_dt(doctype) if parent_dt: doclist = webnotes.model.doctype.get(parent_dt, processed=True) webnotes.response['parent_dt'] = parent_dt if not doclist: - doclist = webnotes.model.doctype.get(dt, processed=True) + doclist = webnotes.model.doctype.get(doctype, processed=True) + + if cached_timestamp and doclist[0].modified==cached_timestamp: + return "use_cache" - # if single, send the record too - if doclist[0].issingle: - doclist += webnotes.model.doc.get(dt) - # load search criteria for reports (all) - doclist +=get_search_criteria(dt) + doclist +=get_search_criteria(doctype) webnotes.response['docs'] = doclist @@ -98,11 +89,6 @@ def load_single_doc(dt, dn, user): if dl and not dn.startswith('_'): webnotes.user.update_recent(dt, dn) - # load search criteria ---- if doctype - # ----- TO BE DEPRECATED ----- - if dt=='DocType': - dl += get_search_criteria(dt) - return dl