Web 應用架構的下一個轉變


Web 技術大概 25 年前開始萌芽,HTTP、HTML、CSS 和 JS 都是在九十年代中期首次被標準化的。直到如今,Web 演變成一個無處不在的應用平臺。隨著 Web 的發展,Web 應用程序的開發架構也在不斷發展。現在有許多用于構建 Web 應用程序的核心架構,目前最流行的是單頁應用 (SPA),但我們正在逐漸過渡到一種新的改進架構來構建 Web 應用程序。

下面是一些主要的架構模式:

  • 多頁應用 (MPA)

  • 漸進增強的多頁應用(PEMPA)

  • 單頁應用 (SPA)

  • 漸進增強的單頁應用 (PESPA)

每種架構都有它的優點和痛點,但是往往架構的痛點會成為一個足以促使人們轉向下一個架構的核心動力,在技術選型時,我們需要綜合考慮。

無論我們怎么構建我們的應用程序,總繞不過需要在服務器上運行代碼。其實這些架構的最大區別就是代碼所在的位置。下面我們就依次來看一下,并觀察代碼的位置是如何隨時間演進的。在分析每種架構時,我們會從以下幾個角度考慮:

  • 持久化(Persistence) - 從數據庫中保存和讀取數據

  • 路由(Routing) - 根據 URL 切換模塊

  • 數據獲取(Data fetching) - 從持久化存儲中檢索數據

  • 數據變更(Data mutation)- 持久化中的數據變化

  • 渲染邏輯(Rendering logic) - 向用戶顯示數據

  • UI 反饋(UI Feedback) - 響應用戶交互

注意:在后面的架構圖中我們都會使用英文

當然,Web 應用程序的組成部分遠不止這些,但這些部分是變化最多的部分,也是我們作為 Web 開發者花費大量時間的地方。根據不同的項目規模和團隊結構,我們可能會處理所有這些類別的代碼,也可能只處理其中的一部分。

多頁應用 (MPA)

在早期,瀏覽器的功能比較簡單,這是當時在 Web 上運行的唯一架構。

cda9db0a68b0cb6dbb3832e8256c88cf.jpeg
MPA

我們編寫的所有代碼都存在于服務器上,只有客戶端上的 UI反饋 代碼由用戶的瀏覽器處理。

MPA 架構

文檔請求

14bc9937a27a0f9294a3b6deffcf6c41.png
MPA 文檔請求

當用戶在地址欄中輸入 URL 時,瀏覽器會向我們的服務器發送請求。我們的路由邏輯將調用一個函數來獲取數據,該函數會與數據庫通信來檢索數據。然后,渲染邏輯會使用此數據來生成將作為響應發送給客戶端的 HTML。一般來講,瀏覽器都會向用戶提供一些處理中狀態的反饋(比如 favicon 位置的 loading)。

變更請求

9a1fa61cc128d3484b6f101438f40107.jpeg
MPA 變更請求

當用戶提交表單時,瀏覽器會將表單內容序列化為發送到我們服務器的請求,我們的路由邏輯會調用一個函數來更新數據庫。然后它就會通知瀏覽器進行重定向,瀏覽器會觸發一個新的 GET 請求來獲取新的 UI(然后就和上一步用戶輸入 URL 的結果一樣了)。

注意:成功的變更會發送一個重定向的響應,而不僅僅是發送一個新的 HTML,這一點很重要。瀏覽器的歷史堆棧中會有一個 POST 請求,點擊后退按鈕會再次觸發這個 POST 請求(想知道為什么應用程序有時會顯示:“不要點擊后退按鈕!!” 是的,就是這個原因。)。

MPA 的優缺點

MPA 的心智模型很簡單,但當時我們對它并不看好。雖然在請求中主要由 Cookie 處理一些狀態和復雜的流程,但在大多數情況下,一切都發生在請求/響應周期的時間內。

缺點:讓諸如焦點管理之類的操作變得苦難,具有動畫效果的頁面切換幾乎不太可能,用戶體驗很差。

值得注意的是,隨著即將推出的 page transitions API ?,Web 平臺不斷改進,給 MPA 架構帶來了更多可能性。

https://developer.chrome.com/blog/shared-element-transitions-for-spas/

漸進增強的多頁應用 (PEMPA)

