Combine all nanoui templates into a single resource bundle.

This reduces the number of assets needing to be sent on join by 150ish.
- Nanoui scripts modified to load templates in parallel instead of one at a time.
- Nanoui scripts modified to be willing to load from the resource bundle if available, falling back to ajax-loading the individual templates if absent.
This commit is contained in:
Leshana
2020-06-06 01:36:36 -04:00
parent 499b9b51f4
commit d6603a7302
3 changed files with 46 additions and 57 deletions

View File

@@ -308,7 +308,7 @@ You can set verify to TRUE if you want send() to sleep until the client has the
"nano/images/modular_computers/",
"nano/js/"
)
var/list/uncommon_dirs = list(
var/list/template_dirs = list(
"nano/templates/"
)
@@ -321,18 +321,21 @@ You can set verify to TRUE if you want send() to sleep until the client has the
if(fexists(path + filename))
common[filename] = fcopy_rsc(path + filename)
register_asset(filename, common[filename])
for(var/path in uncommon_dirs)
// Combine all templates into a single bundle.
var/list/template_data = list()
for(var/path in template_dirs)
var/list/filenames = flist(path)
for(var/filename in filenames)
if(copytext(filename, length(filename)) != "/") // Ignore directories.
if(fexists(path + filename))
register_asset(filename, fcopy_rsc(path + filename))
if(copytext(filename, length(filename) - 4) == ".tmpl") // Ignore directories.
template_data[filename] = file2text(path + filename)
var/template_bundle = "function nanouiTemplateBundle(){return [json_encode(template_data)];}"
var/fname = "data/nano_templates_bundle.js"
fdel(fname)
text2file(template_bundle, fname)
register_asset("nano_templates_bundle.js", fcopy_rsc(fname))
fdel(fname)
/datum/asset/nanoui/send(client, uncommon)
if(!islist(uncommon))
uncommon = list(uncommon)
send_asset_list(client, uncommon)
/datum/asset/nanoui/send(client)
send_asset_list(client, common)

View File

@@ -104,6 +104,7 @@ nanoui is used to open and update nano browser uis
/datum/nanoui/proc/add_common_assets()
add_script("libraries.min.js") // A JS file comprising of jQuery, doT.js and jQuery Timer libraries (compressed together)
add_script("nano_utility.js") // The NanoUtility JS, this is used to store utility functions.
add_script("nano_templates_bundle.js") // Contains all templates, generated by asset cache system at server start.
add_script("nano_template.js") // The NanoTemplate JS, this is used to render templates.
add_script("nano_state_manager.js") // The NanoStateManager JS, it handles updates from the server and passes data to the current state
add_script("nano_state.js") // The NanoState JS, this is the base state which all states must inherit from

View File

@@ -2,6 +2,7 @@
var NanoTemplate = function () {
var _templateData = {};
var _templateSources = {};
var _templates = {};
var _compiledTemplates = {};
@@ -15,59 +16,43 @@ var NanoTemplate = function () {
if (_templateData == null)
{
alert('Error: Template data did not load correctly.');
}
loadNextTemplate();
};
var loadNextTemplate = function () {
// we count the number of templates for this ui so that we know when they've all been rendered
var templateCount = Object.size(_templateData);
if (!templateCount)
{
$(document).trigger('templatesLoaded');
return;
}
// load markup for each template and register it
for (var key in _templateData)
{
if (!_templateData.hasOwnProperty(key))
{
continue;
}
$.when($.ajax({
url: _templateData[key],
if (('nanouiTemplateBundle' in window) && (typeof nanouiTemplateBundle === 'function')) {
_templateSources = nanouiTemplateBundle(); // From nanoui_templates.js
}
var templateLoadingPromises = $.map(_templateData, function(filename, key) {
var fetchSourcePromise;
if (_templateSources && _templateSources.hasOwnProperty(filename)) {
// Its in the bundle, just do it
fetchSourcePromise = $.Deferred().resolve(_templateSources[filename]).promise();
} else {
// Otherwise fetch from ze network
fetchSourcePromise = $.ajax({
url: filename,
cache: false,
dataType: 'text'
}))
.done(function(templateMarkup) {
templateMarkup += '<div class="clearBoth"></div>';
try
{
NanoTemplate.addTemplate(key, templateMarkup);
}
catch(error)
{
alert('ERROR: An error occurred while loading the UI: ' + error.message);
return;
}
delete _templateData[key];
loadNextTemplate();
})
.fail(function () {
alert('ERROR: Loading template ' + key + '(' + _templateData[key] + ') failed!');
});
}
return;
}
}
return fetchSourcePromise.done(function(templateMarkup) {
templateMarkup += '<div class="clearBoth"></div>';
try {
NanoTemplate.addTemplate(key, templateMarkup);
} catch(error) {
alert('ERROR: An error occurred while loading the UI: ' + error.message);
return;
}
}).fail(function () {
alert('ERROR: Loading template ' + key + '(' + _templateData[key] + ') failed!');
});
});
// Wait for all of them to be done and then trigger the event.
$.when.apply(this, templateLoadingPromises).done(function() {
$(document).trigger('templatesLoaded');
});
};
var compileTemplates = function () {