多年來,倡導網頁標準、效能和無障礙的專家們不斷敦促網頁開發者「善用平台」。我自己也常常是其中一員。
這個論點很簡單:既然瀏覽器能為你完成某些功能,為何還要自己用 JavaScript 從頭建構?無論你怎麼做,效能和使用者體驗很可能都比不上瀏覽器直接提供的原生功能。
我認為,從另一個角度來探討這個問題是值得的,即使只是為了理解那些對「平台」持懷疑態度的開發者們的想法。如果「善用平台」如此顯而易見,為何有這麼多人似乎需要被說服?
最明顯的原因是歷史因素:長久以來,瀏覽器一直在追趕其上層生態系的腳步。像 jQuery 這樣的函式庫填補了關鍵的不足,而瀏覽器則在逐步實施相應的 API——即使如此,你也可能得等到像 IE6 這樣的落後瀏覽器被淘汰後,才能真正使用它們。如今,大多數瀏覽器都是長青的(Safari 雖有爭議,但一年更新約七次也不算差),但在大約 2020 年代之前,網頁開發者必須應對一個相當不穩定的網頁環境。在這種環境下,自行開發是個合理的選擇。
另一個原因是熟悉度:當你習慣在 npm 上尋找 React 組件時,無論遇到什麼問題,你傾向於都會去找它們。如果你在 npm 上搜尋「固定定位」,不會有任何套件會告訴你「你這個笨蛋,直接用 CSS 的 position: sticky 就好了」。
而且,即使有健全的標準,npm 上的函式庫也常常能在框架的易用性與底層平台之間填補有用的空白。我一直覺得很有趣的是,許多 React 開發者寧願堅持使用 JSX 和 React 的慣用語——原始的 DOM API 感覺「黏糊糊的」——但卻很樂意使用那些涉及大量原始 DOM 操作的低階函式庫。例如,一個虛擬列表函式庫可能會為了純粹的效能而使用原始 DOM API,同時暴露給新手 React 開發者更容易理解的高階原語。從某種意義上說,React 組件的生態系促成了一種自然的勞動分工,讓那些更有專業知識的人將不熟悉的平台 API 包裝成更熟悉的樣式。
這種效應的部分原因也來自文件。許多 npm 套件都有精心編寫的 README 或網站,提供範例、教學和截圖。然而,直到 MDN 成為網頁文件(而 Google 的未來導向部門是 web.dev)的固定去處之前,網頁平台的說明文件散佈在部落格、StackOverflow 和 CSS Tricks 等網站上。而許多這些網站只是會告訴你使用像 jQuery 或 GreenSock 這樣廣為人知的函式庫!
如果這僅僅是關於第三方函式庫與平台 API 的問題,那麼我認為這無法完全解釋對「善用平台」的厭惡。那些懶惰的開發者(或者我重複說了嗎?),只想為他們遇到的任何問題找到現成的解決方案,他們不太會在乎這個解決方案是來自 npm、瀏覽器,還是從某人的 GitHub Gist 上複製來的。他們只想解決問題然後繼續前進。但還有一種我想要探討的、反對「善用平台」的來源。
對某種類型的開發者來說,自己動手建構東西就是更有趣。而且最終的程式碼往往更容易理解,特別是如果你對網頁平台沒有百科全書般的知識。一旦你建構了某樣東西,可能會產生一種 IKEA 效應,讓你想要維護和調整自己親手寫的程式碼。
舉個例子,想像一下你正在嘗試建構一個模態對話框。你可能在視覺上理解它們應該如何運作:內容出現在螢幕上,但背景仍然可見,儘管部分被遮擋,而且點擊對話框外部可能會關閉它。所以你可能會使用 position:absolute 和 z-index 來正確定位對話框——啊哈,但背景仍然會捲動,所以你必須停用 body 的 overflow……然後,如果你對無障礙有一定了解,你會意識到你需要處理 Esc 鍵關閉、建構一個焦點陷阱,並將焦點返回到啟動對話框的元素,以及……
對許多開發者來說,我剛才描述的聽起來像是一場惡夢(而且是建構一個半成品的好方法)。但對許多開發者來說,這聽起來很有趣!想想看,當你開始建構這個東西時,你學到了多少東西。想想看你如何透過添加動畫、主題、可選的「關閉」按鈕來加入自己的風格……不知不覺中,你就建構了一個可以發布到 npm 的函式庫。這比直接抓取 `<dialog>` 然後就結束了要有趣得多——多麼掃興啊!
而且對我們許多人來說,在像 `<dialog>` 這樣的 API 出現之前,這就是我們學習網頁平台的方式!許多現在倡導「善用平台」的人,曾經自己也是 polyfills、shims 和函式庫的作者。我知道,因為我自己就是其中一員!我花了數年時間研究 IndexedDB、WebSQL 和其他瀏覽器儲存 API 的工具,這是作為我 PouchDB 工作的一部分,最終讓我對自己有足夠的信心,能夠參加 W3C 標準會議,甚至對 IndexedDB 規格本身提出問題和拉取請求。如果沒有平台中需要填補的空白這個強迫性因素,我不知道我是否會找到興趣或動力去達到那樣的專業水平。
當然,自己動手做並非總是全然的好事。有時這僅僅源於純粹的無知。特別是在網頁平台方面,我認為 JavaScript 解決方案之所以會大量湧現,去解決那些本可以用 CSS 更好地解決的問題,原因之一是許多開發者根本沒有花時間深入了解 CSS 的運作方式。
而且說實話,CSS 在歷史上一直很難理解!這個網站被稱為「CSS Tricks」是有原因的。像 clear fix、floats 和 min-width: 0 trick 這樣的東西幾乎不直觀。與其試圖理解 CSS 的內部演算法,不如想像你想要的命令式邏輯,然後用 JavaScript 來表達,這通常容易得多。此外,多年來 CSS 沒有直接的方法來表達常見的模式,如行截斷、textarea 調整大小、捲動條隱藏等。所以開發者當然會用他們已經理解的工具來自己建構。
我甚至不認為這種「迴避平台」的現象僅限於網頁。它適用於任何在他們不完全理解的平台上工作的開發者。例如,在我工作的地方,我們使用 ClickHouse 來儲存各種分析數據。有一次,我和我的同事在如何將大型 JSON 數據儲存在欄位中發生了爭執:他建立了一個在儲存前壓縮它的系統,而我則將數據放入一個單獨的鍵值儲存中,只將鍵插入 ClickHouse。結果我們都錯了!ClickHouse 會自動壓縮數據,而且作為一個欄式數據儲存,如果你讓 ClickHouse 來處理,實際上可以獲得跨行的更好壓縮效果。而單獨的鍵值儲存只是欄式 SELECT 本身所做事情的一個簡化版本。
我直到實際花時間仔細閱讀 ClickHouse 文件,然後編寫基準測試來證明我的假設後,才意識到這些。最後,我對我們建構了一個比平台本身開箱即用功能更慢、更笨拙的東西感到震驚。與 JavaScript 和網頁平台的相似之處很難被忽略。
我敢肯定,如果你是 iOS 或 Android 的開發者,或者是在遊戲引擎上開發的人,或者實際上是任何在任何平台層之上開發的開發者,你可能也有類似的故事。這就是為什麼經驗豐富的資深工程師的刻板印象是那種能夠將初級工程師複雜糾結的程式碼變成一行程式碼的人。你學得越多,就越能運用你對整個系統端到端運作方式的知識,來對其做出最小的貢獻(從而長期減少你的維護負擔)。
我一直在努力避免在這篇文章中談論 AI(因為我過去一年已經談論得夠多了),但當然,我忍不住想知道 AI 編碼將如何影響這種現象。我實際上既有樂觀也有悲觀的看法:
在我自己使用 AI 編碼的經驗中,我同時看到了這兩種現象。我想相信,隨著模型和編碼工具的進步,我們將開始更多地傾向於樂觀的結果,但我無法確定。
總之,這些是我對「善用平台」這個說法冗長且有些矛盾的想法。作為一個口號,我喜歡它,因為它簡潔地捕捉了我看到一些過度設計的混亂程式碼時的感受,並思考如果作者對底層有更好的理解,那會是多麼更好、更優雅。同時,我也曾是那樣的作者,並感受過建構如此美麗、混亂的程式碼(至少對我來說是美麗的)的樂趣,所以我認為理解這些開發者為何這樣做是值得的。因此,我確信只要有平台存在,「善用平台」這個說法就會一直存在。
你可以在 fediverse 或 Lobsters 上評論。