漸進式增強的理念是:我們的 Web 應用程序應該是功能性的,對所有 Web 瀏覽器都應該是可訪問的,然后利用瀏覽器的任何額外功能來增強體驗。該術語由 Nick FinckSteve Champeon2003 年創造。

漸進增強是我們的 Web 應用程序應該是功能性的并且所有 Web 瀏覽器都可以訪問的想法,然后利用瀏覽器具有的任何額外功能來增強體驗。該術語由 Nick Finck 和 Steve Champeon 于 2003 年創造。

XMLHttpRequest 最初由 MicrosoftOutlook Web Access 團隊于 1998 年開發,但直到 2016 年才標準化(你相信嗎!?)。當然,這從未阻止過瀏覽器供應商和 Web 開發者。AJAX 作為一個術語在 2005 年流行起來,很多人開始在瀏覽器中發出 HTTP 請求。

業務建立在這樣一個理念上,即我們不必回到服務器去獲取更多的數據來更新適當的 UI。這樣,我們就可以構建逐步增強的多頁面應用了:

2a61d13677397d63dea93a85bec328f6.jpeg
PEMPA

“哇!“ 你可能會想, “等一下… 這些代碼是從哪里來的?” 因此,現在我們不僅要負責來自瀏覽器的UI反饋,我們還需要向客戶端提供路由、數據獲取、數據變更和渲染邏輯,而不僅僅是在服務器上已有的這些邏輯。“到底發生了什么事?”

好吧,是這樣的。漸進增強背后的理念是,我們的基線應該是一個功能性的應用程序。特別是在 21 世紀初,我們不能保證用戶使用的瀏覽器能夠運行像 AJAX 這樣花哨的新東西,或者他們在與應用程序交互之前能夠在足夠快的網絡上下載我們的 JavaScript 。所以我們需要保持現有的 MPA 架構,只使用 JavaScript 來增強體驗。

也就是說,根據我們所討論的增強級別,我們可能確實需要編寫幾乎所有類別的代碼,數據持久化除外(除非我們想支持離線模式)。

另外,我們還必須向后端添加更多代碼,來支持客戶端發出的 AJAX 請求。所以在兩端都需要有更多的開發者。

這是 jQuery、MooTools 等的時代。

PEMPA 架構

文檔請求

e0a9a6230480c9b8e79e1264a86cd7d5.jpeg
PEMPA 文檔請求

當用戶第一次請求 HTML 文檔時,發生的事情和 MPA 示例中的一樣。但是,PEMPA 還將通過包含用于增強功能的 <script> 標簽來加載客戶端 JavaScript

客戶端導航

5bab9a219fbeecc65cac986bc81e5320.png
PEMPA 客戶端導航

當用戶在我們的應用程序中單擊帶有 hrefanchor 元素時,我們的客戶端數據獲取代碼會阻止默認的整頁刷新行為并使用 JavaScript 更新 URL。然后客戶端路由邏輯會確定需要對 UI 進行哪些更新并手動執行這些更新,包括在數據獲取庫向服務端發出網絡請求時顯示任何 Loading 狀態(UI 反饋)。服務器路由邏輯會調用數據獲取代碼從數據庫中檢索數據并將其作為響應(XMLJSON)發送,然后客戶端使用其渲染邏輯執行最終的 UI 更新。

e86a77b5f4a7d9f55a0fc1e0f307c00f.jpeg
PEMPA 變更請求

當用戶提交表單時,我們的客戶端數據變更邏輯會阻止默認的整頁刷新和發布行為,使用 JavaScript 序列化表單并將數據發送到服務端。然后,服務器路由邏輯調用數據變更函數,與數據庫交互以執行變更,并將更新的數據響應給客戶端。客戶端渲染邏輯將使用更新后的數據來更新 UI;在某些情況下,客戶端路由邏輯會將用戶發送到另一個地方,這會觸發與客戶端導航流程類似的流程。

PEMPA 的優缺點

通過引入客戶端代碼并將 UI 反饋的責任推給我們自己,我們確實解決了 MPA 的問題。我們有更多的控制權,可以給用戶一種更像自定義應用程序的感覺。

