僕はフロントエンドまわりの技術には疎いのですが、Reactは今も人気が高いように見えます

サーバサイドでReactを使ってページのレンダリング(サーバサイドレンダリング)を行ったりもするようで、

そうすればサーバサイドとフロントエンドで処理が共通化出来て便利そうです


JavaでReactのサーバサイドレンダリングをやるならNashornを使う事になり、パフォーマンスが気になったのでベンチマークを取ってみました



アプリのソース

ソースは以下になります
(ISUCON4のJava実装です)

  1. Spring Boot + Thymeleaf
    テンプレートエンジンにSpring Bootでよく使われているThymeleafを使ったバージョン

  2. Spring Boot + Handlebars.js
    テンプレートエンジンにHandlebars.jsを使ったバージョン

  3. Spring Boot + EJS
    テンプレートエンジンにEJSを使ったバージョン

  4. Spring Boot + EJS + React
    テンプレートエンジンにEJS さらに、Reactを使ったバージョン

  5. Spring Boot + EJS + React (body全体で1コンポーネント)
    body全体をReactの1コンポーネントにしたバージョン
    2016/01/17追記

  6. Spring Boot + Thymeleaf + React
    テンプレートエンジンにThymeleaf さらに、Reactを使ったバージョン
    2016/01/10追記

  7. Spring Boot + Thymeleaf + React (body全体で1コンポーネント)
    body全体をReactの1コンポーネントにしたバージョン
    2016/01/17追記

Springのドキュメントによると、テスト済のEJSはこっちなのですが、
最終更新日が2009/10になってて6年以上更新が止まってるみたいなので、同じ名前で同等の機能があるこっちのEJSを使いました


JavaScriptテンプレートエンジンおよびReactの実行にはNashornを使いますが、
Spring 4.2からNashorn、JRuby、Jythonを使ってスクリプト言語のテンプレートエンジンを簡単に動かせる機能(Script templates)が追加になったそうで、それを使ってます
@makingさん、いつもありがとうございます



ベンチマークスコア

それぞれベンチマークを8回づつ実行しました
一番右のscoreの値が高い程良いです
ベンチマークを数回実行後にスコアが良くなるのはJITコンパイルされるからですね

1.Spring Boot + Thymeleaf バージョン

14:58:42 type:score     success:132250  fail:0  score:28570
14:59:58 type:score     success:182805  fail:1  score:39491
15:01:15 type:score     success:191280  fail:0  score:41321
15:02:31 type:score     success:193740  fail:0  score:41852
15:04:02 type:score     success:196980  fail:0  score:42552
15:05:19 type:score     success:193350  fail:0  score:41767
15:06:36 type:score     success:192330  fail:0  score:41547
15:07:52 type:score     success:192960  fail:0  score:41684

2.Spring Boot + Handlebars.js バージョン

14:40:48 type:score     success:82720   fail:0  score:17872
14:42:04 type:score     success:165250  fail:0  score:35699
14:44:36 type:score     success:192230  fail:0  score:41527
14:49:17 type:score     success:201860  fail:0  score:43606
14:50:33 type:score     success:195570  fail:0  score:42247
14:51:49 type:score     success:202610  fail:0  score:43768
14:53:05 type:score     success:203440  fail:0  score:43945

3.Spring Boot + EJS

14:14:15 type:score     success:107360  fail:0  score:23194
14:15:31 type:score     success:174090  fail:0  score:37607
14:16:46 type:score     success:185210  fail:0  score:40009
14:18:02 type:score     success:195050  fail:0  score:42135
14:27:17 type:score     success:196340  fail:0  score:42412
14:28:33 type:score     success:200450  fail:0  score:43301
14:29:49 type:score     success:205960  fail:0  score:44492
14:31:04 type:score     success:203360  fail:0  score:43931

4.Spring Boot + EJS + React

17:03:06 type:score     success:27615   fail:11 score:5969
17:04:21 type:score     success:63650   fail:0  score:13753
17:05:36 type:score     success:83160   fail:0  score:17967
17:06:52 type:score     success:101300  fail:0  score:21884
17:09:07 type:score     success:98525   fail:1  score:21285
17:10:23 type:score     success:150080  fail:0  score:32419
17:11:39 type:score     success:156770  fail:0  score:33866
17:12:54 type:score     success:173570  fail:0  score:37496

5.Spring Boot + EJS + React (body全体で1コンポーネント)
2016/01/17追記

15:27:58 type:score     success:15890   fail:13 score:3436
15:29:14 type:score     success:36980   fail:0  score:7991
15:30:30 type:score     success:56020   fail:0  score:12104
15:31:47 type:score     success:103940  fail:0  score:22455
15:33:03 type:score     success:124010  fail:0  score:26789
15:34:18 type:score     success:116980  fail:0  score:25271
15:35:34 type:score     success:117110  fail:0  score:25299
15:36:50 type:score     success:123230  fail:0  score:26622
15:38:06 type:score     success:130020  fail:0  score:28087
15:39:21 type:score     success:139840  fail:0  score:30210
15:40:37 type:score     success:143640  fail:0  score:31030
15:41:53 type:score     success:145340  fail:0  score:31397

6.Spring Boot + Thymeleaf + React
2016/01/10追記

14:59:31 type:score     success:15005   fail:13 score:3245
15:00:46 type:score     success:53410   fail:0  score:11540
15:02:02 type:score     success:82550   fail:0  score:17835
15:03:17 type:score     success:109280  fail:0  score:23608
15:04:48 type:score     success:138260  fail:0  score:29868
15:06:04 type:score     success:141540  fail:0  score:30577
15:07:20 type:score     success:139305  fail:1  score:30093
15:08:35 type:score     success:147010  fail:0  score:31757

7.Spring Boot + Thymeleaf + React (body全体で1コンポーネント)
2016/01/17追記

17:06:09 type:score     success:13206   fail:11 score:2424
17:07:24 type:score     success:44772   fail:0  score:8211
17:08:40 type:score     success:79236   fail:0  score:14530
17:09:55 type:score     success:116760  fail:0  score:21410
17:11:10 type:score     success:114468  fail:0  score:20989
17:12:26 type:score     success:132948  fail:0  score:24376
17:13:41 type:score     success:135204  fail:0  score:24791
17:14:56 type:score     success:137088  fail:0  score:25137
17:16:12 type:score     success:153036  fail:0  score:28059
17:17:27 type:score     success:150612  fail:0  score:27615
17:18:42 type:score     success:156192  fail:0  score:28639
17:19:58 type:score     success:159768  fail:0  score:29296

Thymeleafと比べると、Handlebars.jsやEJSは最初の方はスコアは低いですがJITコンパイル後はThymeleafを上回っています
(Handlebars.jsやEJSはThymeleafのLayout Dialectに該当する機能がないでフェアでない気もしますが)

NashornはJavaScriptソースコードをJVMバイトコードに変換するそうなので速いですね。Nashornすごい!

参考: Nashorn – OpenJDKに提案された新JavaScriptエンジン


本題のReactは残念ながらスコアが低かったです・・・
Reactの事が全然わかってないので、僕のコードが悪い気もしています
詳しい方のツッコミをお待ちしています



JavaScriptのデバッグについて

Nashorn使うとJavaScriptのデバッグが出来ないんじゃないの?と思ってたら、
NashornのプロジェクトリードであるJim LaskeyさんからNetBeansを使ってみてとの情報を頂きました
プロジェクトリードから返信来るとドキッとしますね!