キャンバスとコードの出会い: Figmaのコードレイヤーの構築



もし、デザインとビルドを同じキャンバス上で行えるとしたらどうでしょう。ここでは、デザインとコードを結びつけるために、どのようにコードレイヤーを作成したかを紹介します。
キャンバスとコードの出会い: Figmaのコードレイヤーの構築を共有
イラスト: Fiona Ye
先週、Figma Sitesの新しいレイヤータイプであるコードレイヤーのベータ版をリリースしました。これはReactコードによってレンダリングされるレイヤーです。ユーザーはコードレイヤーを使用することで、Webの機能をビジュアルキャンバスにフルに活用し、フォーム、シェーダー、インタラクション、APIなどを用いたインタラクティブな体験を構築できます。同時に、コードレイヤーは他のFigmaレイヤーと同様に、フレーム内にネストしたり、コンポーネント内で使用したり、キャンバス上で自由に移動・サイズ変更したりすることができます。さらに、Figma Makeで活用している同じAIモデルを使用して、ユーザーはボタンをクリックするだけで、Figmaで作成したデザインを即座にコードレイヤーに変換し、動作を追加することができます。
Figmaでコードレイヤーを構築するには、デザインとコードという2つの異なるソフトウェアの考え方を調和させる必要があります。現在、Figmaのビジュアルキャンバスは、ユーザーがデザインを迅速に反復できる、自由度が高く柔軟な環境となっています。コードはさらなる機能の可能性を解き放ちますが、より構造化されており、階層的な構成と正確な構文が求められます。これら2つのモデルを調和させるためには、デザインの迅速で探求的な性質を尊重しつつ、コードの持つ全機能を最大限に引き出すハイブリッドなアプローチを構築する必要があります。
これを成功させるためには、次の3つの課題を解決する必要があります。
- コードレイヤーやコンポーネントをFigmaのエコシステムに自然に統合する
- コードカスタマイズを強化するための強力で使いやすいIDEの構築
- デザイナーと開発者の間でマルチプレイヤーコラボレーションを有効にする
素材としてのコード
コードは従来、ファイルシステムとして構成されています。つまり、ディレクトリのツリー構造であり、コードファイルがその末端ノードとなります。このモデルは開発には最適ですが、Figmaの空間的な2Dキャンバスとは相容れにくい面があります。例えば、オブジェクトはビジュアルキャンバスのどこにでも存在できますが、コードファイルはファイルシステム内の特定の場所に存在します。この不一致は、ワークフローにおいて実用的な課題をもたらします。特定のファイル位置に対応するビジュアルレイヤーを、どのようにコピーすればよいのでしょうか? 真実の情報源はキャンバスなのか、それともファイルシステムでしょうか? コードレイヤーを複製する際、コードの世界では一般的な、インスタンス作成を行うべきか、それともFigmaにおける従来の複製方法である、分岐したバージョン作成を行うべきでしょうか?
Figmaのコード機能が、デザイナーと開発者の双方にとって馴染みやすいものにする必要があることはわかっていました。つまり、ユーザーが空間キャンバス上でコードレイヤーを自由に操作できる機能を維持すべきだということです。そこで私たちが導き出した解決策は、コードレイヤーを新しいキャンバスプリミティブとして実装することでした。コードレイヤーは他のレイヤーと同様に動作し、完全な空間的柔軟性(移動、サイズ変更、親レイヤーの変更など)とシームレスなレイアウト統合(オートレイアウトスタックへの配置など)を備えています。最も重要な点は、コードレイヤーを簡単に複製・反復処理できることで、ビジュアルキャンバスの自由で実験的な性質を再現していることです。これにより、異なるバージョンのコードを並べて作成・比較することが可能になります。通常、比較のためにコードを2つ複製するには、別々のGitブランチを作成する必要がありますが、コードレイヤーを使えば、⌥キーを押しながらドラッグするだけで済みます。これにより、ソースコードの分岐が自動的に作成され、迅速な改良が可能になります。
Reactをサポートすることにしたのは、そのコンポーネントモデルがFigmaのコンポーネントの概念と密接に一致しているからです。Figmaのコンポーネントは、デザイナーがインターフェースを構築するために使用する、再利用可能で柔軟な構成要素です。Reactも同様に機能します。開発者は再利用可能なReactコンポーネントを組み合わせて、画面やアプリを構築します。さらに、ReactのpropsはFigmaのコンポーネントプロパティの概念と直接対応しているため、両者を連携させました。コードでプロパティを定義した後、トグル、スライダー、ドロップダウンなどのカスタマイズ可能なコントロールを使用して、視覚的に編集することができます。

