TinyPilot: Month 23

Michael Lynch

TinyPilot: 23ヶ月目

要約

8ヶ月にわたるリデザインがついに完了しました!

ハイライト

  • TinyPilotのウェブサイトのリデザインがついに完了しました。
  • Debianパッケージの作り方を学びました。驚くほど簡単でした。
  • Vueをはじめ、フロントエンドフレームワーク全般を使うのをやめました。

目標の達成度

毎月月初に、その月に達成したい目標を掲げています。目標に対する結果は次のとおりです。

TinyPilotを使った自宅ラボ用NASサーバー構築についてのブログ記事と動画を公開する

振り返りや年末レビュー以外では、1年以上ぶりのブログ記事でした。redditでの反応はいまひとつでしたが、Hacker Newsでは2位まで上がりました。

この記事が多くの訪問者をTinyPilotのウェブサイトに呼び込み、月間ユニーク訪問者数は14,000人に達しました。過去最高を30%上回る記録です。記事と動画の制作には約45時間かけましたが、その努力に見合う成果が得られました。

TinyPilotウェブサイトのリデザインを完了させる

  • 結果: ついに完了しました!
  • 評価: A

リデザインがついに完了しました。ここ4ヶ月間、毎月「今月こそ終わるはず」と思っていましたが、そのたびに何かが起きて遅延していました。今回は正式に完了です。

マーケティングの代理店またはフリーランスを採用する

  • 結果: 6月に入って数日でフリーランスを採用しました
  • 評価: B

条件が合いそうな代理店が見つかったのですが、少し引っかかる点がありました。3ヶ月契約で料金にも合意したのですが、合意した後になって「最低5ヶ月にしてほしい」と言われたのです。これは大きな危険信号でした。何とか折り合いをつけようと話し合いを続けましたが、提案内容にはどれも疑問が残ったため、最終的に話を打ち切りました。

幸い、電気設計を担当してくれているパートナー企業から、デジタルマーケティングのフリーランスを紹介してもらいました。初めての通話から、これまで話した誰よりも相性が良く、その場で採用を決めました。

TinyPilotの統計

指標2022年4月2022年5月増減
ユニーク訪問者数5,26814,296+9,028 (+171%)
総ページビュー数11,97424,131+12,157 (+102%)
販売売上$43,771.00$54,844.20+$11,073.20 (+25%)
エンタープライズ向けサブスクリプション$47.75$47.750
ロイヤリティ$2,253.61$3,269.56+$1,015.95 (+45%)
総売上$46,072.36$58,161.51+$12,089.15 (+26%)
利益-$19,392.76$6,445.38+$25,838.14 (+inf%)

訪問者数も売上も好調な月でした。訪問者数は3倍近くに増え、売上は25%伸びました。

訪問者の大半はHacker News経由でしたが、売上への影響はあまり見られませんでした。記事がHacker Newsに掲載される前から、売上はすでに4月比で約25%増のペースで推移していたのです。ただ、効果が遅れて表れている可能性もあり、6月は例年になく好調な滑り出しを見せています。

TinyPilotウェブサイトのリデザイン

さて、リデザインの話です。

何から話せばよいでしょうか。

何ヶ月も引きずってきたプロジェクトで、終わりはいつも「あと数週間」というところにあるように感じていました。

このプロジェクトの開始時にデザイナーや代理店と面談した際、私は「予算は8,000〜15,000ドル、期間は2ヶ月程度のリデザインを考えています。6ヶ月もかけて40,000ドルも費やした挙句、売上に効果があったかどうかも分からない、という事態は絶対に避けたい」と伝えていました。

結局、プロジェクトは8ヶ月かかり、費用は46,000ドルに膨らみました。避けたかった罠に、まさに自ら落ちてしまったわけです。

この経験については改めて詳しい記事を書く予定ですが、主な失敗点は次のとおりです。

  • スコープが広すぎた: スコープを小さく絞るべきでした。代理店に全面的なリデザインを任せる前に、まずはリブランディングから始めるべきでした。
  • 工数報告のタイムラグが大きすぎた: 2週間遅れではなく、発生した時点で請求時間を報告してもらう仕組みを徹底すべきでした。どれだけ時間がかかっているかがすぐに分からなければ、想定より高額になったときにスコープを調整できません。
  • スケジュールの透明性が不足していた: プロジェクトがどれだけ長引いているかに驚かされることがないよう、タイムラインについてもっと密にコミュニケーションを取るべきでした。
  • マネジメントの時間が不足していた: 月40時間稼働する代理店も、月40時間稼働する個人のフリーランスも、マネジメントの手間は同じ程度だろうと想定していました。しかし代理店は関わる人数が多く、人数が増えればマネジメントの負荷も増えます

それでも、成果を見てみましょう。今回のプロジェクトでは、購入フローに関わる3つのページをリデザインしました。ランディングページ、製品ページ、そしてショッピングカートのページです。