但同時為了給用戶提供他們想要的最佳體驗,我們必須負責路由、數據獲取、變更和渲染邏輯。這樣做有幾個問題:

  • 阻止瀏覽器默認行為 - 在路由和表單提交方面,我們做得不如瀏覽器好。在此之前,保持頁面上的數據是最新的從來都不是一個需要考慮的問題,但現在這在我們的客戶端代碼中占了一半以上。此外,競爭條件、表單重新提交和錯誤處理都是隱藏 bug 的好地方;

  • 自定義代碼 - 有更多的代碼需要管理,而我們以前不必編寫這些代碼。我知道相關性并不意味著因果關系,但我注意到,一般來說,我們的代碼越多,我們的錯誤就越多🤷?♂?;

  • 代碼重復 - 在渲染邏輯方面存在大量的代碼重復。客戶端代碼需要以與后端代碼在變更或客戶端轉換后渲染所有可能狀態相同的方式更新 UI。后端擁有的 UI 必須在前端也可用。而且大多數情況下它們使用的是完全不同的語言,這使得代碼復用困難。進行客戶端交互,然后確保客戶端代碼更新的 UI 與整個頁面刷新時所發生的情況相同,這是非常困難的;

  • 代碼組織 - 對于 PEMPA,這是非常困難的。由于沒有集中存儲數據或渲染 UI 的地方,人們幾乎可以在任何地方手動更新 DOM,而且很難遵循代碼規范,這會減慢開發速度。

就個人而言,這大約是我剛進入 Web 開發世界的時候。回想起這段時光,我心中充滿了渴望的懷舊和顫抖的恐懼🍝。

單頁應用 (SPA)

沒過多久,我們意識到如果我們只是從后端刪除 UI 代碼,就可以消除重復的問題。這就是我們所做的:

f670a3bafd71c8f68af8b0075f36c23b.jpeg
SPA

你會注意到這個架構圖幾乎與 PEMPA 相同。唯一的區別是渲染的邏輯消失了,一些路由代碼也消失了,因為我們不再需要 UI 路由,只剩下了 API 路由。這是 Backbone、Knockout、Angular、Ember、React、Vue、Svelte 等的時代。

SPA 架構

文檔請求

e57533b305f77ddd2c400f8b82dbb577.jpeg
SPA 文檔請求

由于后端不再具有渲染邏輯,所有文檔請求(用戶輸入 URL 時發出的第一個請求)都由靜態文件服務器(通常是 CDN)提供服務。在 SPA 的早期,HTML 文檔幾乎總是一個有效的空 HTML 文件,其中包含用于“掛載”應用程序的 <div id="root"></div> 。然而如今,一些框架允許我們使用稱為“靜態站點生成”(SSG)的技術在構建時預渲染盡可能多的頁面。

客戶端導航

e27ef0729af3a5746a094f60ce77308f.png
SPA 客戶端導航

數據變更

ba8c7a256bcb7ba863a6787912cfdabe.jpeg
SPA 數據變更

這個架構中的其他行為與 PEMPA 相同,只是現在我們主要使用 fetch 代替 XMLHttpRequest

SPA 的優缺點

有趣的是,在上面的架構行為中,與 PEMPA 的唯一區別是文檔請求的體驗更差了! 那么我們為什么還要這么做呢?

到目前為止,最大的優點就是開發者體驗。這是從 PEMPASPA 過渡的原始驅動力,沒有代碼重復是一個巨大的好處。我們通過各種方法證明了這一改變的合理性(DX 畢竟是 UX 的輸入)。不幸的是,改進 DX 是 SPA 真正為我們所做的一切。

我個人相信 SPA 架構有助于提高感知性能,因為 CDNHTML 文檔的響應速度比服務器生成 HTML 文檔的速度要快,但在現實世界的場景中,這似乎從來沒有什么區別(要歸功于現代基礎設施)。可悲的現實是,SPA 仍然存在一些與 PEMPA 相同的所有其他問題,盡管有了更現代的工具,使事情更容易處理。

