TinyPilot: Month 23

Michael Lynch

TinyPilot:23ヶ月目

原文は Michael Lynch により に公開されました。 このブログを購読する

一言でまとめると

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

ハイライト

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

目標の達成度

毎月のはじめに、その月に達成したい目標を宣言している。結果はこうなった。

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

1年以上ぶりに、振り返りや年末レビューではないブログ記事を書いた。Redditでの反応はいまひとつだったが、Hacker Newsでは2位まで上がった。

この記事によって多くの訪問者がTinyPilotのウェブサイトに流れ込み、月間ユニークビジター数は1万4000人に達した。過去最高で、従来の記録を30%上回る数字だ。記事の執筆と動画制作に約45時間を費やしたので、この結果はその努力を正当化してくれた。

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

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

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

マーケティングの代理店またはフリーランスを雇う

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

相性が良さそうな代理店を1社見つけたが、どこか引っかかる感じがした。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ドルをかけたいと伝えた。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で私がした奇妙な設計判断の1つが、インストールとアップデートの仕組みだ。私たちは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月のROASは1.79なので、広告に1ドル使うごとに0.26ドルの利益が出ていることになり、まだ続ける価値がある。

TinyPilotの新しいデジタルマーケティングのコンサルタントが私のGoogle広告アカウントをレビューし、価値の低いキーワードに過剰に支出している箇所をいくつか特定してくれた。今後数ヶ月でこれらの数字を改善できる可能性は高そうだ。

サイドプロジェクト

PicoShare

PicoShareは、3月にリリースしたオープンソースツールで、メールでは送れない大きなファイルを共有するためのものだ。

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

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

5月にPicoShareでファイルのメタデータを編集できるようにした。

以前は、ファイルをアップロードする際にメモを追加したり有効期限を選んだりできたが、一度決めたら変更できなかった。今ではPicoShareがより柔軟になり、ファイルのメタデータや有効期限をいつでも変更できるようになった。

編集画面を追加した後、ファイル削除のプロセスをより間違いが起きにくくする良い機会だと気づいた。以前はファイル一覧で削除ボタンをクリックすると、確認も元に戻す手段もなくファイルが消えてしまっていた。今では、ファイルを削除するにはまず編集画面を開き、削除をクリックしてから削除を確認する必要がある。

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

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

WanderJest

2020年初頭、私は近くのライブコメディを見つけるためのサイトWanderJestを開発していた。パンデミックのため3月にサイトを一時停止したが、徐々に日常が戻る中で、週末や夜にWanderJestの開発を再開している。

PicoShareを開発して印象的だったことの1つは、シンプルな技術スタックが開発速度をどれだけ上げるかということだった。

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まで高める。

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

コメント