首页渲染慢主因是模板反复加载解析,启用cached.loader(缓存template对象)和{% cache %}(缓存片段渲染结果)可降首屏延迟300–800ms;二者需正确配置并配合使用,且互不干扰。

首页渲染慢,八成不是数据库拖后腿,而是模板反复加载、解析、编译——cached.Loader 和 {% cache %} 配合得当,能直接砍掉 300–800ms 的首屏延迟。
配置 cached.Loader:模板加载不重读、不重编译
它缓存的是编译后的 Template 对象,不是渲染结果,所以对所有请求都生效,且不依赖你配的 CACHES 后端。
- 必须嵌套写:
['django.template.loaders.cached.Loader', ['django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader']]—— 错写成并列列表(比如漏掉内层[])就等于没开 - 开发时改了模板却没更新?不是缓存没清,是
os.stat().st_mtime没变或进程没重启;touch或删__pycache__无效,runserver必须重启 - 模板少于 50 个、或大量用
get_template(f'emails/{lang}.html')动态拼路径时,缓存命中率极低,反而增加判断开销
用 {% cache %} 缓存动态片段:避开用户专属数据
首页里公共内容(如轮播图、热门分类、公告栏)适合缓存,但用户登录态、购物车数量这类个性化内容不能塞进去,否则会跨用户污染。
- 在模板顶部加
{% load cache %},再用{% cache 3600 home_banner %}包裹静态区域 - 缓存键名(如
home_banner)最好带语义,避免冲突;如果内容依赖参数(如地区),要显式加入:{% cache 3600 home_categories region_code %} - 别在
{% cache %}块里调用{{ user.username }}或{{ request.user.is_authenticated }}—— 这些变量不会触发新缓存键,会导致未登录用户看到已登录用户的缓存页
视图层加 cache_page:整页响应直落缓存
适用于完全静态或变化极低的首页(比如企业官网首页),跳过整个 Django 请求生命周期,性能提升最猛。
- 装饰器写法:
@cache_page(60 * 15, cache='default'),注意第二个参数指定缓存别名,避免误用开发环境的locmem - 必须确保中间件顺序正确:
UpdateCacheMiddleware在最前,FetchFromCacheMiddleware在最后,否则缓存不生效 - 一旦启用,该视图返回的
response会被完整存入缓存,包括Set-Cookie头 —— 若首页含登录态判断,需配合Vary头隔离:response['Vary'] = 'Cookie'
缓存后端选型:别让 locmem 成为生产陷阱
开发用 LocMemCache 没问题,但上线后它无法跨进程共享,gunicorn 多 worker 下缓存形同虚设。
- 小流量项目可先上
FileBasedCache,但注意LOCATION目录需 Web 进程有读写权限,且文件 I/O 可能成为瓶颈 - 中高流量必须用 Redis:
'BACKEND': 'django.core.cache.backends.redis.RedisCache',Django 4.2+ 原生支持,无需额外包 - 别忽略
TIMEOUT默认值(300 秒):首页缓存建议设为 600–1800,太短起不到作用,太长会导致内容 stale
最容易被忽略的一点:三个缓存层级(cached.Loader、{% cache %}、@cache_page)互不干扰,但各自有生效前提——配错任意一层,其他两层再好也白搭。上线前务必用 curl -I 看响应头是否含 X-Cache: HIT,再查日志确认缓存键生成逻辑是否符合预期。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











