會使用到 Jammit gem 的原因是,我發現網站在 6 月改版後,就常常會發生網站脫衣服(吃不到 css)的狀況,而且都是在上班時間。
翻 log 查到原因後發現,原來是因為原本網站的伺服器只有一台,改版時調整成兩台並且做 HA ,問題就出在多台伺服器上。
Rails 的 layout 中, stylesheet_link_tag 我有設定 :cache => :merge_index ,因此看原始碼時會發現,網站只有讀取 merge_index.css ,這段設定就是請 Rails 幫忙把數隻 css 壓成一隻,減少 http request 的數量。
問題來了,這隻 merge_index 會在瀏覽器訪問頁面時檢查是否存在 /public/stylesheets 資料夾,如果不存在就先產生它,因此在 production 環境的目錄內你會找到 merge_index.css 這個 development 環境沒有、也不在 repository 內的檔案。
以上的狀況,當你只有一台伺服器時,一切都正常;當有多台伺服器時,就會發生瀏覽器問到還沒產生 merge_index.css 的伺服器,因而吃不到 css 造成脫衣服的問題。
這個問題同樣也出現在T客邦網站,因此 xdite 寫了一篇文章介紹 Jammit 來解決這個問題,解決就是 preheat CSS/JS。但實際套用後發現,並不能照著 xdite 的文章實作,那要怎麼寫呢?
首先要編輯 config/assets.yml ,這個 yml 檔案的最前面是關於 Jammit 的設定,詳細的設定清單比方說壓縮方式、gzip、路徑等等可以去看參考文件。
注意,設定中記得要有加入這行,否則在 Jammit package 時,會告訴你無法產生 css (IE7 以下 MHTML issue)。
embed_assets: datauri
接著是設定 stylesheets 和 javascripts ,範例如下
stylesheets:
commons:
- public/stylesheets/reset.css
- public/stylesheets/common-use.css
- public/stylesheets/hf.css
- public/stylesheets/right-column.css
merge_diary:
- public/stylesheets/diary.css
- public/stylesheets/openid-comment.css
javascripts:
commons:
- public/javascripts/pop.js
- public/javascripts/facebox.js
- public/javascripts/jquery.timers-1.2.js
merge_index:
- public/javascripts/jquery.scrollTo-1.4.2-min.js
- public/javascripts/jquery.easing.1.3.js
- public/javascripts/jquery.serialScroll-1.2.2-min.js
- public/javascripts/slideshow.js
以範例來說,到時候產生出來的就會有 commons.css, merge_diary.css, commons.js, merge_index.js ,每隻檔案要包含哪些 css/js 就是在 yml 內設定,相當直觀。
ps. 實際上,因為有設定 datauri ,所以檔案名稱還會後綴 -data-uri ,此處為了直觀故省略了後綴字。
接著,要去修改 layout 中使用 stylesheets 和 javascrpits 的方法,寫法是
<%= include_stylesheets :commons, :merge_diary %>
<%= include_javascripts :merge_index, :commons %>
最後,因為網站需要 preheat stylesheets 和 javascripts ,在 capistrano recrips 內需要加上
before("deploy:symlink") do
run "cd #{release_path} && bundle exec jammit"
end
做完 preheat CSS/JS 之後,就不會在出現網站脫衣服的狀況囉!
留言列表