旧ランディングページのスクリーンショット新ランディングページのスクリーンショット

リデザイン前後のランディングページ

旧Voyager 2製品ページのスクリーンショット新Voyager 2製品ページのスクリーンショット

リデザイン前後の製品ページ

旧ショッピングカートページのスクリーンショット新ショッピングカートページのスクリーンショット

リデザイン前後のショッピングカートページ

費用面を除けば、結果には満足しています。新しいデザインは、以前のものより明らかに良くなったと思います。新しいロゴや画像によって、よりプロフェッショナルで独自性のある印象になりました。

では、新しいデザインは良くなったとして、それは46,000ドル分の価値があるのでしょうか?

もし時間を巻き戻せるなら、ここまでの金額と時間をリデザインに費やすことはしなかったでしょう。それでも、投資を回収できる可能性は十分にあります。

固定費を除くと、TinyPilotの販売売上の70%が利益になります。つまり、リデザインの元を取るには66,000ドルの追加売上が必要です。もし売上が10%伸びれば、月平均50,000ドルから55,000ドルに増える計算です。そうなれば約1年で回収できます。さらにマーケティングが改善してサイトへの流入が増えれば、回収はもっと早まるでしょう。

Debianパッケージは簡単

TinyPilotで私が下した奇妙な設計判断のひとつに、インストールとアップデートの仕組みがあります。私たちはAnsibleを使っています。これは本来、DevOpsエンジニアが大規模にシステムをプロビジョニングするためのツールです。私はTinyPilotの最初のプロトタイプでRaspberry PiをプロビジョニングするのにAnsibleを使いました。その方法がうまくいったので、ずっとそのままにしてきたのです。

Linuxにソフトウェアをインストールする手段としては、もっと良い方法があることは分かっていました。ただ、その経験がありませんでした。TinyPilotはRaspberry Piのハードウェア機能を独特な方法で設定する必要があり、標準的なインストールツールを要件に合わせる作業を考えると気が重かったのです。そこで、Ansibleが問題なく動いていたこともあり、使い続けていました。動作は遅く、本来なら数秒で終わるはずのインストールに2分もかかっていましたが、我慢できる範囲でした。

2年が経ち、Ansibleの限界が見えてきました。インストール処理は複雑になりすぎ、アップデートには5分以上かかるようになっています。

以前からDebianパッケージ(例えばapt-get)も検討していましたが、Debianのパッケージングツールについては悪い評判を耳にしていました。さらにリポジトリサーバーや鍵ペア、パッケージの署名プロセスなども必要だと聞き、基本的な環境を整えるだけでも膨大な手間がかかり、必要なことを実現するのも非常に面倒そうに思えました。

試しにDebianパッケージを作ってみたところ、恐れていたよりずっと簡単でした。Debianパッケージは、特定のフォルダ構成といくつかの特別なファイルを持つtarボールに過ぎません。初めての.debファイルは、約1時間で作れました。

リポジトリサーバーや鍵ペアはどうなのかというと、実は必須ではありません。.debファイルを直接配布すれば、リポジトリを用意しなくても済むのです。

debhelperは、Debianパッケージ作成の公式ツールですが、噂どおり分かりにくく扱いづらいものでした。ただ、そもそも使う必要はありませんでした。debhelperを使わず、Debianのメタデータファイルを手作業で生成する方が簡単だと分かったのです。

さらに良いことに、AnsibleからDebianパッケージへ一気に恐ろしい切り替えをする必要もありません。自分たちのペースで、少しずつロジックをAnsibleからDebianパッケージへ移行できるのです。

最初のDebianパッケージは、オープンソースのWebRTCサーバーであるJanus用のものです。これまでは各デバイスでソースからコンパイルしており、約30分かかっていました。新しいDebianパッケージなら数秒でインストールできます。しかも32ビットARMバイナリが必要な場合でも、DockerのQEMU統合を使えばx64のクラウドサーバー上でDebianパッケージをビルドできます。コンパイルとパッケージングに関するコードはすべてオープンソースとして公開しています。

Debianパッケージについて学ぶ際に役立った資料をいくつか紹介します。

検索広告の効果は頭打ちに

前回計算したとき、Googleの検索広告は素晴らしい成果に見えました。Google広告に1ドル費やすごとに0.69ドルの利益が出ていたのです。しかし、さらに時間が経ちデータが増えたことで、見え方はそれほど楽観的ではなくなりました。

先月数値を集計した際は、4月と5月の第1週を含めていました。その第1週が外れ値だったため、月ごとに分けてみると利益は目減りします。

指標4月5月
広告費$804.12$4,283.71
表示回数5,270239,498
クリック数3513,327
クリック率(CTR)6.6%1.4%
クリック単価(CPC)$2.29$1.29
コンバージョンによる売上$1,314.91$7,649.60
広告費用対効果(ROAS)1.631.79

