为了快速地响应用户的需求、满足运营活动的需要,互联网产品通常有着非常高的发布频率。采用敏捷开发的方式,缩短了交付的周期,加快了产品的迭代,也给项目的文件管理带来了挑战。前端工程直接面向用户,首当其冲,最值得重视。频繁更新的图片、样式、交互,不同的版本文件,怎样保证用户获取一个可预期的结果呢?本文正是从这个问题出发,讨论相关的解决方案。
1. 缓存方式
前端缓存分为两种:
- 强缓存:浏览器在加载静态资源时,检查 Http Response Header 的 Expires 和 Cache-Control 两个字段。如果在有效期,那么使用浏览器缓存。
- 协商缓存:如果没有命中强缓存,浏览器会向服务器验证是否命中协商缓存。协商缓存实际上是在静态资源的 Header 上标记 Last-Modified、ETag,通过对比浏览器端、服务器端静态资源的这些值,判断是否是同一个文件。如果一致,则返回 304,Not Modified 表示命中协议缓存。否则,浏览器从服务器加载静态文件。
服务器缓存主要是 CDN 缓存:CDN ,也就是内容分发网络,是在现有网络的基础上,新增一层架构,提前将静态文件,分发到用户访问最佳的网络节点。当用户使用浏览器访问静态资源时,静态资源域名通过 DNS 解析,根据用户的地理位置,返回一个最佳访问的节点 IP 地址。浏览器拿到 IP 地址之后,再请求静态资源。
2. 强制刷新缓存方式
强制刷新缓存是指:当缓存有效时,通过一定的技术手段,迫使浏览器不使用缓存,而从服务器请求静态资源。主要有两种方式:
- 重新命名静态资源,如: app.js 更新为 app.a232nas9.js
- 静态资源链接添加变化的参数,如:app.js 更新为 app.js?v=20171017
在大型 Web 项目中,更倾向于使用第一种,重命名静态资源的方式实现静态资源的强制刷新。这是由于采用第二种方式,发布时,需要替换静态资源文件。文件替换时,CDN 不能即时完成更新。当仅部分静态资源完成更新时,如果有用户访问,会导致一些不可预期的错误。下面介绍几种 Django 中实现的静态文件版本管理的方式:
2.1 通过 settings 中的变量管理版本
1,在 yourapp 下新建 context_processors.py 文件context_processors.py
|
|
2,修改 settings.py 文件,新增如下内容:
|
|
3、修改 html 中静态资源的引入方式静态资源重新命名方式
|
|
静态资源链接添加变化的参数方式
|
|
每次发布之前,通过修改 settings.py 中 VERSION 变量的值,可以达到前端版本更新的目的。由于静态文件共用一个 VERSION 标识,如果仅仅更新了一个静态文件,其他带上 VERSION 标识的静态文件也将被更新。
2.2 使用 ManifestStaticFilesStorage
Django 中提供 ManifestStaticFilesStorage 类,允许 Django 从 staticfiles.json 文件中读取静态文件映射。staticfiles.json 中保存了类似访问 app.css 时,返回 app.s23324a.css 的对应关系。1,settings.py 设置
|
|
通过对 ManifestStaticFilesStorage 类的继承,复写相应的函数,还可以定制化静态文件名。2,修改 html 中静态资源的引入方式
|
|
3,收集静态文件
|
|
这样在 static 目录下 就会生成一个 staticfiles.json 文件。访问网页时,静态文件会被带上 hash 版本值。
|
|
2.3 使用 CachedStaticFilesStorage
Django 中提供 CachedStaticFilesStorage 类,允许 Django 从缓存中读取静态文件映射。与 ManifestStaticFilesStorage 不同的是 CachedStaticFilesStorage 不需要创建一个映射文件,而是通过缓存来保存映射关系。1,settings.py 设置
|
|
通过对 ManifestStaticFilesStorage 类的继承,复写相应的函数,还可以定制化静态文件名。2,设置缓存
|
|
2,修改 html 中静态资源的引入方式
|
|
3,收集静态文件
|
|
这样在 static 目录下 就会生成一个 staticfiles.json 文件。
3. 参考
- https://www.cnblogs.com/lyzg/p/5125934.html
- http://www.cnblogs.com/smallc/p/4019642.html
- http://blog.thehumangeo.com/2013/05/01/dynamically-cache-static-files-using-django-and-nginx/
- https://devblog.kogan.com/blog/a-hidden-gem-in-django-1-7-manifeststaticfilesstorage