Django-pipeline - 页面加载非常缓慢

10

我正在尝试使用django-pipeline来压缩静态资源、为它们使用缓存并简化我的模板。我的CSS和JS文件可以被浏览器找到和加载,但我的(非常简单的)主页需要大约10秒钟才能加载完成。

在这里输入图片描述

我正在使用Python 2.7.6、Django 1.7.3和django-pipeline 1.4.3。PyCharm使用本地虚拟环境运行开发服务器。

我的settings.py包含以下内容:

DEBUG = True
TEMPLATE_DEBUG = DEBUG

INSTALLED_APPS = (
    'django_admin_bootstrapped', # custom admin
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # pip installed apps
    'pipeline',
    # project apps
    'myapp',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'pipeline.middleware.MinifyHTMLMiddleware',
)

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'pipeline.finders.FileSystemFinder',
    'pipeline.finders.CachedFileFinder',
    'pipeline.finders.PipelineFinder',
)

STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'myapp/static'),
)

STATICFILES_STORAGE = 'pipeline.storage.PipelineCachedStorage'
PIPELINE_CSS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor'
PIPELINE_JS_COMPRESSOR = 'pipeline.compressors.yuglify.YuglifyCompressor'

PIPELINE_CSS = {
    'base': {
        'source_filenames': (
            'myapp/css/base.css',
            'myapp/bower_components/bootstrap/dist/css/bootstrap.css',
            'myapp/bower_components/Hover/css/hover.css',
            'myapp/bower_components/font-awesome/css/font-awesome.css',
        ),
        'output_filename': 'css/myapp.css',
    },
}

PIPELINE_JS = {
    'base': {
        'source_filenames': (
            'myapp/bower_components/jquery/dist/jquery.min.js',
            'myapp/bower_components/bootstrap/dist/js/bootstrap.min.js',
        ),
        'output_filename': 'js/myapp.js',
    },
}

我的基本HTML模板包含以下内容:

{% load staticfiles %}
{% load pipeline %}

<!DOCTYPE html>
<html>
    <head>
        [...]
        {% block css %}
            {% stylesheet 'base' %}
        {% endblock css %}

        {% block javascript %}
            {% javascript 'base' %}
        {% endblock javascript %}

    </head>
    <body> [...] </body>
</html>

我的home.html继承了base.html,但没有使用css和javascript管道的模板标签。

只是为了确保yuglify可用:

$ yuglify --version
0.1.4

我在这里做错了什么?

注意: 如果PIPELINE_ENABLED = True,浏览器无法找到静态资源(myapp.css和myapp.js)。


有什么进展吗?我在本地使用S3管道时也遇到了同样的问题。即,当我将DEBUG设置为True(默认值PIPELINE_ENABLED=False),它就会出现问题。启用管道后,它可以正常工作。 - John Lehmann
2
据我所记,页面加载非常缓慢,因为文件查找器需要遍历一个巨大的路径树。问题在于,在开发中使用debug=False时,必须使用特定的查找器:https://github.com/cyberdelia/django-pipeline/issues/418。我想我在创建这个主题时就到了这个点。因为我使用bower管理前端包,所有目录(src、dist等)和文件(.json或其他无用文件)都被包含在静态文件中! - Q Caron
1
请查看 https://github.com/cyberdelia/django-pipeline/issues/482 获取更多信息。 - Q Caron
你运行在哪个域上?我曾经使用dockerhost:8000时遇到过类似的问题,但当我改回localhost:8000后,它神秘地消失了。有时我想知道localhost是否具有比仅仅作为hosts文件中默认条目更高的特权。 - Craig Labenz
1个回答

2
问题是模板标签代码执行了一堆操作,包括在调试为True时每个请求都运行collectstatic,导致开发非常缓慢。即使debug为False,模板标签仍将连接并查询S3的几个内容。当文件是本地的时候,这不是一个(大)问题,但是使用S3时就会出现问题。我能想到的唯一解决方案是编写自己简化的模板标签pipelines.py
在你开始之前,有两个重要的事情需要知道,首先,为了让pipeline正常工作,我有一个空壳S3PipelineStorage,它结合了pipeline和boto,如果你已经有s3 + pipeline的工作方式,那么你可能已经拥有了这个,但这很重要:
from pipeline.storage import PipelineMixin
from storages.backends.s3boto import S3BotoStorage

class S3PipelineStorage(PipelineMixin, S3BotoStorage):
    pass

接下来在设置中:

STATICFILES_STORAGE = 'path.to.your.file.S3PipelineStorage'

现在,如果您查看模板标记,您会看到我使用staticfiles_storage.url与原始模板标记类似。这将把S3路径添加到相对路径中,但如果您不添加此设置,则每次查询S3以生成URL。您可以添加设置或仅硬编码您的S3路径而不是staticfiles_storage.url,但我建议您添加设置,因为它将提高在任何生成S3资源的URL的地方的性能。
AWS_S3_CUSTOM_DOMAIN = 'your_bucket-%s.s3.amazonaws.com' % ENVIRONMENT.lower()

现在你已经准备好使用模板标签了。只需要使用{% load pipelines %}来代替{% load pipeline %}即可。

from django.contrib.staticfiles.storage import staticfiles_storage
from django import template
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
from pipeline.conf import settings

register = template.Library()

@register.simple_tag
def stylesheet(group):

    if group not in settings.PIPELINE_CSS:
        return ''

    if settings.DEBUG is False or settings.PIPELINE_ENABLED is True:
        context = {
            'type': 'text/css',
            'url': mark_safe(staticfiles_storage.url(settings.PIPELINE_CSS[group]['output_filename']))
        }
        html = render_to_string("pipeline/css.html", context)
    else:
        html = ''
        for path in settings.PIPELINE_CSS[group]['source_filenames']:
            context = {
                'type': 'text/css',
                'url': mark_safe(staticfiles_storage.url(path))
            }
            html = "%s\n        %s" % (html, render_to_string("pipeline/css.html", context))

    return html

@register.simple_tag
def javascript(group):

    if group not in settings.PIPELINE_JS:
        return ''

    if settings.DEBUG is False or settings.PIPELINE_ENABLED is True:
        context = {
            'type': 'text/javascript',
            'url': mark_safe(staticfiles_storage.url(settings.PIPELINE_JS[group]['output_filename']))
        }
        html = render_to_string("pipeline/js.html", context)
    else:
        html = ''
        for path in settings.PIPELINE_JS[group]['source_filenames']:
            context = {
                'type': 'text/javascript',
                'url': mark_safe(staticfiles_storage.url(path))
            }
            html = "%s\n        %s" % (html, render_to_string("pipeline/js.html", context))

    return html

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接