3

雅虎网站加速最佳实践指出:

将脚本放在底部

我的 Django 应用程序中有两种类型的脚本:

  1. 我的基本(例如继承的)模板中包含的脚本;和
  2. 由模板标签实例化的模板内编写的脚本

支持 UI 控件的脚本必须是模板的一部分,因为它们支持模板标签来处理诸如唯一 ID 之类的内容并将相关代码保持在一起。

问题是,如果我按照雅虎的建议将库(#1)放在页面底部,100% 的内联脚本(#2)将失败,因为库尚未加载和解析。

我不能在我的基本模板中扩展 {% block %} 元素,因为我在模板标签的上下文中所做的任何事情都不会传播到它之外——通过设计,以避免变量名冲突(根据 Django 的文档)。

有谁知道如何将 JavaScript 从我的模板标签的模板中推迟到我的基本模板的底部呈现?

4

3 回答 3

4

我通常有这样的基本模板设置。

<html>
<head>

{% block js-head %} Tags that need to go up top  {% endblock js-head %}

</head>
<body>
{% block header %}  Header {% endblock header %}

{% block body %} Body goes here {% endblock body %}

{% block footer %}  Footer {% endblock footer %}

{% block js-foot %}  All other javascript goes here {% endblock js-foot %}
</body>
</html>

然后我可以扩展这个基本模板并且只覆盖我关心的块。我将所有不必放在 js-foot 标题中的 javascript 都放在了 js-foot 中,因为它位于模板的底部,所以它会最后加载。如果您必须移动 javascript 加载的位置,您只需在基本模板中移动 js-foot 块。

没什么花哨的,但它有效。

于 2011-06-21T00:45:46.823 回答
1

包装您包含在内联的脚本

jQuery(函数(){ ... });

当 DOM 准备好并且脚本已下载时将执行。

另一种选择可能是创建某种自定义模板标签,例如:

{% inlinescript %}
// some javascript code.
{% endinlinescript %}

随着执行的进行,您可以使用它来聚合内联脚本。当模板被解析时,您需要聚合这些数据——这会变得很棘手,因为模板标签具有不同的上下文,而这是您希望将其存储在自定义变量中的全局上下文中,例如inline_scripts.

我将看看 Djangowith ... as ..在默认模板库中实现各种构造的方式,以了解如何将您自己的变量添加到上下文中。

然后在页面底部,您可以执行 {{ inline_scripts }}。

最简单的解决方案是jQuery.ready(function(){}) / jQuery(function(){ })(这两种方法是同义词)。

或者你可能想重新考虑雅虎的建议。内联 javascript 有一些积极的方面 - 它可以减少 FOUC / FOUBC(不行为内容的 Flash)。雅虎往往有点迂腐——(看看 YUI API ;)。如果您需要重写应用程序的某些部分以获得适度可察觉的性能改进,那可能不值得。


要进行脚本聚合(最初基于 django-snippets 上的捕获):

@register.tag(name='aggregate')
def do_aggregate(parser, token):
    try:
        tag_name, args = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError("'aggregate' node requires a variable name.")
    nodelist = parser.parse(('endaggregate',))
    parser.delete_first_token()
    return AggregateNode(nodelist, args)

class AggregateNode(Node):
    def __init__(self, nodelist, varname):
        self.nodelist = nodelist
        self.varname = varname

    def render(self, context):
        output = self.nodelist.render(context)
        if context.has_key(self.varname):
            context[self.varname] += output
        else:
            context[self.varname] = output
        return ''

用法:

{% aggregate inline_scripts %}
var foo = 'bar';
{% endaggregate %}

... template code

{% aggregate inline_scripts %}
var baz = 'bar';
{% endaggregate %}

... somewhere near the bottom of your page

{{ inline_scripts }}
于 2010-11-04T21:15:49.760 回答
1

有一个应用程序django-sekizai就是为了这个

于 2014-09-29T12:45:14.483 回答