はじめに
比較のために同じものを React と Riot.js で実装します。
table タグを生成し、3000行の内容を表示します。
Riot.js
JSFiddle https://jsfiddle.net/ryohey/v5ytp918/
// ここは共通
const data = []
for (var i = 0; i < 10000; i++) {
data.push({
name: `test data ${i}`,
key: i
})
}
//
riot.mount('testtable', {rows: data, start: new Date})
<testtable>
<table>
<thead>
<tr>
<td>key</td>
<td>name</td>
</tr>
</thead>
<tbody>
<tr each={opts.rows}>
<td>{key}</td>
<td>{name}</td>
</tr>
</tbody>
</table>
this.on("updated", () => {
console.log(`${(new Date) - this.opts.start} millisec`)
})
</testtable>
React
JSFiddle https://jsfiddle.net/ryohey/rvLxnnyo/
// ここは共通
const data = []
for (var i = 0; i < 10000; i++) {
data.push({
name: `test data ${i}`,
key: i
})
}
//
ReactDOM.render(
<Table rows={data} start={new Date} />,
document.getElementById('container')
)
const Table = React.createClass({
render: function() {
const elements = this.props.rows.map(d =>
<tr key={d.key}>
<td>{d.key}</td>
<td>{d.name}</td>
</tr>
)
return <table>
<thead>
<tr>
<td>key</td>
<td>name</td>
</tr>
</thead>
<tbody>
{elements}
</tbody>
</table>
},
componentDidMount: function() {
console.log(`${(new Date) - this.props.start} millisec`)
}
})
書き方の比較
Riot.js
データの受け渡し
riot.mount('testtable', {rows: data, start: new Date})
第二引数で渡します。
タグの中で opts
として参照します。
(入れ子のカスタムタグの場合にはタグの属性として渡すこともできます)
ループ
<tr each={opts.rows}>
でループを行います。
React
データの受け渡し
<Table rows={data} start={new Date} />
タグの属性として渡します。
クラス内では this.props
として参照します。
ループ
要素の配列を作ってタグの中に展開します。
const elements = this.props.rows.map(d =>
<tr key={d.key}>
<td>{d.key}</td>
<td>{d.name}</td>
</tr>
)
...
render: function() {
...
<tbody>
{elements}
</tbody>
実行速度
React: 2320 millisec
Riot.js: 2744 millisec
リロードするとまちまちの時間が出力されますが、概ね React の方が速いようです。
中身も含めてレンダリングが終わるまでの時間を調べるために、React は componentDidMount
を、Riot.js は updated
を使っています。(ちなみに updated
は mount
とほぼ同時でした)
所感
React.js と Riot はカスタムタグ (コンポーネント) を記述する場所の違いはありますが、<table>
あたりのタグの書き方はどちらも素の HTML のように書くことができました。
ループ処理においては、Riot.js の方が直感的に記述できると思いました。
Riot.js は HTML を中心とした考え方なので、テンプレートを使ったことがあるデザイナーなどの方に馴染みやすく、React は js を中心とした考え方なのでエンジニア向きかなと思いました。
私自身は HTML 的な処理と見た目の分離の考え方に慣れていたので、JSX の書き方や props や state に馴染めず React で作っていた趣味プロジェクトを Riot.js に移しましたが、今回できるだけ同じようにそれぞれ書いて比較したことで、わりと似た感じで書けることに気づき、綺麗に書けば保守性はどちらでもあまり変わらないと思いました。
実行速度に関しては、今回は最初のレンダリングの速度比較だけで、データ更新時の速度比較を行っていないのでまだ調査が必要だと思いました。ただ、React は props.key を使ってデータを識別できるので速そうな気がします。
おわりに
どっちも2秒以上かかってるので、巨大なテーブルを表示するサイトはそもそもサーバーサイドレンダリングすべきかもしれません。
私は Electron でファイルを読み込んで表示するアプリを作ることが目的なので、どうしたらいいやら・・・