我正在尝试提高从我的Compojure网络服务器获取页面的客户端的性能。我们使用(compojure.route/resources "/")
提供了一堆静态文件(JS,CSS),它在文件系统上查找文件,将它们转换为URL,然后将它们作为流提供给Ring。通过转换为流,它似乎丢失了所有文件元数据,例如mod时间。
我可以包装静态资源处理程序并添加Expires
或Cache-Control: max-age
标头,但这会阻止客户端发送任何请求。很有用,但这些文件有时会发生变化(当我们推出一个版本时)。
理想情况下,我希望客户端信任自己的缓存版本,例如一小时,并在该小时后通过If-Modified-Since
标头发出请求。然后我们可以返回304 Not Modified
,客户端可以避免下载几百公斤的JavaScript。
看起来我可以在提供响应时设置Last-Modified
标头,这会导致客户端使用If-Modified-Since
标头限定后续请求。很好,除了我必须重写compojure.route/resources
中的大部分代码以添加Last-Modified
- 不困难但又乏味 - 并且发明了更多代码来识别和响应{{1}标头这不是一项重大任务,也不是一项简单的任务。
这已经存在吗?我找不到它,但它似乎是一个足够普通的,足够大的任务,有人会为它编写一个库。
答案 0 :(得分:4)
FWIW,我通过使用Ring的wrap-file-info中间件来实现这一点;我很尴尬,我在Compojure而不是Ring中寻找这个。但是,compojure.route
的{{1}}和files
处理程序都提供了流而不是文件或网址,当然Ring无法从中找出元数据。
我必须写一份基本上resources
的副本,而不是resources
;当包裹在符合我需要的File
时。仍然不介意一个稍微好一点的解决方案,不涉及从Compojure复制大量代码。
答案 1 :(得分:1)
您是否考虑过使用ring-etag-middleware?它使用文件的上次修改日期来生成实体标记。然后,它将匹配304键入请求中的if-none-match标头。