我们都知道,对于一个相当大的Rails应用来说,前端是相当充实的,资产预编译,更重要的是--开发模式的改变远非瞬息之间。
我们所指的前端是那种大量使用sass、sass库(Compass、Bourbon等)和转置的JavaScript语言(如旧的CoffeeScript、ES6等)的前端。
用libsass替换Ruby Sass
在Sass方面,相当长一段时间以来,有一个纯C/C++实现的Sass CSS预编译器:libsass 。显然,用C/C++实现意味着它的运行速度应该比Ruby的实现快上好几个数量级。
我们所需要的是一个使用它的 gem:进入sassc-rails,它是sass-rails gem 的一个直接替换。
在现实世界中,与vanilla gem相比,sassc-rails 的速度如何?(直接从他们的repo中获得的基准测试)
# Using sassc-rails
[1] pry(main)> Benchmark.bm { |bm| bm.report { Rails.application.assets["application.css"] } }
user system total real
1.720000 0.170000 1.890000 ( 1.936867)
# Using sass-rails
[1] pry(main)> Benchmark.bm { |bm| bm.report { Rails.application.assets["application.css"] } }
user system total real
7.820000 0.250000 8.070000 ( 8.106347)
不是真正的数量级快,但4.5倍的速度也不差。
唯一的问题是,它不能完全与通常的sass gem如Compass等一起工作,也就是说,在生产中使用它之前,要确保它能毫无问题地编译你的scss文件。
为了帮助解决这个问题,你可以查看Sass Compatibility网站,并在不同的分支中安装该宝石后运行你的应用程序,以测试情况。
Compass中场休息
让我头疼的是,Compass根本无法与sassc-rails 。
另外,从另一个角度看,Compass似乎,嗯,有点死了。
我想我要把我那些仍然使用Compass的前端迁移到Bourbon,也许还有autoprefixer-rails
用mini_racer取代JS转写/简化/等等。
therubyracer的问题是,它使用libv8 ~> 3.16.14.0 版本 ("用于发布 v8 运行库和头文件的源码和二进制形式的 gem"),而 mini_racer使用~> 5.1 ,正如人们所期望的,它比前者快得多。
从他们的资源库中得到一些快速的基准测试。
$ ruby bench_uglify.rb
Benching with MiniRacer
MiniRacer minify discourse_app.js 13813.36ms
MiniRacer minify discourse_app_minified.js 18271.19ms
MiniRacer minify discourse_app.js twice (2 threads) 13587.21ms
Benching with therubyracer
MiniRacer minify discourse_app.js 151467.164ms
MiniRacer minify discourse_app_minified.js 158172.097ms
MiniRacer minify discourse_app.js twice (2 threads) - DOES NOT FINISH
Killed: 9
在这里,我们谈论的是10倍的改进,也就是非常好的收益,因此是一个数量级的速度。在兼容性方面,这似乎是一个很好的替代品,也就是说,到目前为止,在我把它加入Gemfile的应用程序中,没有任何问题。
替代mini-racer以获得最佳性能
Sprockets使用ExecJS,它 "选择最好的运行时间来评估你的JavaScript",这意味着如果你不介意安装一个额外的依赖,你可以直接使用Node.js 6.x,以获得最大的性能。
由于我通过在本地预编译来部署我的资产,我只是通过brewbrew install node 安装了Node.js 6.2.0,并在一个2K行的CoffeeScript JS文件上运行time rake assets:clobber assets:precompile 。不多说了,下面是结果。
node.js 6.2.0
rake assets:clobber assets:precompile 7.30s user 1.27s system 102% cpu 8.358 total
mini-racer与libv8 5.x
rake assets:clobber assets:precompile 14.96s user 1.20s system 101% cpu 15.943 total
这又是一个2倍的速度提升!另外,我还用10K行的CoffeeScript试了一下,在这种情况下,mini-racer甚至没有完成。
感谢@attilagyorffy指出了这一点。
我应该在生产中使用这些吗?
在一个设置中,资产被预先编译在本地,然后上传到实际的虚拟机上,这不是一个大问题,也就是说,如果出现问题,只需恢复到原始的宝石。
到目前为止,Mini-racer看起来坚如磐石,而sassc-rails仍有一些库的问题,也就是说,还没有准备好在所有的使用情况下进行生产。
如果你不介意安装node.js,并希望获得最大的性能,那么你完全可以这样做,因为它与ExecJs的工作是完美的。
在最佳情况下,你可以将两者整合到你的Gemfile中,你将在部署过程中得到相当好的提升,更重要的是:在开发过程中(当然是在有大量资产的应用中)。