更糟糕的是,SPA 還帶來了幾個新問題:

  • 包大小 — 有點爆炸了。關于 JavaScript 對網頁性能的影響,請參閱 web Almanac 這篇詳盡的文章。

  • 瀑布請求 — 因為所有用于獲取數據的代碼現在都在 JavaScript 包中,我們必須等待它被下載后才能獲取數據。與此同時,還需要利用這些包的代碼拆分和懶加載,現在我們有了這樣的關鍵依賴情況: document→ app.js→ page.js→ component.js→ data.json→ image.png。這最終會導致更糟糕的用戶體驗。對于靜態內容,我們可以避免很多這樣的問題,但 SSG 策略的開發者正致力于解決這些問題并樂意向我們出售他們的特定于供應商的解決方案。

  • 運行時性能 — 有這么多的客戶端 JavaScript 要運行,一些低功率設備很難跟上(可以閱讀這篇文章:https://v8.dev/blog/cost-of-javascript-2019 )。過去在我們強大的服務器上運行的程序現在可以在人們手中的微型計算機上運行。我知道我們用更少的能源把人類送上了月球,但這仍然是一個問題。

  • 狀態管理 — 這成了一個大問題。為了證明這一點,我提供了可用于解決此問題的庫的數量😩。以前,MPA 會在 DOM 中渲染我們的狀態,我們只需要引用/修改它。現在我們只得到 JSON,我們不僅要讓后端知道數據何時更新,還要保持該狀態的內存表示是最新的。這具有緩存挑戰的所有標志,毫不夸張地說,是軟件中最困難的問題之一。在典型的 SPA 中,狀態管理占人們工作代碼的 30-50%

為了幫助解決這些問題并減少它們的影響,已經有一些開源庫出現了。自 2010 年代中期以來,SPA 成為了開發網頁應用的標準方法。現在我們已經進入了 21 世紀 20 年代,一些新的想法即將出現。

漸進增強的單頁應用 (PESPA)

MPA 的心智模型非常簡單,并且也具有更強大的功能。經歷過 MPA 階段并在 SPA 中工作的人們確實為我們在過去十年中失去的簡單性感到惋惜。如果你考慮到 SPA 架構背后的動機主要是為了在 PEMPA 上改進開發人員的體驗,那么這一點就特別有趣。如果我們能夠以某種方式將 SPAMPA 合并到一個體系結構中,獲得兩者的優點,那么我們就有希望得到既簡單功能又強大考慮到漸進式增強,即使沒有客戶端 JavaScript,基線也是一個功能性應用程序。考慮到漸進式增強,即使沒有客戶端 JavaScript,基線也是一個功能性應用程序。的東西。這就是漸進式增強單頁應用。

考慮到漸進式增強,即使沒有客戶端 JavaScript,基線也是一個功能性應用程序。因此,如果我們的框架支持并鼓勵漸進式增強作為核心原則,那么我們的應用程序的基礎就是 MPA 的簡單心智模型的堅實基礎。具體來說,就是在請求/響應周期的背景下思考事物的心智模型。這使我們在很大程度上消除了 SPA 的問題。

需要強調的是:漸進式增強的主要好處不是“你的應用程序不需要 JavaScript 就可以工作”(盡管這是一個很好的附帶好處),而是心智模型大大簡化了。

為了做到這一點,PESPA 需要在 Prevent default 時 “模擬瀏覽器”。因此,無論瀏覽器是發出請求還是發出基于 JavaScriptfetch 請求,服務器代碼都以相同的方式工作。因此,當我們仍然擁有這些代碼時,我們可以在剩下的代碼中保留簡單的心智模型。其中一個重要部分是,PESPA 模擬瀏覽器的行為,即在發生變更時重新驗證頁面上的數據,以保持頁面上的數據是最新的。使用 MPA,我們只需要重新加載整個頁面。對于 PESPA,這種重新驗證發生在 fetch 請求中。

記住,我們在 PEMPA 中也有一個重要的問題:代碼重復。PESPA 通過使后端 UI代碼和前端UI代碼完全相同來解決這個問題。通過使用一個既能在服務器渲染又能在客戶端上進行交互/處理更新的UI庫,我們就不存在代碼重復的問題。

73fef1c313ccb05c470f468d9a500dc9.jpeg
PESPA

您會注意到有一些用于數據獲取、變更和渲染的小框。這些是用來增強的。例如,掛起狀態、樂觀UI 等在服務器上無法實現,所以我們將有一些只在客戶端上運行的代碼。但即便如此,在現代UI庫中,實現也非常簡單。

PESPA 架構

文檔請求

11cd9f13f6e5cc50a83132db7ce0dee9.jpeg
PESPA 文檔請求

使用 PESPA 的文檔請求實際上與 PEMPA 相同。應用程序所需的初始 HTML 直接從服務器發送,并且還會加載 JavaScript 以增強用戶交互體驗。

客戶端導航

4695b79d4c109f272e6ac2572d7fc75f.png
PESPA 客戶端導航

當用戶單擊鏈接時,我們會阻止瀏覽器的默認行為。我們的路由將確定新路由所需的數據和 UI,并為下一個路由需要的任何數據觸發數據獲取,并渲染為該路由渲染的 UI

數據變更

b48e5f54730f4b523d2329074d3aa9e6.jpeg
PESPA 數據變更

PESPA 的變更是通過表單提交完成的。沒有更多的 onClick+fetch 廢話(但是命令式變更對于漸進增強是體驗更好的,比如當用戶會話超時時重定向到登錄頁面)。當用戶提交表單時,我們將組織瀏覽器默認行為。我們的變更代碼會序列化表單,并將其作為請求發送到與表單動作相關聯的路由(默認為當前 URL)。后端路由邏輯調用數據庫交互代碼并返回成功的響應(例如一個點贊操作)或重定向(例如創建一個新的GitHub repo)。如果是重定向,路由處理器會為該路由(并行)加載代碼/數據/資產,然后觸發渲染邏輯。如果不是重定向,路由處理器會重新驗證當前UI的數據,并觸發渲染邏輯來更新UI。有趣的是,不管它是內聯變更還是重定向,路由處理器都參與其中,為兩種類型的變更提供了相同的心智模型。

PESPA 的優缺點

PESPA 消除了以前架構中的大量問題。讓我們一一看一下:

MPA 問題:

  • 全頁刷新 - PESPA 阻止瀏覽器默認行為,使用客戶端 JS 來模擬瀏覽器。從我們編寫的代碼的角度來看,這與 MPA 沒有什么不同,但從用戶的角度來看,這是一種改進了很多的體驗。

  • UI 反饋控制 - PESPA 允許我們完全控制網絡請求,因為我們正在阻止瀏覽器默認行為并發出數據獲取請求,因此我們可以以任何對我們的 UI 最有意義的方式向用戶提供反饋。

PEMPA 問題:

  • 阻止瀏覽器默認行為 - PESPA 的一個核心方面是它們的行為方式應該與瀏覽器在路由和表單方面的行為方式大致相同。這就是他們為我們提供 MPA 心智模型的方式。取消來自重新提交表單的請求,正確處理無序響應以避免競爭條件問題,以及顯示錯誤以避免永遠不會消失的微調器。這就是框架真正有用的地方。

  • 自定義代碼 - 通過在客戶端和服務器之間共享代碼并擁有模擬瀏覽器行為的正確抽象,我們最終大大減少了我們必須自己編寫的代碼量。

  • 代碼重復 - PESPA 的部分想法是服務器和客戶端使用完全相同的代碼來渲染邏輯。所以沒有重復可言。不要忘記挑戰:“進行客戶端交互,然后確保客戶端更新的 UI 與我們刷新頁面時獲得的 UI 相同。” 對于 PESPA,它應該始終通過我們開發人員的努力或考慮。

  • 代碼組織 - 由于 PESPA 的瀏覽器模擬提供的心智模型,應用程序狀態管理不是一個考慮因素。并且渲染邏輯在網絡兩端的處理方式相同,因此也不會出現隨意的 DOM 變更。

  • 服務器/客戶端阻隔 - 模擬瀏覽器的 PESPA 意味著前端代碼和后端代碼位于同一位置,從而消除了阻隔并提高了我們的工作效率。

SPA 問題:

  • 包大小 - 使用 PESPA 需要一個服務器,這意味著我們可以將大量代碼移動到后端。所有 UI 需要的是一個可以在服務器和客戶端上運行的小型 UI 庫、一些用于處理 UI 交互和反饋的代碼以及用于組件的代碼。多虧了 URL(基于路由的)代碼拆分,我們終于可以告別擁有數百 KB JS 的網頁了。最重要的是,由于漸進式增強,大多數應用程序應該在 JS 完成加載之前工作。目前 JS 框架正在努力進一步減少客戶端所需的 JS 數量。

  • 瀑布請求 - PESPA 的一個重要部分是它們可以了解給定 URL 的代碼、數據和資產要求,而無需運行任何代碼。這意味著除了代碼拆分之外,PESPA 還可以一次觸發對代碼、數據和資產的請求,而不是依次等待一個。這也意味著 PESPA 可以在用戶觸發導航之前預先獲取這些內容,以便在需要時瀏覽器可以立即返回,從而使整個應用程序的使用體驗變得好。

  • 運行時性能 - PESPA 在這個部分有兩件事情要做:1)他們將大量代碼移動到服務器,因此設備首先要執行的代碼更少;2)由于漸進增強,UI 已經準備好在 JS 完成加載和執行之前使用。

  • 狀態管理 - 因為瀏覽器模擬,我們提供了 MPA 心智模型,所以應用程序狀態管理在 PESPA 上下文中不是問題。這一點的證據是應用程序應該在沒有 JavaScript 的情況下大部分工作。當變更完成時,PESPA 會自動重新驗證頁面上的數據。

