HTML/CSS SCSS 開發原則:禁用 @import 'compass';

xdite · 2013年05月04日 · 最后由 codemonkey 回复于 2014年12月01日 · 11026 次阅读
本帖已被管理员设置为精华贴

http://blog.rocodev.com/posts/11-dont-import-compass

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

===

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

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

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

!![]((http://i.imgur.com/QrOB2ET.png)

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 太多次...

有学习到了

这个是 SCSS 有问题,建议加入 required_once

混用 requireimport 造成的吧... 把 application.css 改成 application.css.scss 再把 require 都改成 @import 应该就快了...

把 "@import compass" 改成 "@import mixin_helpers" 的话,导入的文件是少了几个但层级完全没减少啊...

@luikore 全 import 不一定快。而且會產生其他 issue。

我的折衷作法是拆幾個群組,混用 require 和 import ... 不然幾千行的 css import 下去也是編超久...

@xdite 好吧 import 多了全局变量污染问题也是挺严重的,这样构架确实是最好的方案了

#5 楼 @luikore 搭车问一下这行 scss 为毛不起作用

ul#image-text-list{
    @extend .clearfix;
}

#6 楼 @SharpX .clearfix 定义了么?

#7 楼 @luikore 定义了,用的 bootstrap, 而且这个 scss 在 bootstrap 之后加载的

#8 楼 @SharpX 如果你要 @extend 的选择器是 bootstrap 定义的,就得在这个文件的前面用 @import 把 bootstrap 引进来...

另外 ul#image-text-list 还是改成 #image-text-list 好点

Ruby 的 autoload 特性在这种情况下最实用了。

参考下~

假設 compass 底下超過 30 道 import 好了。乘以呼叫 compass 的 20 次 这个什么意思?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号