自我思考 - 停更三年,回來才發現網站也壞了兩年。

image

這個部落格最後一篇文章是 2023-05-24,之後停了三年。這次回來想更新,第一件事不是寫文章,是發現網站根本部署不了。最後一次成功部署停在 2024-05,也就是說它已經壞了兩年,而這兩年裡沒有任何人告訴我,包括我自己。這篇是關於那三年我去做了什麼,以及為什麼「不會的時候,人是寫不出東西的」。

最後一篇文章的日期,剛好在換工作前一週

2023-05-24 發文,2023-06 進新公司

我沒有刻意停更。回頭看時間點才發現,最後那幾篇面試日記寫完、offer 拿到、進了新公司,然後就沒有然後了。

新工作跟我原本做的事不一樣。以前我是「寫前端的」,到了新公司變成前後台都要碰,而且手機 App 是開發跟維護都要做。

不是接手別人寫好的東西改一改就好,新功能得自己從頭做,既有的也得自己顧下去。

換句話說,我不只是在一個陌生的平台上修東西,是要在那個平台上做決定。而做決定這件事,需要的是「真的懂」,不是「查得到」。

工作忙起來是一個原因,但那不是真正的原因。忙的時候人還是有辦法擠出時間做喜歡的事。真正的原因比較難承認。

我從一個我會的領域,跳到一個我不會的領域。

然後我遇到了 ANR

前端沒有這種東西:畫面卡住不只是難看,是作業系統直接把你的 App 判死刑

在網頁上,主執行緒被卡住的後果是畫面頓一下、動畫掉幀、使用者覺得這網站有點慢。不好,但不致命。

在 Android 上,主執行緒卡太久,系統會跳出一個對話框問使用者「這個應用程式沒有回應,要關閉嗎」。這就是 ANR(Application Not Responding)。

它不是你的程式碼丟出的錯誤,是作業系統對你下的判決。

第一次遇到的時候我完全不知道從哪裡查起。錯誤訊息不會告訴你「你哪一行寫錯了」,因為根本沒有哪一行寫錯:每一行單獨看都是對的,錯的是它們加起來太慢。

而且它不是使用者回報給我的,是我自己測出來的。把測試資料灌多一點之後,App 開始卡,卡到系統跳出那個對話框。

資料少的時候一切正常,我原本以為那就代表沒問題。

從 ANR 追到 SQLite

症狀跟根因隔了三層,這是我學到最多的一次除錯

追查的路徑大概是這樣:先確認不是單一功能的 bug,而是效能問題;再往下找是哪一段耗時;最後追到資料庫。

問題不只一個,是三個疊在一起:

  • 在迴圈裡查資料庫。一個列表跑迴圈,每一筆都去查一次,十筆就是十次查詢
  • 缺索引。沒有索引的查詢就是整張表掃過去,資料少的時候快得看不出差別
  • 資料表設計本身有問題,讓上面兩件事變得更容易發生

這三個有一個共同點,資料少的時候全部都看不出來。

而且它們不是相加的,是相乘的。迴圈的次數乘上每次查詢要掃過的資料量。

資料量小的時候,小數字乘小數字還是小數字;資料一多,兩邊同時變大,乘起來就直接把主執行緒卡到系統受不了。

這也是為什麼我一開始完全找不到「哪一行寫錯了」。每一行單獨看都對,錯的是這個設計在資料長大之後撐不住,而它在資料還小的時候完全沒有徵兆。

這段除錯經驗跟我以前在前端做的完全不同。前端的效能問題通常看得見,開 DevTools 就有火焰圖,哪一段慢一目了然。

這次是「東西在使用者手機上偶爾會死,而且不一定重現」。

三年前那篇文章,我自己變成了裡面的人

〈為什麼老是覺得自己不夠好?〉寫在 2023-05-16

那篇裡我寫過一段:

很多時候我們的確會應用一些技術,不論是查看文件或是 Google 都有相當多的範例可以參考⋯⋯但深層的原理如果沒搞懂的話,下次有人問起,要描述或是解說的話大概率又講不出來。

寫那篇的時候,我是站在「已經會前端」的位置上談這件事的。三年後我跳到 Android,變成那個「會用但講不出原理」的人本人。

我還在那篇裡用三步上籃當比喻。不熟練的人一下同手同腳,一下走步,一下力道過猛。當時我覺得那是個講給別人聽的比喻。

追 ANR 那段時間,我就是那個同手同腳的人。

而人在同手同腳的時候,是寫不出文章的。 不是沒時間,是沒有東西可以寫。你正在經歷的事情你自己都還沒搞懂,怎麼寫成一篇給別人看的筆記?

所以停更這件事,與其說是懶惰,不如說是我暫時失去了「可以拿出來講的東西」。

網站是怎麼安靜爛掉的

沒有人在看,也沒有任何機制會告訴你它壞了

這次回來清點,才知道這三年裡它爛成什麼樣子:

  • 部署從 2024-05 之後就沒成功過。 原因是 Vercel 上的 Node 版本被釘在 18.x,而 Node 18 已經下架,建置在 clone 完就中止。那個版本號只存在 dashboard 的下拉選單裡,沒進版本控制,所以沒有任何東西會提醒我
  • /contact 的表單是死的。 <form action="">,送出不會有訊息送達任何地方。掛在站上三年,訪客按了以為寄出,我什麼都沒收到
  • post-6 裡我寫「目前暫定 6/7(三) 前要給回應,到時再更新狀況」,然後三年沒回來改那一行
  • 7 篇文章裡有 16 處格式錯誤,中文散文被包在程式碼區塊裡,在網頁上被語法高亮切成隨機顏色

這些沒有一項是「我知道但懶得修」。全部都是我不知道。

一個沒有人在看、也沒有任何機制會回報狀態的系統,就是會這樣安靜地爛掉,而且爛的過程完全沒有聲音。

這次補的是機制,不是決心

說「以後會常常更新」沒有用,我三年前就說過類似的話了

所以這次回來,我沒有先寫文章,而是先把上面那些坑補起來,而且是用下次會自己叫我的方式補:

  • Node 版本寫進 package.json 的 engines,變成一個有 diff、有 commit 記錄的東西,而不是下拉選單裡的一個選項
  • 死掉的表單整頁移除,聯絡方式改成一個實測收得到信的信箱
  • 補上每頁的 title 與 description、sitemap、RSS。在那之前,/blog、/portfolio 加上 7 篇文章頁,九個頁面全部連 <title> 標籤都沒有
  • 寫了一支檢查器,接在存檔的 hook 上。以後只要文章格式有問題,當場就會被擋下來,不用等我想起來去檢查

最後這一項是我覺得最重要的。那 16 處格式錯誤,我當年每一處寫下來的時候都覺得很合理。

不會覺得有錯的錯誤,不會有人主動去檢查。 所以能救的只有機制,不是提醒自己要小心。

所以呢

不做承諾,只講現在的狀態

我不打算說「以後會固定更新」。三年前的我大概也不覺得自己會停三年。

能說的只有:現在網站是活的,信箱是通的,寫壞了會有東西擋我,而我手上重新有了一些「搞懂了、可以拿出來講」的東西。就先這樣,寫得出來就寫。

如果你也有一個停更很久的部落格,我猜你的狀況可能跟我一樣。不是懶,是那段時間你正在變成一個新的菜鳥。

那沒什麼好丟臉的,等你從同手同腳變回會上籃,東西自然就寫得出來了。