TinyPilot: Month 23

Michael Lynch

TinyPilot:第 23 個月

一句話總結

耗時八個月的重新設計終於完成了!

重點摘要

  • TinyPilot 網站的重新設計終於完成。
  • 我已經學會製作 Debian packages(Debian 套件),而且出乎意料地簡單。
  • 我已經放棄 Vue 和一般的 frontend frameworks(前端框架)。

目標成績

每個月月初,我都會宣告當月想完成的事項。以下是我達成這些目標的情況:

發布一篇關於使用 TinyPilot 打造自宅實驗室 NAS 伺服器的部落格文章與影片

這是我一年多來第一篇非回顧或年終總結性質的部落格文章。它在 reddit 上的反應平平,但在 Hacker News 上衝上了第 2 名

這篇文章為 TinyPilot 的網站帶來了大量訪客,使單月不重複訪客數達到 1.4 萬。這是歷史新高,比之前的紀錄高出 30%。我花了約 45 小時撰寫文章與製作影片,因此這樣的成果讓投入的時間有了回報。

完成 TinyPilot 網站的重新設計

  • 成果:終於完成了!
  • 評分:A

重新設計終於完成了。過去四個月裡,每個月我都以為這個專案就要收尾,結果總有事情導致延宕。現在,它總算正式完成了。

聘請行銷代理商或自由工作者

  • 成果:六月初的幾天內就聘請了一位自由工作者
  • 評分:B

我找到一家感覺可能合適的代理商,但對他們有點不太放心。我們已就為期三個月的合約價格達成共識,但在我同意後,他們卻要求改為至少五個月。這是一個很大的警訊。我仍嘗試與他們協調,但他們的提案都讓人覺得不太可靠,所以最終我結束了洽談。

幸好,我的電機工程合作夥伴公司推薦了一位數位行銷自由工作者。從第一次通話起,他就比我接觸過的任何人都更合適,所以我當場就聘用了他。

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%)

這個月在訪客數與銷售額方面表現強勁。訪客數幾乎成長為三倍,銷售額則躍升了 25%。

大部分訪客來自 Hacker News,不過似乎對銷售額沒有太大影響。在我發布文章並登上 Hacker News 之前,銷售額就已經有望比 4 月成長約 25%。成效可能會延後顯現,因為我看到 6 月初的開局異常強勁。

TinyPilot 網站重新設計

唉,這次的重新設計。

該怎麼說呢?

這個專案已經拖了好幾個月,而終點總感覺就在幾週之後。

在專案初期面試設計師與代理商時,我告訴他們,我希望花 8,000 至 15,000 美元進行為期幾個月的重新設計。我還強調,我絕對不想要一個得花上六個月、投入 4 萬美元後,才能看出這些改變是否對銷售產生實質影響的專案。

結果,這個專案花了八個月,耗資 4.6 萬美元。我恰好落入了我原本想避免的陷阱。

我之後會寫一篇更長的部落格文章來詳述這次經驗,但主要的錯誤在於:

  • 範圍過於寬泛:我本應將範圍控制在最小,先從品牌重塑開始,再讓代理商擴展為全面的重新設計。
  • 工時回報過慢:我應該堅持要求代理商即時向我回報計費工時,而不是延遲兩週才回報。如果我無法看到一項任務耗時多久,就無法在發現成本超出預期時及時調整範圍。
  • 時程安排缺乏透明度:我應該更積極要求對方就時程進行更透明的溝通,才不會對專案拖延如此之久感到措手不及。
  • 管理時間不足:我原以為每月工時 40 小時的代理商,與每月工時 40 小時的個人自由工作者所需的管理成本差不多。代理商涉及更多人員,而更多的人員意味著需要更多的管理

不過,來看看成果吧。這次專案包含了結帳流程中三個頁面的重新設計:首頁、產品頁與購物車頁面:

舊版首頁截圖新版首頁截圖

首頁重新設計前後對比

舊版 Voyager 2 產品頁截圖新版 Voyager 2 產品頁截圖

產品頁重新設計前後對比

舊版購物車頁面截圖新版購物車頁面截圖

購物車頁面重新設計前後對比

