Kalan's Blog

Kalan 頭像照片,在淡水拍攝,淺藍背景

四零二曜日電子報上線啦!訂閱訂起來

本部落主要是關於前端、軟體開發以及我在日本的生活,也會寫一些對時事的觀察和雜感
本部落格支援 RSS feed(全文章內容),可點擊下方 RSS 連結或透過第三方服務設定。若技術文章裡有程式碼語法等特殊樣式,仍建議至原網站瀏覽以獲得最佳體驗。

目前主題 亮色

我會把一些不成文的筆記或是最近的生活雜感放在短筆記,如果有興趣的話可以來看看唷!

Hotwire 與 Turbolinks

前言

DHH (Ruby on Rails 的作者)發了一則推特,在講他的新作 Hotwire。DHH 是個 SPA 黑粉(從推文上可以略知一二),因此他極力避免在開發上加入太多 JavaScript。這則推文在推特上引起熱烈討論,在這邊稍微做個整理。

關於 Hotwire 的介紹在這邊直接引用官方上面的說明:

Hotwire is an alternative approach to building modern web applications without using much JavaScript by sending HTML instead of JSON over the wire

這個說明有兩個重點:

  • 不需要使用 JavaScript
  • 直接傳送 HTML 而非 JSON

這個概念其實不是最近才有,早在好幾年前 Ruby on Rails 就是採用類似的手法,叫做 Turbolink

Turbolinks 是一個 JavaScript 套件,通常會搭配 Ruby on Rails 一起使用(單獨當作函式庫使用也可以),主要是透過 fetch HTML 直接抽換的方式來避免直接換頁要重新發送請求、CSS 的成本。其實說「不需要使用 JavaScript」不完全正確,JavaScript 還是在,只是在函式庫那邊已經幫你處理好,所以開發上可以不用寫 JavaScript 而已。

舉例來說,當頁面上有這樣一個 tag:

<a href="/articles/1" data-remote="true">link</a>

如果 Ruby on Rails 有啟用 Turbolinks 的功能,那麼當使用者點擊連結時,實際上並不是重新發送請求,而是 turbolinks 會做類似這樣的事情:

fetch('/index.html').then(res => res.html())
	.then((html) => $page.html(html))

這樣一來當使用者點擊按鈕時,不會重新渲染 HTML,而是先 fetch 那一頁的 HTML 檔案(透過 ajax),然後再透過 JavaScript 直接渲染出來。Ruby on Rails 本身跟 turbolinks 有高度整合,所以有時候幾乎感覺不到 turbolinks 的存在,只會覺得「哇嗚怎麼換頁好像變快了」。

當 HTML 越大效果應該會越來越不明顯,不過 HTML 本身不大的話是可以達到比較好的使用者體驗的。

為什麼這種方式有用?

  • 不需要換頁重新請求 CSS 與 JavaScript,使用者體驗較佳
  • head 的部分 turbolinks 會幫你做處理
  • 幾乎不需要撰寫額外的 JavaScript
  • 後端工程師可以用最小的力氣達到比較好的體驗

需要注意的地方

  • 像是 load 之類的 event,因為 turbolinks 的機制並沒有重新載入整個頁面,所以只有第一次載入會觸發。要記得切換成 turbolinks:load 之類的方式來監聽事件
  • 當 JavaScript 互動越來越多,事件綁定容易彼此衝突。
  • 狀態在換頁不會被消除,所以 JavaScript 沒寫好容易造成記憶體洩漏

當 JavaScript 的互動越來越多的時候,搭配 turbolinks 有時會出現奇怪的現象,像是重複執行造成的錯誤等等。

一些想法

其實身為開發者多少都有寫過 SPA 的經驗,因此大家都知道要寫出一個堪用、好用的 SPA 並不容易,狀態管理沒寫好狂吃記憶體、狀態不同步、錯誤處理沒寫好、動不動就載入一大坨 JavaScript bundle 等等,反而乾脆一些直接用純 SSR 渲染的方式還比較好一些,然後透過 turbolinks 這種方式來增強體驗或許是個不錯的方法。

後記

有人認為 JSON 會比 HTML 小,所以傳輸上會比較有效率,但是 gzipped 過後其實兩者是差不多的,而且 HTML 有時候甚至會比較小。所以直接渲染 HTML 感覺不是那麼罪不可赦的事。

只是目前 Turbolink 整合最好的恐怕也只有 Ruby on Rails,Hotwire 還相對比較新可能部分開發者還在觀望中。

上一篇

2020 年尾聲,來聊聊電腦是什麼

下一篇

2020 回顧 / 2020 Year in Review — 技術篇

如果覺得這篇文章對你有幫助的話,可以考慮到下面的連結請我喝一杯 ☕️ 可以讓我平凡的一天變得閃閃發光 ✨

Buy me a coffee