有一點很重要,無論有沒有客戶端 JavaScriptPESPA 的工作方式都不完全相同。無論如何,這絕不是漸進增強的目標。只是大多數應用程序應該在沒有 JavaScript 的情況下工作。這不僅僅是因為我們關心無 javascript 的用戶體驗。這是因為通過以漸進增強為目標,我們大大簡化了我們的 UI 代碼。你會驚訝于我們可以在沒有 JS 的情況下走多遠,但是對于某些應用程序來說,沒有客戶端 JavaScript 就沒有必要或不切實際。但是,即使我們的某些 UI 元素確實需要一些 JavaScript 來操作,我們仍然可以獲得 PESPA 的主要好處。

PESPA 的區別:

  • 功能是基線 - 用于增強的 JS 未啟用

  • 懶加載+智能預取(不僅僅是 JS 代碼)

  • 將代碼推送到服務器

  • 無需手動復制 UI 代碼(如在 PEMPA 中)

  • 透明瀏覽器仿真 (#useThePlatform)

至于缺點,我們還在研究中。但以下是一些初步想法:

許多習慣于 SPASSG 的人會感嘆我們現在有服務端代碼運行我們的應用程序。然而,對于任何現實世界的應用程序,我們都無法避免服務端代碼。當然,在某些用例中,我們可以一次構建整個站點并將其粘貼到 CDN 上,但我們為日常工作而開發的大多數應用程序都不屬于這一類。

與此相關的是人們對服務器成本的關注。這個想法是,SSG 允許我們一次性創建應用,然后通過 CDN 以非常低的成本將其提供給幾乎無限數量的用戶。這有兩個缺陷。1) 我們可能會在我們的應用程序中使用 API,因此這些用戶仍然會在訪問時觸發大量我們最昂貴的服務端代碼。2) CDN 支持 HTTP 緩存機制,所以如果我們真的能夠使用 SSG,那么我們絕對可以利用它來提供快速響應并限制渲染服務器處理的工作量。