すべてが揃ったWeb上のIDE
コードレイヤーはAIだけで作成・編集することも可能ですが、ユーザーが完全な柔軟性を求めて、コードを直接編集したいというニーズもあると私たちは考えていました。これをシームレスに実現するため、Figmaに最新のコード編集機能をビルトインしました。その第一歩として、IDEの中核エンジンとしてCodeMirrorを採用しました。
CodeMirrorは、Webベースのコード編集のための拡張可能な基盤を提供しており、カラーテーマ、検索・置換、行番号などの機能に対する拡張機能を定義できます。多くの場合、コードエディターをFigmaに統合するために、デフォルトの動作をオーバーライドする必要がありました。例えば、CodeMirrorのデフォルトの元に戻す/やり直しの動作を、独自の元に戻すスタックに基づいたカスタム実装に置き換えました。
私たちは早い段階から、特に大規模なコードベースにおいて、パフォーマンスがボトルネックになり得ることを認識していました。バンドルや型チェックといったIDEの処理は時間がかかりがちで、JavaScriptはシングルスレッドであるため、大規模なファイルを処理する際にUIがフリーズしてしまうことがあります。Figmaのコード環境を高速に保つため、開発ツールチェーンの大部分をWeb Worker上で実行しています。ワーカーの内部では、迅速なバンドル時間を実現するためにesbuild (Figmaの共同創業者Evan Wallaceが作成)を使用し、効率的なスタイルコンパイルのためにTailwind v4とLightning CSSを採用しています。これらのツールは一部がネイティブコードで記述され、WebAssemblyにコンパイルされるため、パフォーマンスが大幅に向上します。
依存関係の管理の複雑さを最小限に抑えるために、NPMまたはESM URLからインポートされたパッケージは自動的にインストールされます。package.jsonを初期化する必要はありません。必要なライブラリをインポートするだけで、安全なサンドボックス環境でビルドを開始できます。MotionやReact-Three-Fiberといったコミュニティで人気のパッケージを含め、ほとんどのパッケージはFigma内でそのまま利用可能です。