撇開花費不談,我對成果感到滿意。我認為新設計無疑比舊版更好。新的標誌與圖片讓專案看起來更專業、更具辨識度。

所以,新設計確實更好,但它真的值 4.6 萬美元嗎?

如果能回到過去,我肯定不會花這麼多錢、投入這麼多時間在重新設計上。不過,它仍有可能自行回本。

扣除固定成本後,TinyPilot 銷售營收中有 70% 是獲利。這意味著重新設計必須帶來 6.6 萬美元的額外銷售額才能回本。如果它能讓銷售額提升 10%,我的月平均營收就會從 5 萬美元增加到 5.5 萬美元。這樣大約一年就能回本。如果更好的行銷能吸引更多顧客造訪網站,我回本的速度會更快。

Debian packages 其實很簡單

我在 TinyPilot 上做的一個奇怪設計決策是它的安裝與更新機制。我們使用 Ansible 來處理,這是一套為 DevOps 工程師大規模佈建系統而設計的工具。我當初就是用 Ansible 來佈建搭載第一代 TinyPilot 原型的 Raspberry Pi。這個流程可行,所以我們就一直沿用下來。

我知道在 Linux 上有更好的軟體安裝解決方案,但我沒有相關經驗。TinyPilot 在設定 Raspberry Pi 硬體功能方面有特殊需求,所以我很排斥去調整標準安裝工具以符合這些需求。相反地,我們繼續使用 Ansible,因為它運作正常,也沒有造成什麼問題。只是速度較慢,原本幾秒鐘就能完成的安裝得花上兩分鐘,但還不算太糟。

兩年下來,我們已經把 Ansible 推到極限。安裝流程變得越來越複雜,更新甚至要花五分鐘以上。

我過去曾考慮過 Debian packages(例如 apt-get),但聽過不少關於 Debian 打包工具的負面評價。再加上還有所謂的套件庫伺服器、金鑰對與套件簽署流程?光是要把基本環境架起來似乎就要耗費巨大心力,更別說要實現我們需要的功能,簡直是自找麻煩。

作為實驗,我試著建置了一個 Debian package,結果發現比我想像中簡單得多。Debian packages 不過是具有特定資料夾結構與幾個特殊檔案的 tarball。我大約花了一小時就做出了第一個可運作的 .deb 檔案。

至於套件庫伺服器和金鑰對?其實那是選用的。你可以直接散布 .deb 套件檔,完全不需要套件庫。

debhelper 這個建立 Debian packages 的官方工具,確實如傳聞中那般令人困惑又難用,但其實並非必要。我們發現直接跳過 debhelper、手動產生 Debian 的詮釋資料檔案反而更簡單。

更棒的是,我們不必一次就從 Ansible 驚險地全面切換到 Debian packages。我們可以按照自己的步調,逐步將邏輯從 Ansible 轉移到 Debian packages。

我們的第一個 Debian package 是給 Janus 這個開源 WebRTC 伺服器用的。過去我們在每台裝置上從原始碼編譯這個應用程式,得花約 30 分鐘。現在新的 Debian package 幾秒鐘就能安裝完成。而且即使我們需要 32 位元 ARM 執行檔,也能在 x64 雲端伺服器上透過 Docker 的 QEMU 整合來建置 Debian package。所有用於編譯與打包的程式碼皆已開源

以下是我們在學習 Debian packages 時覺得有幫助的資源:

搜尋廣告的成長趨於平緩

上次計算時,Google 搜尋廣告的表現看起來非常亮眼。我每在 Google Ads 花費 1 美元,就能賺取 0.69 美元的獲利。但隨著時間推移、資料變多,情況就沒那麼樂觀了。

上個月我計算數據時,包含了 4 月與 5 月的第一週。那第一週後來證明是異常值,因此按月區分後,獲利就顯得較弱:

指標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)。高於此數值即為獲利。以 1.79 來說,我每投入 1 美元廣告費仍能賺 0.26 美元,所以我會繼續投放。

TinyPilot 新聘的數位行銷顧問檢視了我的 Google Ads 帳戶,並找出了幾個我在低價值關鍵字上花費過多的地方,因此未來幾個月我們應該能改善這些數據。