売上の約30%はハードウェアと人件費に消えるため、ROASが1.43でほぼ損益分岐点(1.43 - 30% = 1.0)になります。それ以上であれば利益が出ます。5月は1.79なので、広告費1ドルあたり0.26ドルの利益が出ていることになり、引き続き継続します。

TinyPilotの新しいデジタルマーケティングコンサルタントがGoogle広告アカウントを確認し、価値の低いキーワードに過剰に支出している箇所をいくつか指摘してくれました。今後数ヶ月で、これらの数値は改善できる見込みです。

サイドプロジェクト

PicoShare

PicoShareは、メールでは送れないような大きなファイルの共有を手軽にする、3月に私が公開したオープンソースツールです。

5月には、アップロード後にファイルのメタデータを編集できる機能を追加しました。

PicoShareのメタデータ編集画面のスクリーンショット

5月にPicoShareでファイルのメタデータ編集に対応しました。

当初は、ファイルをアップロードする際にメモを追加したり有効期限を設定したりできましたが、一度決めたら変更できませんでした。現在はより柔軟になり、ファイルのメタデータや有効期限をいつでも変更できます。

編集画面を追加したことで、ファイル削除の操作をより安全にする良い機会だと気づきました。以前はファイル一覧で削除ボタンをクリックすると、確認もなく、元に戻す手段もなくファイルが消えてしまいました。現在は、ファイルを削除するにはまず編集画面を開き、削除をクリックしてから確認する必要があります。

PicoShareの削除確認ダイアログのスクリーンショット

誤ってファイルを削除してしまうことを防ぐため、確認ダイアログを追加しました。

WanderJest

2020年初頭、私は身近なライブコメディを探せるサイト、WanderJestの開発を進めていました。パンデミックの影響で3月に開発を中断しましたが、徐々に日常が戻るにつれ、週末や夜の時間を使ってWanderJestの開発を再開しています。

PicoShareを開発していて強く感じたことのひとつは、技術スタックをシンプルにすることで開発速度がどれだけ上がるかということです。

PicoShareWanderJest
バックエンドGoGo
フロントエンドGoテンプレート + HTML5Vue 2
データストアSQLite + LitestreamFirestore

Firestoreはスキーマ変更が非常に難しいため、開発の足かせになっています。私が知る唯一の方法は、カスタムの移行コードを書いて本番サーバーにデプロイすることです。SQLiteなら、本番データベースをダウンロードし、SQLクエリを書いて試行錯誤したうえで、サーバーに反映するだけで済みます。

現在、VueをGoのテンプレートに、FirestoreをSQLiteに置き換える形でWanderJestを再実装しています。

現在のWanderJestライブサイトのスクリーンショットGoベースで再実装中の新しいWanderJestサイトのスクリーンショット

現在のVueベースのWanderJestサイト(左)と、GoのHTMLテンプレートで再実装中のWanderJest(右)

Goでフロントエンドを書くのは、思っていたより簡単です。初期の開発体験はVueほど快適ではありません。条件付きレンダリングやリアクティブなプロパティが欲しくなりますが、素のJSではそれらは得られません。ただ、全体としてGoでのページ描画はずっとシンプルです。

Vueでページにデータを描画する際の手順は次のとおりでした。

  1. バックエンドがデータストアからデータを取得する。
  2. バックエンドが、フロントエンドに渡したいプロパティだけを含むデータのコピーを作成する。
  3. バックエンドがデータをJSONにシリアライズする。
  4. フロントエンドがバックエンドからJSONデータを取得する。
  5. フロントエンドが取得したデータに基づいてページ要素を描画する。

一方、Goのテンプレートでページを描画する場合は、わずか2ステップです。

  1. バックエンドがデータストアからデータを取得する。
  2. バックエンドがデータストアのデータを使ってページテンプレートを埋める。

Goでフロントエンドをレンダリングすれば、バックエンドがフロントエンドにどのデータを公開するか、どのようにシリアライズ・デシリアライズするか、ローカルキャッシュをどう管理するかといった作業をすべて省くことができます。

Vue版と同等の機能を実装できるまで待つ必要がありますが、総コード量を約50%削減できる見込みです。

まとめ

今月できたこと

  • TinyPilotのウェブサイトのリデザインを完了しました。
  • TinyPilotの新バージョンをリリースしました。
  • 自宅ラボ用NASサーバーに関する新しいブログ記事を公開しました。
  • デジタルマーケティングのフリーランスを採用しました。

学んだこと

  • Debianパッケージは見た目より簡単です。
  • フロントエンドフレームワークなしの方が楽に開発できます。

来月の目標

  • TinyPilotインストール用の自己完結型tarボールを作成する。
  • TinyPilotウェブサイトのリデザインに関する長編ブログ記事の初稿を完成させる。
  • 有料検索広告のROASを2.0まで引き上げる。

原文は Michael Lynch により に公開されました。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。