初めまして。Qitta初投稿です。
2ヶ月で「Draw.ioとCacooを足して200で割ったアプリ」をReactで作った話です。ポエムはNoteに(ChatGPTがあることないこと)書いたので良ければ。
きっかけ
小さなSIerにいるんですが、いつまで経っても仕事でAI使う機会が出てず(大丈夫かSI業界)、ChatGPT-4oみて流石にマズいなと思い、個人開発で試したというところです。
Clineが良さそうですが、まずはスタンダードにGithubCopilot + ChatGPTでどれだけ効率変わるか、実際触って試してました。
あと、図形エディタのような高頻度なレンダリングにReactが耐えれるか試したかったのもあります。
できたもの
何かできるって段階にはまだ至ってないんですが、それらしく動くようになっています。それがこちら。
機能は大体こんな感じです。
- 四角形・円・線の作成
- 図形の移動・回転・拡大縮小・反転
- 図形内へのテキスト入力、文字サイズ・色・アライメントの変更
- 図形の塗りつぶし・枠線のスタイル変更
- 線分の頂点の追加・移動(※削除作るの忘れてた)
- グループ化およびグループ単位での変形
- 図形同士の接続(※時々千切れる不具合あり)
- Undo/Redo機能(※未完成・不安定)
- AIによる図形の自動作成(※実験的・非公開)
作っているうちにAI使う前のスピード感忘れてきましたが(今後見積ミスりそう...)、少なくとも効率が2〜3倍になったと思います。もっとかも。
ちなみにライブラリは基本Reactのみです。移動・変形・回転・反転等々全部自分で書いてます(この辺はAIもあんまりやってくれなかった)。
現状のdependencies。classnamesは使ってないけどいつの間にか居ました記憶がない。
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"classnames": "^2.5.1",
"openai": "^4.91.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
Reactは高頻度描画に耐えられたのか?
答えはYes/Noのどちらでもありました。DOMの直接操作はせずに済んだのですが、メモ化をしても「dependencies array」の評価が地味に重く、以下のように「dependencies array」は空配列にして、参照をuseRefでバイパスしないと耐えられませんでした。
// Create references bypass to avoid function creation in every render.
const refBusVal = {
id,
items,
startOwnerId,
endOwnerId,
autoRouting,
onDiagramChange,
canvasStateProvider,
};
const refBus = useRef(refBusVal);
refBus.current = refBusVal;
...
/**
* Handle Path component change event.
*/
const handlePathChange = useCallback((e: DiagramChangeEvent) => {
// Bypass references to avoid function creation in every render.
const { onDiagramChange } = refBus.current;
onDiagramChange?.({
...e,
endDiagram: {
...e.endDiagram,
autoRouting: false,
},
});
}, []);
アンチパターンではあると思いますが意外と可読性は下がらなかったので、高頻度な描画にはこの参照をパイパスするやり方が思います。ちなみにDOMを直接操作するのは複雑化しすぎてナシでした。
今後
直近は図形エディタとしての機能を作っていきますが、将来的には図形を書く感覚でAIエージェントだったりワークフローを組めるようにしたいなと、今のとこは思ってます。Difyでいいじゃんって話ですが、AI技術の進化は予測困難だと思うので、少なくとも必要であろうUIの基盤は自分で持っておきたいなと思っています。