compassが遅い件 vol.1
以前、compassのコンパイルが遅い…と記載しましたが、「遅い」に対していくつか対策したのでその手法を記事にしました。
(色々手法があるので、今回はvol. 1として書きます!
はじめに
compassはRubyで書かれており、モンキーパッチングが出来る。ということで、compassのconfigファイル(config.rb)でcompassの処理を上書きすることができます。
今回は、どうやって変更を加えるのかを実験した後に
「コンパイルする対象を正規表現で絞り込むカスタマイズ」をしたいと思います。
実質的にコンパイル速度が早くなるという修正ではないです。
任意のグループでコンパイルを走らせることができるようになりました。ぐらいの変更です。
(これだけでも筆者の案件状況ではかなり効果的でした。詳しくは書かないですが、同一ソースで複数サービスが動くという状況。
最終的には、このグループでのコンパイルをforkさせ、複数のグループを並列にコンパイルさせるとこまでやりました。
今回は、それをするための前準備になります。
・compassのソースはこちら(GitHub)
https://github.com/Compass/compass
・macだと、このあたりにソースがあります
/Library/Ruby/Gems/1.8/gems/compass-0.12.2/
・筆者のcompassのバージョン
$ compass -v
Compass 0.12.2 (Alnilam)
実験する環境をつくる
まずはじめに、コンパイルできる環境を作ります。
1. コンパイル環境をつくる
任意のディレクトリに移動し、下記コマンドを実行すると、コンパイルに必要なファイル/フォルダが生成されます。
config.rb
sass
stylesheets
2. とりあえずコンパイルしてみる
※ --timeオプションでコンパイルにかかった時間が表示されるので、今回は毎回このオプションをつけて実行する
1. コンパイル環境をつくる
任意のディレクトリに移動し、下記コマンドを実行すると、コンパイルに必要なファイル/フォルダが生成されます。
$ compass init↓が生成される。
config.rb
sass
stylesheets
2. とりあえずコンパイルしてみる
$ compass compile --time⇒ すると、コンパイルが走っていることが確認できます。
※ --timeオプションでコンパイルにかかった時間が表示されるので、今回は毎回このオプションをつけて実行する
実験する
compassのconfigファイル(config.rb)でcompassの処理を上書きすることができると記述しましたが、
本当に上書きできてるの?ってことを実験したいと思います。
compassでコンパイルする対象を取得するメソッドはこのような実装
config.rbに対して下記のような修正を加える(筆者はconfig.rbの下部に書いている)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ::Compass | |
class Compiler | |
# 元のソース | |
def sass_files(options = {}) | |
p "here!!" | |
exclude_partials = options.fetch(:exclude_partials, true) | |
@sass_files = self.options[:sass_files] || Dir.glob(separate("#{from}/**/#{'[^_]' if exclude_partials}*.s[ac]ss")) | |
end | |
end | |
end |
⇒ この処理は、既存のメソッドをそのままコピーし、間に「p "here!!"」と1行追加しました。
※ 上書きすることができているならば、「compass compile」時に、「here!!」とログが流れ、正常にコンパイルが通っているはず。
$ compass compile --time
"here!"
"here!"
remove .sass-cache/
remove stylesheets/ie.css
remove stylesheets/print.css
remove stylesheets/screen.css
"here!"
create stylesheets/ie.css (0.002s)
create stylesheets/print.css (0.001s)
create stylesheets/screen.css (0.104s)
Compilation took 0.141s
うん、正しい!
コンパイルする対象を正規表現で絞り込むカスタマイズ
では、上記のことを利用して、コンパイル対象を正規表現で絞り込むカスタマイズをしたいと思います。config.rbに対して下記のような修正を加える。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### コンパイル対象を絞り込みするオプション | |
# 指定がない場合のコンパイル対象 | |
DEFAULT_TARGET_PATTERN = "IE" | |
# 値にマッチするscssファイルをコンパイル対象として絞り込む | |
SASS_FILE_PATTERNS = { | |
"IE" => "^.*ie.*$", | |
"PRINT" => "^.*print.*$", | |
} | |
TARGET_PATTERN = DEFAULT_TARGET_PATTERN | |
### コンパイル対象を絞り込む対応 | |
module ::Compass | |
class Compiler | |
def sass_files(options = {}) | |
exclude_partials = options.fetch(:exclude_partials, true) | |
opt_sass_files = self.options[:sass_files] | |
# ファイル指定あり | |
if opt_sass_files | |
return opt_sass_files | |
end | |
# ファイル指定なし | |
sass_files = Dir.glob(separate("#{from}/**/#{'[^_]' if exclude_partials}*.s[ac]ss")) | |
##### 取得したsass_filesを操作することで、コンパイル対象を変更することができる | |
target_pattern = SASS_FILE_PATTERNS[TARGET_PATTERN] | |
# 指定がないので絞り込ままい | |
if target_pattern.nil? || target_pattern.empty? | |
return sass_files | |
end | |
# 指定があるので正規表現で絞り込み | |
target_regexp = Regexp.new(target_pattern) | |
_sass_files = [] | |
sass_files.each do |file| | |
_file = File.basename(file) | |
if target_regexp =~ _file | |
_sass_files.push(file) | |
end | |
end | |
return _sass_files | |
##### | |
end | |
end | |
end |
これは何の修正なのか?
sassファイル名が「^.*ie.*$」にマッチするファイルをコンパイルするように修正しています。
(SASS_FILE_PATTERNSのIEを指定しているためです。
コンパイルしてみる
$ compass compile --time
remove .sass-cache/
remove stylesheets/ie.css
create stylesheets/ie.css (0.002s)
Compilation took 0.003s
絞り込めてる!正しい!
ちなみに、DEFAULT_TARGET_PATTERNを「PRINT」にすることで、下記のみコンパイルされることも確認。
stylesheets/print.css
コンパイル対象を変える際に、いちいちconfig.rbを書き換えるのも面倒くさい…
きっと、↑のようなことになると思うので、オプションで指定したいですよね。config.rbでオプション追加できるかなーと思って処理を追ってみましたが、
config.rbを読み込む前にcompassコマンドのオプション解析を済ませておりました‥
(compassのcオプションでconfig.rbを指定できるので、今思うと当たり前。
http://kanapple.net/study/archives/16
ということで、コマンドをラップするしかありません。
compassをrequireしてコマンドを新たに作ろうかなーとも思ったので、面倒なので↓にしてみました。
$ mkdir bin
$ touch bin/zoocompass
$ chmod 755 bin/zoocompass
$ vim bin/zoocompass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
command_options = ARGV | |
# config.rbに渡すパラメータを定義 | |
# 'key' => { // zoocompassで処理を分岐する場合に使うキー(今回は必要ないけど | |
# 'env' => '', // config.rbで使う環境変数名 | |
# 'opt' => '', // zoocompass実行時に指定するオプション名 | |
# } | |
# | |
custom_options = { | |
'compile_target' => { | |
'env' => 'TARGET_PATTERN', | |
'opt' => '--target', | |
} | |
} | |
# custom_optionsのオプションを指定していた場合は、オプションから削除+環境変数へセットする | |
custom_options.each do |o,v| | |
index = command_options.index(v['opt']) | |
if !index.nil? | |
# 環境変数へセット | |
option = command_options.values_at(index + 1)[0] | |
ENV[v['env']] = option | |
# オプションから削除 | |
command_options.delete_at(index + 1) | |
command_options.delete_at(index) | |
end | |
end | |
# compassを実行する | |
compass_options = command_options.join(' ') | |
compass_command = 'compass ' + compass_options | |
system(compass_command) |
合わせて、config.rbのTARGET_PATTERN部分を下記に修正する(ENVでパラメータを受け取る
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
TARGET_PATTERN = ENV['TARGET_PATTERN'] || DEFAULT_TARGET_PATTERN |
compassをラップした「bin/zoocompass」を使うと、オプションで指定したパラメータをconfig.rbで参照できるようになります。
(それ以外はcompassと何も変わりません。
何も変わってないか、試してみる
$ ./bin/zoocompass compile --time
remove .sass-cache/
remove stylesheets/ie.css
create stylesheets/ie.css (0.003s)
Compilation took 0.005s
うん、変わってない。
追加したオプションで試してみる
$ ./bin/zoocompass compile --time --target IE
unchanged sass/ie.scss
Compilation took 0.001s
うん、よい。
$ ./bin/zoocompass compile --time --target PRINT
remove .sass-cache/
remove stylesheets/print.css
create stylesheets/print.css (0.003s)
Compilation took 0.004s
うん、指定できてるぽい。
できた!!
注意事項!
compassのバージョンを上げる場合は、元のソース(compass側のソース)に変更がないか要確認。案件内でやる場合には、みんなに周知しないと。
終わりに
次回以降、これを使って並列実行させた記事も書いていきたいと思います。やったことを少しずつ記事にしてきますー。
以上!
Related Posts
登録:
コメントの投稿
(
Atom
)
0 件のコメント :
コメントを投稿