近年、Web制作の現場では「ノーコード(NoCode)」や「ローコード(LowCode)」が花盛りです。Webflow、Bubble、Framer、そして国産のSTUDIOなど、素晴らしいツールが次々と登場し、私たちもプロトタイプ作成やLP制作などでその恩恵を受けてきました。
「もうコードなんて書かなくていいんじゃないか?」
一瞬、そんな甘美な囁きが脳裏をよぎります。しかし、サービスの規模が大きくなり、クライアントの要求が「機能」から「体験(UX)」や「資産価値」へとシフトした瞬間、私たちは必ず**「ノーコードの壁」**に直面します。
今回は、一度はノーコードの利便性に触れた私たちが、なぜ今再びNext.js(App Router)とTypeScriptを用いたフルスクラッチ開発に舵を切ったのか。その理由を、技術的な観点(パフォーマンス、拡張性、開発体験)から、実際のコードを交えて赤裸々に語ります。
これは、ノーコードを否定するものではなく、**「技術選定の解像度」**を上げるための記録です。
1. 序論:ノーコード開発が抱える「80:20のジレンマ」
ノーコードツールは魔法の杖です。通常の開発なら1週間かかる実装を、ドラッグ&ドロップだけで数時間で終わらせることができます。しかし、プロジェクトが進むにつれて、ある法則が牙を剥きます。
**「パレートの法則(80:20の法則)」**です。
- 最初の80%(基本機能): ノーコードなら爆速で完成する。
- 残りの20%(独自のこだわり・複雑な要件): ノーコードでは実現不可能か、極めてトリッキーなハックが必要になる。
この「残りの20%」こそが、Studio Puffとしてのブランド価値であり、エンジニアの腕の見せ所です。私たちは、この20%を妥協しないために、エディタに戻ることを決意しました。
2. 理由①:ブラックボックス化したDOM構造とパフォーマンス(Lighthouse)
ノーコードツールの最大の弱点は、**「出力されるHTML/CSSを完全には制御できない」**という点です。
多くのツールは、スタイリングの自由度を確保するために、過剰な<div>のネストや、未使用のJavaScriptライブラリを大量にバンドルします。これは「Core Web Vitals」、特にLCP(Largest Contentful Paint)やCLS(Cumulative Layout Shift)に悪影響を及ぼします。
現場のリアル:divの迷宮
ブラウザの開発者ツールを開いてみてください。シンプルなボタン一つを表示するために、何層ものラッパー要素が生成されていませんか?
HTML
<div class="wrapper-xyz-123">
<div class="container-inner-absolute">
<div class="element-padding-box">
<div class="content-text-style">
Click Me
</div>
</div>
</div>
</div>
Next.jsによる解決策:セマンティックかつ軽量なマークアップ
フルスクラッチであれば、私たちはHTMLを1行単位で制御できます。Next.jsのnext/fontやnext/imageを活用することで、アセットの最適化も自動化されます。
TypeScript
// Next.js (React) でのクリーンな実装
import Link from 'next/link';
import { buttonVariants } from '@/components/ui/button';
export function CallToAction() {
return (
// 必要最小限のDOM構造
<section className="flex justify-center p-8">
<Link href="/contact" className={buttonVariants({ variant: "primary" })}>
お問い合わせ
</Link>
</section>
);
}
この差は、モバイル回線での表示速度に直結します。「表示が0.1秒遅れるごとに売上が1%下がる」と言われるECやコンバージョン重視のサイトにおいて、このDOMの制御権は生命線なのです。
【ここにLighthouseのスコア比較画像を貼る(ノーコード版:黄色/赤 vs Next.js版:オールグリーン)】
3. 理由②:動的なデータ制御とAPI連携の「自由度」
ノーコードツールにもCMS機能やAPI連携機能はあります。しかし、それはあくまで「用意されたレールの上」での話です。
例えば、以下のような要件が発生した時、ノーコードでは「詰み」になりがちです。
- 複雑な条件分岐: 「ユーザーの過去の購入履歴に基づいて、表示するバナーを動的に変えたい」
- 外部APIの集約: 「Amazon APIから取得した商品データと、自社DBの在庫データをマージして表示したい」
- 例外処理: 「APIがタイムアウトした時だけ、キャッシュされたデータを表示しつつ、裏で再試行したい」
コードで書けば、世界は自由だ
TypeScriptを用いれば、複雑なビジネスロジックも型安全に記述できます。以下は、複数のAPIを並列で叩き、データを加工して返す「BFF(Backend For Frontend)」的な処理の例です。
TypeScript
// app/api/products/route.ts
import { NextResponse } from 'next/server';
interface ProductData {
id: string;
price: number;
stock: boolean;
}
export async function GET() {
try {
// Amazon APIと自社在庫APIを並列取得
const [amazonRes, stockRes] = await Promise.all([
fetch('https://api.amazon.com/...', { next: { revalidate: 3600 } }),
fetch('https://api.studiopuff.com/stock', { cache: 'no-store' }),
]);
if (!amazonRes.ok || !stockRes.ok) {
throw new Error('Data fetch failed');
}
const products = await amazonRes.json();
const stocks = await stockRes.json();
// データのマージ処理(ここがノーコードでは辛い!)
const combinedData = products.map((p: any) => ({
...p,
isInStock: stocks[p.id] > 0,
discountText: p.price > 10000 ? '送料無料' : '送料別',
}));
return NextResponse.json(combinedData);
} catch (error) {
// エラーログをSentry等に送信
console.error(error);
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
}
}
このように、「データがどうあるべきか」を細部まで定義できるのは、プログラミング言語の特権です。
4. 理由③:開発体験(DX)と「チームでの資産化」
意外と見落とされがちなのが、「ソースコード管理(Git)」の有無です。
ノーコードツールの多くは、バージョン管理機能を持っていますが、それは「履歴に戻れる」だけです。エンジニアチームが求めているのは、もっと高度なコラボレーションです。
ノーコード開発の現場での悩み
- 「誰がどこを変更したのか追えない」
- 「Aさんが編集中だから、Bさんは触れない(ロックがかかる)」
- 「共通コンポーネントの修正が、意図しないページで崩れを引き起こす」
GitHubを中心としたモダンなワークフロー
コードベースであれば、GitとGitHubを用いた強力なエコシステムを活用できます。これは単なる管理ツールではなく、**「品質を担保する仕組み」**です。
- Pull Request (PR): コードレビューを経て初めて本番に反映される。
- CI/CD (GitHub Actions): テスト、Lint(構文チェック)、Type Checkが自動で走る。
- Renovate: ライブラリの依存関係を自動で最新に保つ。
YAML
# .github/workflows/ci.yml の例
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Install dependencies
run: npm ci
# ここで品質を担保!
- name: Run Lint
run: npm run lint
- name: Run Type Check
run: npm run type-check
- name: Run Test
run: npm run test
この「自動化された安心感」があるからこそ、私たちは大規模なリファクタリングや機能追加を恐れずに進めることができます。
【ここにGitHubのコミットログやActionsが成功している緑色のチェックマークのスクショを貼る】
5. まとめ:ノーコードは「敵」ではなく「使い分け」
ここまでフルスクラッチの利点を語ってきましたが、私たちはノーコードを捨てたわけではありません。
- 検証(MVP)フェーズ: スピード優先でノーコードを使用。
- グロースフェーズ: 品質の安定と拡張性を求めてNext.jsへ移行。
重要なのは、**「プロジェクトのフェーズと目的に応じて、最適な技術スタックを選定できる目」**を持つことです。
もしあなたが、「ノーコードで作ったサイトの表示が遅い」「やりたい機能が実装できない」と悩んでいるなら、それはサイトが成長し、次のステージ(コードの世界)へ進む合図かもしれません。
Studio Puff Tech Blogでは、今後もこうした「現場の技術選定」や「移行の苦労話」を、コードと共に発信していきます。