ブラウザだけで完結する “local-first” ツール群を作った(PDF / 画像 / QR・31言語対応)— UniToolx
タグ(Qiitaに貼る用 / 5つ)
JavaScriptWebアプリ画像処理プライバシー
はじめに(この記事の目的)
Qiita は「再利用性・汎用性の高い内容」が歓迎されるので、この記事は “宣伝だけ” ではなく、local-first(ブラウザ内処理)で PDF / 画像 / QR のツールを作るときにハマるポイントをまとめます。
その上で、実物として作っている UniToolx を最後に貼ります。
コメントで欲しいこと:
- 足りない機能
- 使いづらいUX
- バグ(再現情報があると最高)
背景:なぜ local-first(アップロード無し)にしたのか
PDFや画像は、ちょっと処理したいだけでも、よくこうなります。
- 個人情報が入ったPDFや写真を アップロードしたくない
- 登録が必要・UIが重い・広告やポップアップが多い
- “今すぐ1回だけ” なのに手間が大きい
そこで狙いはシンプルです:
「開いたらすぐ使える」「可能な限りブラウザ内で処理して終わる」
※ただし local-first には制約があります。
端末差、メモリ、PDFの互換性など、無理があるケースは正直に割り切るのが現実的です。
UniToolx(現時点でできること)
入口:https://unitoolx.com/
UIは 31言語対応です。
## 1) QR Generator(QR生成)
できること:
- Link/Text
- Wi-Fi
- Contact(vCard)
- PNGでダウンロード
リンク:https://unitoolx.com/t/qr.html
## 2) Image Converter & Compressor(画像変換/圧縮)
できること:
- 変換 / 圧縮 / リサイズ(バッチ対応)
- 複数ファイルの処理 → まとめてZIPでダウンロード
対応形式:
- JPG / PNG / WebP / GIF / BMP / SVG / ICO / HEIC
注意点:
-
SVGはラスタ化(ピクセル化)します -
HEIC/HEIFは環境によって時間がかかる場合があります
リンク:https://unitoolx.com/t/image.html
## 3) PDF Tools(結合/分割)
できること:
- Merge:複数PDF → 1つ(並べ替え可)
- Split:1ページごと / 範囲指定(例:
1-3, 7, 10-12) - Splitの出力はZIP
リンク:https://unitoolx.com/t/pdf.html
## 4) PDF Editor(PDF編集:注釈/署名/カバー等)
この editor は “Wordみたいな完全編集” ではなく、注釈・署名・マークアップ系が中心です。
できること:
- テキスト追加
- 画像挿入
- 手書き(Draw)
- 署名
- ハイライト
- カバー/Redact(隠す)
- ページ削除
- ページ回転
表示されている上限:100MB
リンク:https://unitoolx.com/t/pdf-editor.html
local-first 実装の勘所(エンジニア向け)
ここからが “再利用できる” 部分です。
local-first はプライバシー面で強い一方、UX/性能/互換性で地雷が多いです。
## 1) 入力UX:最初の1秒で離脱が決まる
ユーザーは「ドラッグ → 即反応」を期待します。入力が雑だと、それだけで信用されません。
基本はこれだけでOK:
const input = document.querySelector('input[type="file"]');
input.addEventListener("change", async () => {
const file = input.files?.[0];
if (!file) return;
// まず ArrayBuffer にする(画像でもPDFでも基本は同じ)
const buf = await file.arrayBuffer();
console.log("name:", file.name);
console.log("type:", file.type);
console.log("size:", file.size);
console.log("bytes:", buf.byteLength);
// TODO: buf を処理して出力へ
});
Drag & Drop も dataTransfer.files から同じ流れで扱うだけです。
## 2) 重い処理でUIを固めない(Worker / 進捗 / エラー)
PDFやHEICは重くなりがち。メインスレッドを塞ぐと体感で終わります。
- 可能なら Web Worker に投げる
- 進捗が取れる場合は
%を出す(安心感が段違い) - エラー時は “次に何をすべきか” が分かるメッセージにする(再試行、軽量化、別ブラウザなど)
雰囲気コード:
// main.js
const worker = new Worker("worker.js");
async function processFile(file) {
const buf = await file.arrayBuffer();
worker.postMessage({ type: "PROCESS", buf, name: file.name }, [buf]);
}
worker.onmessage = (e) => {
const { type } = e.data;
if (type === "PROGRESS") {
// e.data.value: 0..100
console.log("progress:", e.data.value);
}
if (type === "DONE") {
// e.data.output: Blob など想定
console.log("done:", e.data.output);
}
if (type === "ERROR") {
console.error("error:", e.data.message);
}
};
## 3) メモリ管理:local-first の現実
local-first は「サーバーの代わりに端末のメモリを使う」ので、ここを甘くすると壊れます。
- 大きいファイルは 上限を明示(例:100MB)
-
URL.createObjectURL()したらURL.revokeObjectURL()で解放 - 多ページPDFのプレビューは “全ページ一括レンダ” を避ける(段階的に)
インラインコード例:URL.revokeObjectURL(url)
## 4) “扱えないPDF” は必ず出る(例外処理ゲー)
現実にはこういうPDFが混ざります。
- 破損 / 特殊構造 / 変な埋め込み
- 暗号化・パスワード
- ページ数が多すぎてメモリ不足
ここで重要なのは「完全対応」よりも 失敗時の体験です。
- 失敗理由を “ざっくり” でも表示(例:
encrypted/unsupported/out of memory) - ユーザーが再現報告できるテンプレを用意(次のセクション)
## 5) 画像変換:SVGとHEICは注意
画像変換は一見簡単ですが、端末差が出やすいです。
-
SVGはラスタ化するなら注意書き必須(ベクターのままではない) -
HEIC/HEIFは遅い/失敗しやすい環境がある(ブラウザ/端末差) - 圧縮品質は形式依存(JPG/WebP と PNG では意味が違う)
コメントで欲しいこと(バグ報告テンプレ)
2分だけテストして、気づいたことをコメントしてくれたら本当に助かります。
以下テンプレで書いてもらえると、再現→修正が速いです。
## バグ報告テンプレ
- OS / Browser(例:Windows11 + Chrome / macOS + Safari / iOS など)
- どのツール?(QR / Image / PDF Tools / PDF Editor)
- 入力ファイル(形式・サイズ・ページ数・特徴)
- 操作内容(例:splitで
1-3, 7, 10-12) - 結果(固まった / エラー / 出力が壊れた / 想定と違う)
- 再現率(毎回 / たまに)
## “欲しい機能” も聞きたい(率直に)
- PDF Editor:一番ほしい操作は?
例)テキストのフォント/サイズ/色のUI、オブジェクト選択/整列、ページサムネ、精密な移動、Undoの強化 etc. - PDF Tools:分割UI(範囲指定)は分かりやすい?
- Image Tools:現場で一番使う出力形式は?(JPG/PNG/WebP など)
もし良ければ “壊しに来てください”(ストレステスト)
以下みたいなテストが一番ありがたいです。
- 50ページ以上のPDF
- 100MB近いPDF
- iPhoneのHEIC写真
- splitで
1-2, 5, 9-12 - QRのWi-Fi(実際につながるか)
リンク(実物)
- UniToolx:https://unitoolx.com/
- QR Generator:https://unitoolx.com/t/qr.html
- Image Tools:https://unitoolx.com/t/image.html
- PDF Tools:https://unitoolx.com/t/pdf.html
- PDF Editor:https://unitoolx.com/t/pdf-editor.html
おわりに
local-first は「プライバシー」と「速度」に強い一方で、端末差・メモリ・PDFの互換性など難しさもあります。
だからこそ、実環境で踏まれたバグ と 現場の要望 が一番価値があります。
気づいた点があれば、遠慮なくコメントで教えてください。