前端進階
-前端網頁實現自動儲存的 7 種方式
this.web

自動儲存是前端一個很細節功能,但對使用者的體驗影響很大。特別是在處理複雜表單系統或文檔編輯頁面時,自動儲存能大幅降低資料遺失的風險,也讓操作更加順暢。
在這篇文章中,我將帶你深入了解 7 種自動儲存的實作方式與關鍵細節,幫助你打造更穩定、良好的產品使用體驗。
一、固定時間間隔
在前端自動儲存中,固定時間間隔儲存(Interval Saving) 是最簡單直接的方式。它透過設定週期性時間(如每隔 5 秒)自動觸發儲存行為,特別適合用於短時間內頻繁輸入的表單或簡易筆記應用。
const interval = setInterval(() => {
saveData(data)
}, 5000)優點:
- 實作簡單、穩定。
- 適合短時間內頻繁輸入的場景。
缺點:
- 無論資料是否有改變都會呼叫 API,容易造成不必要的請求。
- 若儲存動作較複雜,會造成效能負擔。
最佳實踐:
- 可以搭配判斷資料是否變動(
hasChanges)來減少冗餘儲存。
二、動作間隔
若希望更貼近使用者輸入節奏,可以採用動作間隔(Debounce Saving) 的方式。這種方法會在使用者停止輸入一段時間後自動儲存,非常常見於編輯器或即時輸入表單中。
const handleChange = (e) => {
debounce((data) => saveData(data), 1000)
}優點:
- 僅在輸入動作結束後才儲存,避免頻繁請求。
- 更貼近使用者實際編輯行為。
缺點:
- 若頁面在等待時間內被關閉,可能遺失最新資料。
最佳實踐:
- 根據表單複雜度調整 debounce 時間。
三、偵測動作靜止
在需要更精準判斷使用者狀態的情況下,偵測使用者閒置(Idle Detection Saving) 是一種進階實作。它會監聽滑鼠與鍵盤活動,當使用者停止操作一段時間後自動觸發儲存。
let idleTimer
const resetIdleTimer = () => {
clearTimeout(idleTimer)
idleTimer = setTimeout(() => {
saveData(data)
}, 3000)
}
window.addEventListener('mousemove', resetIdleTimer)
window.addEventListener('keydown', resetIdleTimer)優點:
- 可降低 API 請求次數。
- 更好地判斷使用者行為。
缺點:
- 稍微複雜,需管理多個事件監聽。
- 若 idle 判斷太短會頻繁觸發,太長又會失去即時性。
最佳實踐:
- 建議 idle 閥值設定在 2~5 秒之間。
- 也可搭配 localStorage 或 indexedDB 暫存,確保即使儲存失敗也不遺失資料。
四、焦點轉移時
另一種常見的前端自動儲存策略是焦點轉移觸發(Blur/Visibility Saving)。當使用者切換輸入框或離開當前頁籤時自動儲存,特別適合多欄位表單或長篇內容編輯器。
輸入框可以使用 onBlur 觸發,如果要偵測用戶是否最小化視窗或切換瀏覽器的 tab,則可以使用 visibilitychange 事件
const handleVisibilityChange = () => {
if (document.visibilityState === 'hidden') {
saveData(data)
}
}
document.addEventListener('visibilitychange', handleVisibilityChange)
優點:
- 更精穩的捕捉使用者離開前的狀態。
- 適合表單類頁面或多欄位輸入。
缺點:
- 若頁面因閃退或網路問題離開,仍可能遺失。
- 若輸入框過多,或用戶快速切換輸入框,會頻繁觸發儲存事件。
- 若輸入內容很大量,例如像 Notion 這種副文本的編輯,則不容易觸發自動儲存
最佳實踐:
- 可以搭配 debounce 避免頻繁切換的情況
五、關閉頁面時
有時候使用者可能會不小心關閉頁面,我們可以使用 beforeunload 搭配 navigator.sendBeacon(),在關閉頁面後還能送資料給伺服器。
不使用傳統 fetch 是因為有些瀏覽器或環境在頁面關閉後就不能使用 http request 了,而 sendBeacon 可以避免這個問題。
const handleBeforeUnload = () => {
navigator.sendBeacon('/api/save', data)
}
window.addEventListener('beforeunload', handleBeforeUnload)優點:
sendBeacon在頁面卸載階段仍可執行,不受瀏覽器阻擋。- 請求為非同步,不會影響頁面的關閉速度。
缺點:
- 不支援舊版 IE、部分早期瀏覽器。
- 某些瀏覽器對 sendBeacon 有大小限制,要注意。
最佳實踐:
- 可搭配 localStorage 或 indexedDB 備份機制作雙保險。
六、網路斷開時
為了應對突發的網路中斷,離線暫存與自動同步機制是進階前端應用不可或缺的一環。這類自動儲存方式可在使用者離線時先暫存資料,待連線恢復後再自動同步到伺服器。
雖然沒網路時,我們不能傳送資料到伺服器做自動儲存,但可以先利用本地儲存,等用戶有網路後再做自動儲存。
const handleOffline = () => {
localStorage.setItem('draft', JSON.stringify(data))
}
const handleOnline = () => {
const draft = localStorage.getItem('draft')
if (draft) {
saveData(JSON.parse(draft))
localStorage.removeItem('draft')
}
}
window.addEventListener('offline', handleOffline)
window.addEventListener('online', handleOnline)優點:
- 保證即使網路中斷也不會遺失資料。
缺點:
- 實作起來稍微複雜,也要考慮資料同步問題。
- 若使用者清除暫存資料,仍會遺失資料。
最佳實踐:
- 也搭配 IndexedDB 或 Service Worker 進行離線暫存以及恢復連線後的同步。
- 斷線後顯示【網路已斷開】等提示
七、Websockets 斷聯時
這個方式比較適用於即時協作類應用(如 Google Docs),當偵測到 WebSocket 連線中斷時,自動觸發一次緊急儲存。
socket.onclose = () => {
savedata(data)
}優點:
- 能確保協作資料在中斷前被保留。
- 對即時編輯、多人文件特別關鍵。
缺點:
- 依賴 WebSocket 狀態,不適用於非即時應用。
- 若儲存邏輯與後端同步機制沒設計好,可能發生資料上的衝突。
最佳實踐:
- 搭配版本號或編輯時間戳。
- 斷線後可顯示暫存提示,等重連後自動同步。
總結
自動儲存雖然是很細節功能,但對使用者體驗與資料安全也非常重要。
無論是固定時間間隔、自動偵測輸入、還是離線儲存,每種方式都有其適用場景與取捨。
實務上,我們前端工程師通常會根據應用的性質與使用者行為,混合多種自動儲存策略來達到最佳的效果。
這篇文章主要是想提供自動儲存的思路,因此省略了一些像是資料同步、資料序列化、資料大小等細節,在自己專案上實作時仍要注意~!
資料參考:To save or to autosave: Autosaving patterns in modern web applications | by Brooklyn Dippo | Medium