人們離開 SPA 時遇到的另一個常見問題是,現在我們必須應對在服務器上進行渲染的挑戰。對于習慣于只在客戶端上運行代碼的人來說,這絕對是一種不同的模型,但如果我們使用的工具考慮到了這一點,這就不是什么挑戰了。如果我們沒有這樣做,那么它肯定是一個挑戰,但是有一些合理的變通方法,可以強制某些代碼在我們遷移時只在客戶端運行。

正如我所說,我們仍在發現漸進式增強型單頁應用程序的缺點,但我認為它的好處是值得的,我們目前可以察覺到。

我還應該提到,盡管我們已經在相當長的一段時間內使用現有工具實現了 PESPA 體系結構的功能,但在共享渲染邏輯代碼的同時關注漸進增強還是新的。這篇文章主要感興趣的是演示事實上的標準架構,而不僅僅是平臺的功能。

PESPA 實踐:Remix

PESPA 的領頭羊是 Remix,這是一個專注于 Web 基礎和現代用戶體驗的 Web 框架。Remix 是第一個開箱即用的 Web 框架,它提供了我所描述的 PESPA 提供的一切。在這方面,其他框架也可以效仿 Remix 的做法。我特別注意到 slveltekitSolidStart 在他們的實現中都采用了 PESPA 原則。我想還會有更多的元框架(同樣,元框架支持 PESPA 架構已經有一段時間了,但是 Remix 把這種架構放在了最前沿,其他的也在效仿)。當我們為我們的 PESPA 建立一個 Web 框架時,情況如下:

44175d3ce7fa982c638f0291beb85c14.png

在這種情況下,Remix 充當了跨 Web 的橋梁。如果沒有 Remix,我們必須自己實現它才能擁有完整的 PESPARemix 還通過結合基于約定和基于配置的路由來處理我們的路由。Remix 還將幫助我們逐步增強數據獲取和變更(例如 twitter 上的點贊按鈕)以及用于實現諸如掛起狀態和樂觀 UI 之類的 UI 反饋。

多虧了 Remix 中內置的嵌套路由,我們也獲得了更好的代碼組織( Next.js 也在追求)。雖然 PESPA 架構不需要嵌套路由,但基于路由的代碼拆分是一個重要部分。此外,我們通過嵌套路由獲得了更精細的代碼拆分,因此這是一個重要方面。

Remix 證明我們可以通過 PESPA 架構更快地構建更好的體驗。我們最終會遇到這樣的情況:

505be1386f701fbc79bf8a61a6af7d91.png
完美的 lighthouse 分數

最后

就我個人而言,我非常期待這個轉變。同時獲得更好的 UXDX 是一種堅實的勝利。我認為這是一個重要的決定,我對我們的未來感到興奮。另外我也創建了一個庫,演示了使用 TodoMVC 應用程序在各個時代移動的所有代碼! 你可以在這里找到它:

https://github.com/kentcdodds/the-webs-next-transformation

  • 本文譯自:epicweb.dev/the-webs-next-transition

  • 作者:Kent C. Dodds

  • 往期精彩推薦:2022 Web 年鑒 — JavaScript

如果你有任何想法,歡迎在留言區和我留言,如果這篇文章幫助到了你,歡迎點贊和關注。

07381749391fac10bc71c591230c27d3.gif

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經堅持寫了8年,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助5000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

cfcaeffe8d158953ac21dcbc3641e26f.jpeg

掃碼加我微信 lxchuan12、拉你進源碼共讀

今日話題

目前建有江西|湖南|湖北?籍 前端群,想進群的可以加我微信 lxchuan12?進群。分享、收藏、點贊、在看我的文章就是對我最大的支持~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/274509.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274509.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274509.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

生命在于運動?

我有兩個朋友&#xff0c;一個喜歡運動&#xff0c;經常打球騎單車&#xff0c;一個就喜歡宅在家里&#xff0c;最多大家玩的時候去旁觀。兩人常常爭執&#xff0c;一個說&#xff1a;生命在于運動&#xff0c;你看我多健康&#xff01;一個說&#xff1a;生命在于靜止&#xf…

C++ 學習筆記----類篇

&#xff08;一&#xff09;基本概念&#xff1a; 1、類與對象&#xff1a; 1 //聲明類 2 class Human { 3 4 //... Data members and methods go here 5 6 }; 7 8 //定義對象 9 Human human; 2、通常用class聲明類&#xff0c;struct也可以&#xff0c;只不過在信…

ux和ui_設計社交餐廳策展應用程序— UX / UI案例研究

ux和uiSabor, which translates from “taste” or “flavor” in Spanish, is a concept for an iOS app designed to provide users with honest, reliable and relatable restaurant recommendations from friends and family. It is a social restaurant curation applicat…

你不知道的 script 標簽的 defer 與 async 屬性

我持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 點此掃碼加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外&#xff1a;目前建…

我是怎么調試 Element UI 源碼的

我持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 點此掃碼加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列。另外&#xff1a;目前建…

java對象的理解

1、看生成幾個對象&#xff0c;就看new了幾次&#xff0c; Stu s1new Stu(“張三”); Stu s2s1;-這里也是生成了一個對象&#xff0c;只不過s1和s2指向了同一個對象 2、Stu s1new Stu(“張三”); Stu s2 new Stu(“李四”); s1s2&#xff1b;這里生成了兩個對象&#xff0c;但是…

模板緩沖_模板緩沖以及如何使用它可視化體積相交

模板緩沖介紹 (Introduction) The trendy thing in real-time rendering these days is ray-tracing. However, traditional rasterization hasn’t disappeared, and it won’t in the near future. I recommend this blog post on the subject: A hybrid rendering pipeline …

重磅!哈啰 Quark Design 正式開源,下一代跨技術棧前端組件庫

