2011-05-25 104 views
4

我試圖改善客戶端從我的Compojure網頁服務器獲取頁面的性能。我們使用(compojure.route/resources "/")提供了一堆靜態文件(JS,CSS),該文件在文件系統上查找文件,將它們轉換爲URL,然後將它們作爲流進行響鈴。通過轉換爲流,它似乎會丟失所有文件元數據,例如mod時間。如何使用Compojure生成修改的http頭文件?

我可以包裝靜態資源處理程序並添加一個ExpiresCache-Control: max-age標頭,但是這樣可以防止客戶端發送任何請求。有用的,但這些文件有時會改變(當我們發佈一個版本時)。

理想情況下,我希望客戶端信任其自己的緩存版本,比如說,一個小時,然後在該小時過後通過If-Modified-Since標頭髮出請求。然後,我們可以返回304 Not Modified,並且客戶端避免下載幾百公斤的javascript。

看起來我可以在提供響應時設置一個Last-Modified標頭,並使客戶端使用If-Modified-Since標頭限定後續請求。太棒了,除非我必須重寫compojure.route/resources中的大部分代碼才能添加Last-Modified - 這並不困難,但很乏味 - 並且發明了一些代碼來識別並響應If-Modified-Since標頭。這不是一項艱鉅的任務,但也不是一件簡單的任務。

這是否已經存在某處?我找不到它,但它似乎是一個足夠普遍的,足夠大的任務,現在有人會爲它編寫一個庫。

回答

4

FWIW,我通過使用Ring的wrap-file-info中間件得到了這個工作;我非常尷尬,我在Compojure而不是Ring找到了這個。但是,compojure.routefilesresources處理程序都提供了流而不是文件或URL,當然Ring無法從中找出元數據。

我不得不寫基本上resources副本,而不是返回File;當包裹在wrap-file-info符合我的需求。仍然不介意稍微好一點的解決方案,不涉及從Compojure複製大量代碼。

+0

接受我自己的答案,以便在有人搜索時顯示爲「已解決」。希望這不是太俗氣。 – amalloy 2011-11-16 19:27:22

1

您是否考慮使用ring-etag-middleware?它使用文件的最後修改日期來生成實體標籤。然後它在匹配中鍵入一個304到請求中的if-none-match頭部。