介紹
2017年9月,Cloudflare推出了 Cloudflare Workers,提供了在他們的邊緣網路上執行 JavaScript 的能力。這意味著您的程式碼將在全球一百多個位置的整個邊緣網路上部署,大約30秒。這項技術讓您可以專注於在靠近使用者的地方編寫應用程式,無論他們在世界的哪個地方(約50毫秒延遲)。
Worker 的執行時與 Node.js 或瀏覽器不同,它使用 V8(Google Chrome 開發的 JavaScript 引擎)執行程式碼。到目前為止,您可以在他們的平臺上執行的是在到達伺服器之前在邊緣執行的小指令碼,以提高效能或根據請求頭新增一些邏輯,例如。
2020年11月,在開發 Nuxt 3 時,我們大膽嘗試在生產環境中將 Nuxt 執行在邊緣執行時 / V8 隔離環境上。
這使得在使用 Cloudflare Workers 等平臺時,能夠從世界各地在約50毫秒內伺服器渲染頁面,而無需處理伺服器、負載均衡器和快取,費用約為每百萬請求0.3美元。截至今天,新的平臺正在出現,如 Deno Deploy,允許在 V8 隔離環境上執行應用程式。
挑戰
為了讓 Nuxt 在 Worker 中執行,我們不得不重寫 Nuxt 的一些部分,使其與環境無關(可在 Node.js、瀏覽器或 V8 中執行)。
我們從伺服器開始,建立了unjs/h3:一個為高效能和可移植性而構建的極簡 HTTP 框架。它取代了我們在 Nuxt 2 中使用的Connect,但與它相容,因此您可以繼續使用 Connect/Express 中介軟體。在 Worker 中,對於每個傳入請求,它會啟動 Nuxt 生產環境,將請求傳送給它並返回響應。
在 Nuxt 2 中,在記憶體中啟動生產伺服器(也稱為冷啟動)的持續時間約為300毫秒,因為我們必須載入伺服器和應用程式的所有依賴項才能處理請求。
透過開發 h3,我們決定將附加到伺服器的每個處理程式進行程式碼分割,並僅在請求時才延遲載入它們。當您啟動 Nuxt 3 時,我們只將 h3 和相應的處理程式載入到記憶體中。當請求進來時,我們載入與路由對應的處理程式並執行它。
透過採用這種方法,我們將冷啟動時間從約300毫秒減少到約2毫秒。
為了在邊緣執行 Nuxt,我們面臨另一個挑戰:生產打包大小。這包括伺服器、Vue 應用程式和 Node.js 依賴項的組合。Cloudflare Workers 目前對 Worker 大小有1MB(免費計劃)和5MB(每月5美元計劃)的限制。
為了實現這一目標,我們建立了unjs/nitro,我們的伺服器引擎。當執行 nuxt build
命令時,它會打包您的整個專案,並將所有依賴項包含到最終輸出中。它使用Rollup等等vercel/nft來跟蹤 node_modules
中使用的程式碼,以刪除不必要的程式碼。一個基本的 Nuxt 3 應用程式生成的輸出總大小約為700KB(gzip壓縮後)。
最後,為了在開發(Node.js)和 Cloudflare 生產(邊緣執行時)之間提供相同的開發體驗,我們建立了unjs/unenv:一個透過模擬或新增已知依賴項的 polyfill 來將 JavaScript 程式碼轉換為在任何地方(平臺無關)執行的庫。
在 Nuxt,我們相信您應該有選擇最適合您的託管提供商的自由。
這就是為什麼您可以在
- NuxtHub
- Cloudflare Pages
- Deno Deploy
- Vercel Edge Functions(底層使用 Cloudflare Workers)
- Netlify Edge Functions(底層使用 Deno)
上部署具有邊緣渲染的 Nuxt 應用程式。我們還支援許多其他部署提供商,包括 靜態託管 或 傳統的 Node.js 無伺服器和伺服器託管。
推動全棧能力
現在 Nuxt 可以在邊緣執行時執行,我們可以做的不僅僅是渲染一個 Vue 應用程式。多虧了 server 目錄,建立一個 API 路由只需要一個 TypeScript 檔案。
要新增 /api/hello
路由,請建立一個 server/api/hello.ts
檔案
export default defineEventHandler((event) => {
return {
hello: 'world'
}
})
您現在可以在頁面和元件中普遍呼叫此 API
<script setup>
const { data } = await useFetch('/api/hello')
</script>
<template>
<pre>{{ data }}</pre>
</template>
在建立 useFetch 和 $fetch 時需要注意的一點是,在伺服器端渲染期間,如果您呼叫 API 路由,它將模擬請求並直接呼叫函式程式碼:避免 HTTP 請求並減少頁面渲染時間。
在開發體驗方面,您會注意到在建立伺服器檔案時,Nuxt 伺服器會保持執行而無需重建 Vue 應用程式。這是因為 Nuxt 3 在建立 API 和伺服器路由時支援熱模組替換 (HMR)。
此外,透過利用物件關係對映 (ORM) 如drizzle-orm,開發人員可以連線邊緣和無伺服器資料庫,例如D1, Turso, Neon, Planetscale等等。
我建立了Atidone,一個開源演示,展示了一個具有身份驗證和資料庫的全棧應用程式在邊緣執行。原始碼可在 GitHub 上獲得,採用 MIT 許可證:atinux/atidone.
結論
我們對邊緣渲染及其所帶來的可能性感到興奮。Nuxt 團隊迫不及待地想看到您在此基礎上構建什麼!
歡迎加入我們的Discord 伺服器或在 Twitter 上提及@nuxt_js分享您的作品。