大家好&#xff0c;我是若川。我持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 點此掃碼加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試…

對lua協程的一點理解

讀《Programming In Lua》協程那一章&#xff0c;比較困惑的還是procuer-consumer那個例子&#xff1a; function consumer(prod)while true dolocal x receive(prod)print(x)end endfunction receive(prod)local status, value coroutine.resume(prod)return value endfunct…

b端 ux 設計思維_借助系統思維從視覺設計過渡到UX

b端 ux 設計思維“How can I switch to UX?” This is a common question from visual designers because there’s a lot of overlap on the surface. But it can also be a difficult transition since UX encompasses much more below the surface.“如何切換到UX&#xff…

三面面試官:運行 npm run xxx 的時候發生了什么?

大家好&#xff0c;我是若川。近期發現好些小伙伴工作有2-3年了&#xff0c;基本不會寫腳手架&#xff0c;或者說沒學過腳手架。對腳手架大致是如何執行的基本不太知道。其實這類學習資料真的挺多的。而且我們基本天天 npm run dev&#xff0c;應該學習內部實現。不知道的小伙伴…

figma下載_Figma的自動版式實用

figma下載Figma’s Auto Layout has been around for a while, but not everyone’s aware of the benefits it brings. It doesn’t replace constraints, they’re still very much needed. The trick is to use the right feature where necessary. I want to show you how …

Qt通過ODBC讀取excel文件

之前替學校考試科用C Builder做過一個小的數據庫工具&#xff0c;處理excel表格用的&#xff0c;現在想轉換到Qt平臺下來&#xff0c;在網上搜了搜有一些利用OBDC讀取xls文件的教程&#xff1a; http://hi.baidu.com/kxw102/item/770c496d5736470ca0cf0f1d http://blog.sina.co…

真 · 三面面試官:運行 npm run xxx 的時候發生了什么?

昨晚沒權限我只放了鏈接&#xff0c;今天聯系開了白名單。昨天推文主要是為了投票&#xff0c;表明 Node.js 的重要性&#xff0c;有人評論是水文。今天重新轉載下。歡迎繼續點此去投票。投票顯示有高達近80% 表示不太會開發腳手架&#xff0c;看來大多數人確實沒有應用場景。可…

ovo svm_反思我在OVO擔任遠程產品設計實習生的時間

ovo svmIn a quiet bedroom accompanied only by the low humming of my laptop fan, I sat before a Google Hangouts meeting, and got to know my colleagues for the first time, unaware of the joy of a ride that was waiting for me at OVO Design.在一個安靜的臥室里&…

native的Socket向Android的LocalSocketServer發送漢字亂碼的問題

native的Socket發送字節流默認是GB2312的&#xff0c;所以在Java方面需要指定GB2312 byte[] buffer new byte[50]; StringBuffer strBuf new StringBuffer(); InputStream input receiver.getInputStream(); while((len input.read(buffer)) ! -1) {String newStr new Str…

最受讀者喜愛的前端書 Top 15【留言送書】

最受讀者喜愛的前端書Top 15JavaScript高級程序設計&#xff08;第4版&#xff09;| 中文版累計銷量32萬冊&#xff0c;JavaScript“紅寶書”全新升級 | 涵蓋ECMAScript 2019&#xff0c;全面深入&#xff0c;入門和進階俱佳 | 結合視頻講解配套編程環境&#xff0c;助你輕松掌…

圖文結合簡單易學的 npm 包的發布流程

大家好&#xff0c;我是若川。我持續組織了近一年的源碼共讀活動&#xff0c;感興趣的可以 點此掃碼加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試…

擬態防御_擬態從未消失。 這就是為什么。

擬態防御Looking back on design languages, what Apple’s WWDC 2020 Keynote means for the future of design languages, and how we move on from here.回顧設計語言&#xff0c;Apple的WWDC 2020主題演講對設計語言的未來意味著什么&#xff0c;以及我們如何從這里繼續前進…

C++二維數組做形參

二位數組作為形參&#xff0c;目前僅知道兩種形式&#xff0c;一種直接采用二維數組&#xff0c;一種是用二維指針。以下是做的一個簡單的實例。 大家幫我看看&#xff0c;在實際應用中兩者有和優缺點。當然&#xff0c;有更好的方式更好了。 以下均應用在字符串數組中 void ar…