支線專案

PicoShare

PicoShare 是我在三月發布的開源工具,用於分享那些因檔案過大而無法透過電子郵件傳送的檔案。

在五月,我新增了上傳後編輯檔案詮釋資料的功能:

PicoShare 中詮釋資料編輯畫面的截圖

五月時,我在 PicoShare 中新增了編輯檔案詮釋資料的功能。

原本,你只能在上傳檔案時新增備註並選擇到期時間,且這些決定一旦做出就無法更改。現在,PicoShare 變得更靈活,允許你隨時變更檔案的詮釋資料與到期日。

新增編輯畫面後,我意識到這是讓刪除流程更不容易出錯的好機會。以前,只要在檔案清單中點擊刪除按鈕,檔案就會立刻消失——沒有確認,也無法復原。現在,刪除檔案必須先進入編輯畫面,點擊刪除後再確認刪除:

PicoShare 中刪除確認對話框的截圖

我新增了確認對話框,以減少誤刪檔案的情況。

WanderJest

2020 年初,我當時正在打造 WanderJest,這是一個幫助人們尋找附近現場喜劇表演的網站。由於疫情,我在三月暫停了這個網站。隨著生活逐漸恢復正常,我在週末與晚間又開始重新投入 WanderJest。

在開發 PicoShare 的過程中,讓我印象深刻的一點是,更簡單的技術堆疊能多大幅度地提升我的開發速度:

PicoShareWanderJest
後端GoGo
前端Go templates + HTML5Vue 2
資料儲存SQLite + LitestreamFirestore

Firestore 會拖慢我的速度,因為要進行結構描述變更非常困難。我所知道的唯一方法就是撰寫客製化的遷移程式碼並部署到正式伺服器。而使用 SQLite,我只需下載正式環境的資料庫,撰寫一些 SQL 查詢來調整,然後再推回伺服器即可。

我現在正在重做 WanderJest,打算以 Go templates 取代 Vue,並以 SQLite 取代 Firestore。

WanderJest 現行網站截圖以 Go 為基礎的新版 WanderJest 網站截圖

現行以 Vue 為基礎的 WanderJest 網站(左)與以 Go HTML templates 重做的進行中版本(右)的對比

用 Go 撰寫前端比我想像中容易。前期的開發體驗不如 Vue 那麼好。我會很想念條件式渲染或響應式屬性,而這些在原生 JS 中是沒有的。但整體而言,用 Go 渲染頁面要簡單得多。

使用 Vue 時,我在頁面上渲染資料的流程是:

  1. 後端從資料儲存區擷取資料。
  2. 後端衍生一份僅包含我們想與前端共享屬性的資料副本。
  3. 後端將資料序列化為 JSON。
  4. 前端從後端擷取 JSON 資料。
  5. 前端根據從後端擷取的資料填入頁面元素。

相比之下,使用 Go templates 渲染頁面只需兩個步驟:

  1. 後端從資料儲存區擷取資料。
  2. 後端以資料儲存區的資料填入頁面範本。

當你在 Go 中渲染前端時,就可以省去所有關於後端要向前端暴露哪些資料、如何序列化與反序列化,以及如何管理本地快取的工作。

我得等到功能與 Vue 版本達到一致後才能確定,但我認為有望將總程式碼行數減少約 50%。

總結

完成了什麼?

  • 完成了 TinyPilot 網站的重新設計。
  • 發布了新的 TinyPilot 版本。
  • 發布了一篇關於我的自宅實驗室 NAS 伺服器的新部落格文章。
  • 聘請了一位數位行銷自由工作者。

學到的經驗

  • Debian packages 比想像中簡單。
  • 沒有 frontend frameworks 的生活更輕鬆。

下個月的目標

  • 為安裝 TinyPilot 建立自給自足的 tarball。
  • 完成一篇關於 TinyPilot 網站重新設計的完整部落格文章初稿。
  • 將付費搜尋廣告的 ROAS 提升至 2.0。

原文由 Michael Lynch 發布

本文章由 muse-spark-1.2-contributor 進行翻譯