EP20 - OpenAI Drama + 框架渲染和 Signal
如果上禮拜有在關注新聞的話應該知道 OpenAI 最近的 drama,11/17 中午 OpenAI CEO Sam Altman 收到董事會的消息說他被開除了而同一時間也和另一位 co-founder Greg Brockman 說會把他踢出董事會但會繼續雇用他在 OpenAI 工作,但當 Greg 發現 Sam 被開除後他也很帥的同進退也不幹了,OpenAI 也發表聲明了這件事情也說是因為 Sam Altman對股東和董事會不誠實讓他們覺得 Sam 不適合繼續當 CEO,CTO Mira Murati 會暫任 CEO 而 OpenAI 也會尋找其他人來接任 CEO 位子,正當大家還在猜到底真的發生什麼事的時候,有更多在 OpenAI 工作很久的人也一起共進退辭職了,隔了兩天說在和 Sam 討論他回來繼續當 CEO 的可能不過晚上就說找到 Twitch 前 CEO Emmet Shear 來當 CEO,然後,我現在說的這些感覺都在同一時間發生,微軟 CEO Satya Nadella 說 Sam 和 Greg 以及其他同進退的人都會加入微軟帶領他們 AI 團隊,而這才星期天而已,隔天傳出 Sam 還是在繼續洽談能回去的可能,中間傳出新聞說 OpenAI 在問 Anthropic 就是做了 Claude AI 的那間公司說能不能合併,這邊我在想該不會一間能幫助人來進步的公司要因為人為操弄在一夕間就毀了吧,這時候 OpenAI 內部一封連署說希望把 Sam Altman 邀請回來繼續當 CEO 而且董事會要重組,要不然這些員工都要去微軟工作了,有趣的是這連署信上面 Ilya Sutskever 的名字,也是目前覺得是把 Sam Altman 踢掉的始作俑者,週二宣布 Sam Altman 回去當 CEO 而其他之前離職的人也都回去了,董事會也被重組了,希望到此徹底落幕。那很多人在猜到底發生什麼事,沒有確切證據我也不想 spread rumors,有人說董事會收到 email 關於他們研究的 AI 可能會對人類帶來災難性的未來;有人說 Sam Altman 只想要 profit 而不管公司的本來的 mission;有人說是未來人為了打贏未來的人類 AI 戰爭而回來修改歷史的,反正希望之後會有一個正式的 investigation 和報告講當初發生了什麼事,從外面來看感覺整件事情被執行的很倉促,感覺有什麼隱情。
這集想聊聊 Signal 和 rendering,最早期的當前端有了 ajax 可以用之後,我們會叫 API 然後更新我們前端的畫面,當時就很土法煉鋼只能通過 DOM API 來手動的抓那個 DOM 來做更新,後來前端越來越複雜然後有更多資料需要展示時候尤其還可以不需要透過重新整理頁面來更新畫面,直接更新 DOM 對效能來說其實挺慢的因為除了要找到那個 DOM 以外,每次更新時瀏覽器就得重新計算位置和套用 CSS,所以之後的框架也包括現今主流框架 React Angular Vue 等等 by default 都會用 VirtualDOM 來做更新,以 React 為例,我們會設定 useState 來存取及更新我們 UI 要用的 state,這時候 React 會存一份 Virtual DOM tree 用來表示這個 component,之後 React 會把這個 commit 到真的 DOM 才能讓我們看到真的 UI,這時候若 state 更新了 React 會在 Virtual DOM 中計算什麼 DOM 需要更新,這是所謂的 reconciliation step 或是俗稱的 diffing algorithm,最後 commit 到真的 DOM 就是我們看到的 UI。
在 React 中我們會用 props 把 parent state 傳給 child components,React 的 Context API 也是類似的道理但 Virtual DOM 沒辦法知道說哪一個 props 或 state 是刻在哪一個 DOM 但知道是在哪個 component 所以 React 看到 props 更新了它直接全部 re-render 然後再比對什麼 DOM 需要更新,也有可能其實沒有東西需要 update 所以這個步驟就多餘了,React 提供了 useMemo 和 useCallback 來做 memoization 這樣我們開發者可以自定義也告訴 React 這個 component 其實不用更新這樣可以跳過 reconciliation step,不過 React 也說有時候會比較慢尤其 state 多的話因為 React 得一個一個 state 去比對哪一個有更新,有時候砍掉 re-render 比較快,後來 React 說他們在開發一個 compiler 叫 React Forget 這樣在 compiling step 時候自動加上 memoization,目前聽說 Meta 內部在測試但還沒開放出來給大眾使用,那這些 effort 都是建立在需要用 Virtual DOM 來做比對和更新,慢慢的很多人開始重新思考有沒有什麼方法可以更好的優化這整個過程,Preact 是一個非常類似 React 但更小更輕便而且API 和 React 幾乎一樣,很多人覺得 React 臃腫而且很多不必要的 API 所以弄了個 Preact,Preact 裡面有個特色後來也可以在 React 中使用的 Preact Signals,React 我們會用 useState 來建立一個新的 state 而 Signal 除了可以達成同樣的事情,它會給你一個 Signal object,若要取出或是更新資料得直接叫 .value 才能拿到那個值,如果你用 props 的方式傳下去,因為 Signal 本身是 object 這樣傳都是 reference,除非你直接用 .value 否則中間這些 components 都不會 re-render,因為這樣,當 signal.value 更新後,只有真的使用到這個 signal 的值的 component 才會 re-render,光是這樣就可以優化 Virtual DOM 的渲染步驟跳過多餘的檢查和 diffing,另一個也是用 JSX 的框架叫 Solidjs,用過 React 的人看 Solid 會覺得好眼熟只是有些 function 不一樣,特別講 Solid 是因為他們底層也是用 Signal 的哲學來管理 application states,而 Solid 也更進一步的不考慮使用 Virtual DOM 而直接更新 actual DOM,因為 compiler 的幫忙他們可以知道哪些 Signal 會更新到哪一些 DOM 就不用像 React 這樣在 runtime 的時候再決定。
其他框架比如 Vue 3 在導入 Composition API 時候也有類似的語法和效果也已經有點像是現在比較廣義的 Signal 定義了只是當時 Signal 還沒有這麼廣泛的利用,但最終還是會往 Signal 方向走。Angular 16 當時也在決定是否採用 Signal 或是繼續使用 RxJS 來做 state management,後來 community 大方向覺得 Signal 比較好所以在 Angular 16 正式採用 Signal。話說我那天本來想試試看 Nextjs app router 能不能也用 preact signal,還好我先去看看 github 發現有問題也還沒修復,會直接整個 application crash,我就好吧,以後有什麼想試試看的東西就先去 github 看一下免得做白工
如果你喜歡這內容的話幫我在 Twitter 和 Threads 上面分享給其他正在前端這條路上努力的朋友們,也別忘了訂閱我們電子報收到第一手消息喔 🚀