コードレイヤーの共同編集を実現する
Figmaの中心にあるのは、マルチプレイヤーのコラボレーションであり、これによりチームは効率的に協力して優れた体験をデザインし、リリースすることができます。私たちのマルチプレイヤー技術は、位置や色などの多くのノードフィールドの同時調整をサポートしています。しかし、数千行にも及ぶ可能性のあるソースコードのような複雑なフィールドに対しては、これまでこの技術が活用されたことはありませんでした。
この新たな要件は、私たちのアプローチを見直す好機となりました。編集内容を同期させる最も単純な解決策は、最終書き込み優先(last-write-wins)方式であり、各ユーザーによる変更が他のユーザーの変更を上書きします。これは、Figmaのデザイン内のUXコピーのような短いテキストには有効ですが、大規模なソースコードファイルを同時に編集する場合、特に通信速度が遅い環境では機能しなくなります。また、AIモデルがコードに対して同時編集を行い、さらなる競合を引き起こすことで、この問題がさらに深刻化することも判明しました。
操作変換(OT)は、実行順序とコンテキストに基づいて操作を調整することにより、収束を達成するために同時発生する操作を変換する競合解決の技法です。
そこで、より優れた代替案を探し、操作変換(OT)やコンフリクトフリーの複製データ型(CRDT)といった、従来の共同テキスト編集アルゴリズムに注目しました。OTは、競合する操作を変換することで、競合なく適用できるようにします。これは、Googleドキュメントなど、多くの共同テキストエディターの基盤技術となっています。しかし、競合の多いファイルをマージする際には処理が遅くなります。競合するすべての編集内容を互いに照らし合わせて変換しなければならないからです。
コンフリクトフリーの複製データ型(CRDTs)は、操作の順序にかかわらず、すべてのレプリカが同じ状態に収束することを保証することで、最終的な一貫性を保証するデータ構造です。
一方、ほとんどのCRDTでは、各文字を独立したエンティティとして扱います。これにより、編集内容のマージは格段に容易になりますが、メモリのオーバーヘッドは大きくなります。更新を処理するには、たとえ同時編集が行われていない場合(これが最も一般的なユースケース)でも、ドキュメントの履歴全体をメモリ上に再構築する必要があります。これによりメモリ使用量が膨れ上がり、パフォーマンスが低下します。
幸いなことに、昨年発表された論文で、OTとCRDT両方の利点のほとんどを兼ね備えた新しいアルゴリズム、Event Graph Walker (Eg-walker)が紹介されました。Eg-walkerは、編集操作を因果有向非巡回イベントグラフとして表現します。そのアルゴリズムはgitのrebaseに類似しており、複数の分岐したブランチを線形な順序に再配置します。同時発生したイベントをマージするために、Eg-walkerは一時的にCRDT構造を構築します。解決アルゴリズムが完了すると、Eg-walkerは内部のCRDTを破棄し、メモリを解放します。順次かつ競合のない編集が行われる理想的なケースでは、更新コストはほぼゼロになります。その結果、マージ処理の速度はCRDTと同等でありながら、メモリオーバーヘッドはOTと同様に最小限に抑えられます。

パフォーマンスとメモリ使用量の面で優れていることから、コードレイヤー向けのマルチプレイヤー共同編集サービスの構築にEg-walkerアルゴリズムを採用しました。ユーザーがコードファイルを編集すると、クライアントは編集リストをサーバーに送信します。サーバーはEg-walkerを使用して、アクティブなすべてのクライアントからの同時編集を調整し、競合を解決した上で、更新された編集リストをクライアントに返します。このアーキテクチャにより、マルチプレイヤーサービスがすべてのクライアントに代わって計算負荷の高いマージ作業を処理するため、初回のロード時間が速く、大規模なファイルシステムであってもパフォーマンスの高いユーザーエクスペリエンスを実現します。
コードとデザインの未来
原則に基づく発明
影響力のある作家、研究者、インターフェースデザイナーであるBret Victorは、「ほとんどの人が口にしない生き方」について語っています。自分にとって重要で、必要で、正しいと信じる指針を見つけ、それを原動力にする方法について、同氏の講演の全編をご覧ください。
コードレイヤーは、Figmaにおけるコード機能の始まりに過ぎません。今後、コードレイヤーへの直接操作機能をさらに拡充し、コードとデザインのワークフロー間の隔たりをさらに縮めていく予定です。これにより、ユーザーは状況に応じて、シームレスに作業環境を切り替えることができるようになります。
インターフェースデザイナーのBret Victorは、講演「Inventing On Principle (原則に基づいて発明する)」の中で、「クリエイターは、自分が作り出しているものとの即時のつながりが必要だ……何かを作っているとき、変更を加えたり決断を下したりしたなら、その効果を即座に確認できる必要がある」と述べています。Figmaにおけるコードの機能を拡張し続ける中で、私たちはある考えを指針としています。それは、デザインとコードを別々のツールで分断するのではなく、共有された環境の中で、誰もが共に作成できるようにすべきだということです。
Figma Sitesでは現在、コードレイヤーがベータ版で提供されています。皆さんが作り出すものを見るのを楽しみにしています。




