単一画面の Canvas ツールのスタック選定(vanilla TS / Svelte / Preact と PWA ツーリング)

一言まとめ

画面が 1 つで Canvas 2D が中心の Web ツールでは、React(約 45 KB gzip)はランタイムが precache の負荷になり、Konva / Fabric も不要。vanilla TS + Vite を基本にし、画面や状態が増えたら Svelte 5(約 4 KB)か Preact(約 4 KB)へ。Service Worker は vite-plugin-pwa の generateSW でアプリシェルだけ precache する。

作成 · 更新 · #canvas#pwa#vite#svelte#preact
目次 9 sections
  1. 01 ランタイムのサイズ(min+gzip 概算)
  2. 02 実在する Canvas 系ツールのスタック
  3. 03 フレームワークが死荷重になる条件 / 正解になる条件
  4. 04 Canvas ライブラリは要らない
  5. 05 UI コンポーネントライブラリも要らない
  6. 06 PWA ツーリング: vite-plugin-pwa
  7. 07 画面構成の最小セット
  8. 08 関連
  9. 09 更新履歴

調査時点: 2026-06。公開プロジェクト frost-mosaic(なぞった所をモザイクにする PWA)の技術選定で調べたもの。数値は当時の概算で、Bundlephobia 等で再確認する前提。

Canvas 2D は、HTML の描画領域に JavaScript で図形や画像を描く API。PWA(Progressive Web App)は、インストールやオフライン利用など、アプリに近い機能を備えた Web アプリ。

ランタイムのサイズ(min+gzip 概算)#

フレームワークランタイム備考
vanilla TS / JS0 KB
Preact約 4 KB公式の “3KB” は宣伝値。計測値は 4〜4.3 KB
Svelte 5約 3〜4 KBコンパイラ出力は素の JS。コンポーネントのソース量が約 137 KB を超えると React より大きくなる
SolidJS約 7〜8 KB
Vue 3約 34 KB
React 18 / 19 + ReactDOM約 45 KB

PWA ではこのサイズがそのまま Service Worker の precache に入る。

実在する Canvas 系ツールのスタック#

ツールフレームワークCanvas
ExcalidrawReact + TypeScriptCanvas 2D + Rough.js
SquooshPreact + TypeScript + RollupCanvas + WebAssembly
Photopea非公開(vanilla に近いとみられる)Canvas 2D + 独自エンジン

Excalidraw は共同編集・ルーティング・パッケージ分割など複数画面相当の機能量があり、React の採用理由は画面の複雑さにある。単一画面の画像変換ツールである Squoosh は Preact を選んでいる。

フレームワークが死荷重になる条件 / 正解になる条件#

死荷重になりやすいのは、Canvas の描画ループと Virtual DOM の差分検出を重ねる構成。react-konva の開発者自身が「React + Konva は 2 層の抽象化になり遅くなりうる」と書いている。requestAnimationFrame やピクセル処理を頻繁に回すアプリで顕在化する。

フレームワークが正解になるのは次のいずれかが起きたとき。

  • 画面が複数になる(About、設定、ヘルプなどのルーティングが発生する)
  • スライダーや設定パネルの状態が複雑に相互依存する
  • チームで開発し、コンポーネント規約の恩恵が出る
状況選択
依存ゼロを優先vanilla TS + Vite
状態管理が煩雑になったSvelte 5(約 4 KB)
React エコシステムを使いたいPreact(約 4 KB、Squoosh の実績)
React単一画面 Canvas ツールには過大

Canvas ライブラリは要らない#

ライブラリサイズ目安向く用途
Konva.js約 60 KBドラッグ・変形・イベントバブリング・ヒットテスト
Fabric.js v6200 KB 超SVG import / export、画像編集向けの組み込みブラシ
Paper.js60 KB 超ベジェ・パス操作
p5.js80 KB 超creative coding

フリーハンドのマスクを描いてモザイク / ぼかしを合成する処理は Canvas 2D API だけで書ける。

  • フリーハンド描画: pointermove → ctx.lineTo + ctx.stroke。マスクは OffscreenCanvas の別レイヤーで持つ
  • ぼかし: ctx.filter = "blur(Xpx)"; ctx.drawImage(img, ...)。端のフェードを避けるため、ブラー半径分はみ出して描く
  • モザイク: getImageData でブロックごとの平均色を計算して putImageData、または縮小 → imageSmoothingEnabled = false → 拡大
  • マスク合成: globalCompositeOperation = "destination-in" または "source-atop"

Konva が解決する「オブジェクトの選択・ドラッグ・変形」は、画像上の塗り領域を扱うツールには出てこない。

UI コンポーネントライブラリも要らない#

スライダー 4 個・トグル・ボタン数個の規模では、<input type="range"> + 自前 CSS で足りる。ネイティブ要素はキーボード操作とスクリーンリーダーに対応しており、WCAG 2.1 AA の最低基準は満たせる。コンポーネントライブラリ(shadcn/ui は Radix で約 30 KB、MUI は 100 KB 超)が必要になるのは、複雑なコンボボックス・日付ピッカー・aria-live の動的 UI が要るとき。React を採らないなら shadcn/ui も選択肢から外れる。

PWA ツーリング: vite-plugin-pwa#

  • devDependency として動く。Workbox のランタイムは生成される sw.js に埋め込まれ、アプリ本体のバンドルには入らない。virtual:pwa-register を import したときだけ 1 KB 未満の登録スニペットが入る
  • generateSW 戦略で dist/ の HTML / CSS / JS を自動で precache する。画像や利用者のファイルはデフォルトで precache に含まれない
  • injectManifest はバックグラウンド同期やプッシュ通知など独自の SW ロジックが要るときだけ
  • Workbox 7 以降、maximumFileSizeToCacheInBytes(既定 2 MiB)を超えるアセットはビルドエラーになる
  • globPatterns を絞り、アプリシェル(index.html / main.js / style.css)だけ precache する。利用者の画像はキャッシュしない

画面構成の最小セット#

Squoosh・Photopea・Excalidraw はいずれも「ツール自体が着地点で、別のランディングページを持たない」構成。個人 OSS ツールで要るのは 3 点。

  1. エディタ画面(/): ファイルドロップ → 操作 → 保存
  2. About / プライバシー: モーダルか /about。「ブラウザ内で処理・サーバー送信なし・ライセンス」を 3 行程度
  3. UI 内のインラインヒント(「ここをなぞる」程度のマイクロコピー)

専用 LP、FAQ、チュートリアル動画は要らない。

関連#

更新履歴#

  • 2026-06-15: 初版(ローカル調査ノート)
  • 2026-10-17: Wiki へ移植、概念ページとして再構成。冒頭に定義を追加

出典

  1. https://github.com/preactjs/preact/discussions/3325
  2. https://khromov.se/svelte-5-brings-up-to-50-bundle-size-decrease-for-existing-svelte-4-apps/
  3. https://svelte-scaling.acmion.com/
  4. https://bundlephobia.com/package/vue
  5. https://github.com/GoogleChromeLabs/squoosh/blob/dev/package.json
  6. https://github.com/excalidraw/excalidraw
  7. https://konvajs.org/docs/guides/best-canvas-library.html
  8. https://vite-pwa-org.netlify.app/guide/service-worker-precache
  9. https://vite-pwa-org.netlify.app/workbox/generate-sw
  10. https://www.photopea.com/privacy.html

同じトピック — Web