TL;DR :禁止使用 @import "compass";,最少最少都要從第二層如 @import "compass/css3"; 呼叫起。

===

上禮拜幫一個專案上了從 Wrapbootstrap 上買來的 Core Admin CSS 當後台 Admin 之後。開發的同事偷偷問我,是否有什麼設定可以讓開發時不重新 compile CSS,因為現在第一次進後台,compile CSS 都要超過五秒。但我們自己寫的前台 CSS 倒沒有這個問題....

五秒是個很驚人的數字,根據以往的經驗,我猜測可能又是 CSS 架構設計不當的問題,所以編譯才要花這麼久時間。

果不其然,鑽進去看了一下整體架構之後,我只送了一個 commit,改了九行。

before : Compiled core-admin/application.css (44080ms) (pid 74648)
after : Compiled core-admin/application.css (116ms) (pid 74648)

compile 時間就從 44 秒降到 0.1 秒.......XDDDD

Okay 這其中的原因是:

core-admin/application.css 的架構是這樣的,大概掛了 20 支以上的 CSS。

*= require core-admin/uniform_default
*= require core-admin/base
*= require core-admin/box
*= require core-admin/message_box
*= require core-admin/dropdowns
*= require core-admin/font-awesome
*= require core-admin/responsive-tables
*= require core-admin/fullcalendar
*= require core-admin/gritter
...

其中絕大部分的 CSS 又有這一行 @import "mixin_helpers";,而 mixin_helpers.css.scss 裡面的第一行就是 @import "compass";

Compass 與 AssetPipeline 編譯原則

Compass 的運作原理就是用層狀結構掛下底下數十支 mixin。假設 compass 底下超過 30 道 import 好了。乘以呼叫 compass 的 20 次,那會是相當驚人的數字。而 AssetPipeline 的問題是只要遇到 @import 速度就會慢下來。

所以很慢是理所當然的。把 @import "compass"; 換成直接呼叫 compass 下負責的 mixin,如 @import "compass/css3/box-shadow"; 就沒有這些問題了。

禁止直接使用 @import "compass";

這也是我們前台 CSS 並不慢的原因,因為公司的前端開發內規有一條就是禁止使用 @import "compass";,最少最少都要從第二層如 @import "compass/css3"; 呼叫起。這樣可以避免之後很多維護上的問題…

SMACSS 愛好者特別注意

特別如果你是 SMACSS:Scalable and Modular Architecture for CSS 的愛好者的話,更不可以不注意這一點…

Tuning 原則

另外附上我 tune CSS compile 速度的原則,提供各位參考:

  • 了解 asset pipeline 的 compile 原理
  • compile 速度永遠是卡在 @import (這也是 compass 與 sprocket 作者意見不合的地方 )
  • compass 的原理建立在層狀 import,所以也就是掛到越底層的css,在 compile 時速度會越快
  • 如果懶得每次都掛一堆 mixin,希望寫 helper 進去給所有 css 一次掛,記得檢查你掛了什麼....
  • 如果需要掛 mixin helper 的地方太多,那麼就應該改用 import 而非 require,這樣就不會 compile mixin helper 太多次...