by shigemk2

当面は技術的なことしか書かない

kintoneの表と裏〜大規模JavaScript開発と非構造データベース

f:id:shigemk2:20131208192353j:plain

what's kintone?
ビジネスアプリをノンプログラミングで作成出来る。
アプリ版RPGツクールみたいなやつ。
データベース型webアプリ

kintoneの表
仕事のなかでJavaScriptをどのように使ってUIを作成したか

フレームワーク部分を除くと70000行
Closure Library(jQueryは甘え)

JavaScriptでほぼ全てのDOM
サーバサイドでのやりとりはXHRでAPIを叩く
UIづくりのなかでどんな苦労をしたのかを考える

イベント管理
フォームメーカー
ドラッグ&ドロップのみで縦横自由にコントロールを配置してレイアウト
およそ20個くらい

ドラッグ&ドロップを導入すると、UIがおそろしく複雑になる。
イベント発火数がやばい
イベントを上手く管理しないといけない

1. クラス間通信
clickをトリガーとして、クラスからイベントを投げあう。

実装はシンプルなMapで実現できる直接の親子関係がなくてもイベントを
介してやりとりが出来る
クラスの役割が明確になっているので、1クラスに実装が集中することがない
DOMイベントと違ってたくさんのイベントが投げられても重くならない

2. 動的なDOMの書き換え
DOMを動的に書き換える
リークが発生するから

原因
オブジェクトの参照が殘ってしまったから
DOM構造がまるまる殘ってしまう

Chromeなどでもリーク
IE9は優秀

参照にnullを入れて地道にガベコレさせる
swfオブジェクト内でも参照を切る必要がある
改善の余地あり。

3. 遅延処理
ヘビーな使われかた(繰り返し行が50行くらいあった)
iFrameのロードにより遅くなってしまうことがある
IEBで10秒以上描画に時間がかかった

重いループ処理への対応
1つ1つのループ処理を分割して非同期化

Deferredパターンを活用する
後で扱いたいリソース、例えばAjax処理の結果を
同期的に書くデザインパターン

ループ処理をDeferred化する
トリガをseeTimeoutで囲んでチェインさせることで
ループ処理をゆっくり実行できる

繰り返しDOMだけがゆっくり表示されている

利点

  • コードが複雑になりにくい
  • Deferredなので処理が全て終わったか分かる(コードの実行が終了したかどう

かを予め確認出来るので、これが出来ないと完了するまでにモードの切り替え
とかをしないといけないのでしんどい)

表示速度≒体感速度

重いピンポイントで非同期にすることで、UIをブロックせずに速度が向上する
クロージャしなくていい

ポイント

  • クラスベースな設計
  • メモリ管理の徹底
  • 遅延管理

問題

  • モジュール数が増えすぎた
  • 読み込むjsの数が300ちかくに

1画面300KBに…

というわけで、JavaScriptをコンパイルすることにした。

Closure Compilerを使用
最適化レベルを選べる(最大最適化(Advanced Compilation))
1画面90KBになった

  • ある規模以上のUIになってくるとJavaScriptの設計を考える必要がある
  • コードが増えてもコンパイルすればよい

kintoneの裏

kintoneでできること
DnDでフォームを作成する

フォームを使うので、データを作成、管理できる
データが増えてきたら、もちろんソートも可能になるし、
レポートの集計もできる

日報や社員情報も管理できる

スキーマレスなデータを管理しないといけない

スキーマレスデータの保存方法
選択肢はたくさんある
NoSQL? mongoDB? CouchDB?

リレーショナルデータベース?
PostgreSQL

独自のデータストア?

なぜデータベースはMySQLなのか?

データの内容はユーザーによって違う
NoSQLは整列、集計、JOINに制限
データの一貫性、安全性を重視

オープンソースで実績のあるシステム
他製品との統一、エンジニアの制限

スキーマレスなデータをどう扱うの?

案1 フォームを変更するたびに、テーブル構造を同期する?
alter や deleteをそのたびに使う
DDLトランザクション外なので厳しい

案2 カラムがたくさんあるテーブルを作っておけば、どんなスキーマでも大丈
夫?

ありとあらゆる予想されるテーブルを予め作成する。
でもあまり賢くないよね

案3 kintoneのやりかた
データテーブル
スキーマレスなデータを保存

インデックステーブル
カラムと値を展開

1. スキーマレスなデータでjsonぽく保存する

2. 文字列型インデックス、日付型インデックスなど、インデックスを
統合することで、ひとつのテーブルを作成する
カラム

column value id
氏名 ほげ 1
氏名 ほむ 2
性別 1
性別 2
id column value column value
1 氏名 ほげ 性別
2 氏名 ほむ 性別

みたいに纏める

columnで絞り込み、valueで絞り込み、整列する
データテーブルからbodyを取る

良いところ

  • フォームの変化に即時対応出来る
    • インデックステーブルにデータを追加したり削除するだけ
  • テーブルと同じように扱える
    • 絞り込み、並び換え、集計
    • 他のテーブルと結合も出来る

NoSQLだと、他のデータベースとの連携が出来ない


悪いところ

カラム単位の更新、一括更新が出来ない
更新のログ情報だけを保存し、データを取るときはマージするなどの対策
インデックステーブルだけを更新するという手も可

インデックステーブルも巨大になる
必要な部分だけでインデックステーブルを作成したり、
パーティショニングが必要

クエリが複雑になる

まとめ
MySQLスキーマレスなデータをあつかう。
データとインデックスを別々に扱う
元データに影響を与えずにスキーマ変更できるので、
大量のデータを扱う場合にも有効

他にも
アクセス権評価
クエリ記法
非同期処理