Hidden divs for loading "lazy javascript"? Possible security / other problems?
I'm curious about people's opinions and thoughts about this situation. The reason I would like to lazy loading javascript is for performance. Loading javascript at the end of the body reduces browser blocking and results in much faster page loading.
But there is some kind of automation that I use to generate the html (specifically for django). This automation allows you to create forms using "Widgets" that output the content needed to render the entire widget (additional javascript, css, ...). The problem is that the widget wants to output the javascript immediately to the middle of the document, but I want all the javascript to be loaded at the end of the body.
When the following widget is added to the form, you can see that it displays the tags <script>...</script>
:
class AutoCompleteTagInput(forms.TextInput):
class Media:
css = {
'all': ('css/jquery.autocomplete.css', )
}
js = (
'js/jquery.bgiframe.js',
'js/jquery.ajaxQueue.js',
'js/jquery.autocomplete.js',
)
def render(self, name, value, attrs=None):
output = super(AutoCompleteTagInput, self).render(name, value, attrs)
page_tags = Tag.objects.usage_for_model(DataSet)
tag_list = simplejson.dumps([tag.name for tag in page_tags],
ensure_ascii=False)
return mark_safe(u'''<script type="text/javascript">
jQuery("#id_%s").autocomplete(%s, {
width: 150,
max: 10,
highlight: false,
scroll: true,
scrollHeight: 100,
matchContains: true,
autoFill: true
});
</script>''' % (name, tag_list,)) + output
I suggest that if someone is using <div class=".lazy-js">...</div>
with some css ( .lazy-js { display: none; }
) and some javascript ( jQuery('.lazy-js').each(function(index) { eval(jQuery(this).text()); }
), you can effectively force all javascript to load at the end of the page load: / p>
class AutoCompleteTagInput(forms.TextInput):
class Media:
css = {
'all': ('css/jquery.autocomplete.css', )
}
js = (
'js/jquery.bgiframe.js',
'js/jquery.ajaxQueue.js',
'js/jquery.autocomplete.js',
)
def render(self, name, value, attrs=None):
output = super(AutoCompleteTagInput, self).render(name, value, attrs)
page_tags = Tag.objects.usage_for_model(DataSet)
tag_list = simplejson.dumps([tag.name for tag in page_tags],
ensure_ascii=False)
return mark_safe(u'''<div class="lazy-js">
jQuery("#id_%s").autocomplete(%s, {
width: 150,
max: 10,
highlight: false,
scroll: true,
scrollHeight: 100,
matchContains: true,
autoFill: true
});
</div>''' % (name, tag_list,)) + output
Ignore all the details of my specific implementation (media specific), I'm looking for a consensus as to whether a method of using lazy loaded javascript via hidden hidden tags could create problems, whether security or otherwise?
One of the more convenient parts about this is that it fits the DRY principle pretty well IMO, because you don't have to hack a certain lazy load for every page instance. It just "works".
UPDATE . I'm not sure if django has the ability to enqueue things (via template inheritance inheritance or something?) For output just before the end </body>
?
a source to share
I would prefer a tool that allows me to "append" content to the output stream ( or ) add it to the buffer to be output at the end of the page, before the character </body>
.
I'm not sure which commercial tools support this (or django?), But this is how I created my frameworks.
As for your question about security / other concerns ... the script will process every time it is read (unless you output the script tag with the attribute defer
(in IE / newer browsers)) it physically moves, it does not change behavior, and does not make him "lazy".
Security, pulling content out of the script tag and calling eval()
on it opens you up to the possibility of something executing you didn't plan on. (unlikely, but possible)
a source to share
The problem is that the widget wants to output javascript immediately into the middle of the document, but I want to ensure all javascript loads at the end of the body.
Then I wouldn't use this widget. A dynamically supplied client side script from the client side is a disaster that will compromise security unless you or your user is wiser. How did you know if this code was compromised, for example?