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
上運行的唯一架構。

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

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

當用戶提交表單時,瀏覽器會將表單內容序列化為發送到我們服務器的請求,我們的路由邏輯會調用一個函數來更新數據庫。然后它就會通知瀏覽器進行重定向,瀏覽器會觸發一個新的 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 Finck
和 Steve Champeon
于 2003
年創造。
漸進增強是我們的 Web
應用程序應該是功能性的并且所有 Web 瀏覽器都可以訪問的想法,然后利用瀏覽器具有的任何額外功能來增強體驗。該術語由 Nick Finck 和 Steve Champeon 于 2003 年創造。
XMLHttpRequest
最初由 Microsoft
的 Outlook Web Access
團隊于 1998
年開發,但直到 2016
年才標準化(你相信嗎!?)。當然,這從未阻止過瀏覽器供應商和 Web
開發者。AJAX
作為一個術語在 2005
年流行起來,很多人開始在瀏覽器中發出 HTTP
請求。
業務建立在這樣一個理念上,即我們不必回到服務器去獲取更多的數據來更新適當的 UI
。這樣,我們就可以構建逐步增強的多頁面應用了:

“哇!“ 你可能會想, “等一下… 這些代碼是從哪里來的?” 因此,現在我們不僅要負責來自瀏覽器的UI反饋,我們還需要向客戶端提供路由、數據獲取、數據變更和渲染邏輯,而不僅僅是在服務器上已有的這些邏輯。“到底發生了什么事?”
好吧,是這樣的。漸進增強背后的理念是,我們的基線應該是一個功能性的應用程序。特別是在 21
世紀初,我們不能保證用戶使用的瀏覽器能夠運行像 AJAX
這樣花哨的新東西,或者他們在與應用程序交互之前能夠在足夠快的網絡上下載我們的 JavaScript
。所以我們需要保持現有的 MPA
架構,只使用 JavaScript
來增強體驗。
也就是說,根據我們所討論的增強級別,我們可能確實需要編寫幾乎所有類別的代碼,數據持久化除外(除非我們想支持離線模式)。
另外,我們還必須向后端添加更多代碼,來支持客戶端發出的 AJAX
請求。所以在兩端都需要有更多的開發者。
這是 jQuery、MooTools
等的時代。
PEMPA 架構
文檔請求

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

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

當用戶提交表單時,我們的客戶端數據變更邏輯會阻止默認的整頁刷新和發布行為,使用 JavaScript
序列化表單并將數據發送到服務端。然后,服務器路由邏輯調用數據變更函數,與數據庫交互以執行變更,并將更新的數據響應給客戶端。客戶端渲染邏輯將使用更新后的數據來更新 UI;在某些情況下,客戶端路由邏輯會將用戶發送到另一個地方,這會觸發與客戶端導航流程類似的流程。
PEMPA 的優缺點
通過引入客戶端代碼并將 UI 反饋的責任推給我們自己,我們確實解決了 MPA
的問題。我們有更多的控制權,可以給用戶一種更像自定義應用程序的感覺。
但同時為了給用戶提供他們想要的最佳體驗,我們必須負責路由、數據獲取、變更和渲染邏輯。這樣做有幾個問題:
阻止瀏覽器默認行為 - 在路由和表單提交方面,我們做得不如瀏覽器好。在此之前,保持頁面上的數據是最新的從來都不是一個需要考慮的問題,但現在這在我們的客戶端代碼中占了一半以上。此外,競爭條件、表單重新提交和錯誤處理都是隱藏
bug
的好地方;自定義代碼 - 有更多的代碼需要管理,而我們以前不必編寫這些代碼。我知道相關性并不意味著因果關系,但我注意到,一般來說,我們的代碼越多,我們的錯誤就越多🤷?♂?;
代碼重復 - 在渲染邏輯方面存在大量的代碼重復。客戶端代碼需要以與后端代碼在變更或客戶端轉換后渲染所有可能狀態相同的方式更新
UI
。后端擁有的UI
必須在前端也可用。而且大多數情況下它們使用的是完全不同的語言,這使得代碼復用困難。進行客戶端交互,然后確保客戶端代碼更新的UI
與整個頁面刷新時所發生的情況相同,這是非常困難的;代碼組織 - 對于
PEMPA
,這是非常困難的。由于沒有集中存儲數據或渲染 UI 的地方,人們幾乎可以在任何地方手動更新DOM
,而且很難遵循代碼規范,這會減慢開發速度。
就個人而言,這大約是我剛進入 Web
開發世界的時候。回想起這段時光,我心中充滿了渴望的懷舊和顫抖的恐懼🍝。
單頁應用 (SPA)
沒過多久,我們意識到如果我們只是從后端刪除 UI
代碼,就可以消除重復的問題。這就是我們所做的:

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

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

數據變更

這個架構中的其他行為與 PEMPA
相同,只是現在我們主要使用 fetch
代替 XMLHttpRequest
。
SPA 的優缺點
有趣的是,在上面的架構行為中,與 PEMPA
的唯一區別是文檔請求的體驗更差了! 那么我們為什么還要這么做呢?
到目前為止,最大的優點就是開發者體驗。這是從 PEMPA
向 SPA
過渡的原始驅動力,沒有代碼重復是一個巨大的好處。我們通過各種方法證明了這一改變的合理性(DX
畢竟是 UX
的輸入)。不幸的是,改進 DX 是 SPA
真正為我們所做的一切。
我個人相信 SPA
架構有助于提高感知性能,因為 CDN
對 HTML
文檔的響應速度比服務器生成 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
上改進開發人員的體驗,那么這一點就特別有趣。如果我們能夠以某種方式將 SPA
和 MPA
合并到一個體系結構中,獲得兩者的優點,那么我們就有希望得到既簡單功能又強大考慮到漸進式增強,即使沒有客戶端 JavaScript
,基線也是一個功能性應用程序。考慮到漸進式增強,即使沒有客戶端 JavaScript,基線也是一個功能性應用程序。的東西。這就是漸進式增強單頁應用。
考慮到漸進式增強,即使沒有客戶端 JavaScript
,基線也是一個功能性應用程序。因此,如果我們的框架支持并鼓勵漸進式增強作為核心原則,那么我們的應用程序的基礎就是 MPA
的簡單心智模型的堅實基礎。具體來說,就是在請求/響應周期的背景下思考事物的心智模型。這使我們在很大程度上消除了 SPA
的問題。
需要強調的是:漸進式增強的主要好處不是“你的應用程序不需要 JavaScript
就可以工作”(盡管這是一個很好的附帶好處),而是心智模型大大簡化了。
為了做到這一點,PESPA
需要在 Prevent default
時 “模擬瀏覽器”。因此,無論瀏覽器是發出請求還是發出基于 JavaScript
的 fetch
請求,服務器代碼都以相同的方式工作。因此,當我們仍然擁有這些代碼時,我們可以在剩下的代碼中保留簡單的心智模型。其中一個重要部分是,PESPA
模擬瀏覽器的行為,即在發生變更時重新驗證頁面上的數據,以保持頁面上的數據是最新的。使用 MPA
,我們只需要重新加載整個頁面。對于 PESPA
,這種重新驗證發生在 fetch
請求中。
記住,我們在 PEMPA
中也有一個重要的問題:代碼重復。PESPA
通過使后端 UI代碼和前端UI代碼完全相同來解決這個問題。通過使用一個既能在服務器渲染又能在客戶端上進行交互/處理更新的UI庫,我們就不存在代碼重復的問題。

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

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

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

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
會自動重新驗證頁面上的數據。
有一點很重要,無論有沒有客戶端 JavaScript
,PESPA
的工作方式都不完全相同。無論如何,這絕不是漸進增強的目標。只是大多數應用程序應該在沒有 JavaScript
的情況下工作。這不僅僅是因為我們關心無 javascript
的用戶體驗。這是因為通過以漸進增強為目標,我們大大簡化了我們的 UI
代碼。你會驚訝于我們可以在沒有 JS
的情況下走多遠,但是對于某些應用程序來說,沒有客戶端 JavaScript
就沒有必要或不切實際。但是,即使我們的某些 UI
元素確實需要一些 JavaScript
來操作,我們仍然可以獲得 PESPA
的主要好處。
PESPA
的區別:
功能是基線 - 用于增強的
JS
未啟用懶加載+智能預取(不僅僅是
JS
代碼)將代碼推送到服務器
無需手動復制 UI 代碼(如在
PEMPA
中)透明瀏覽器仿真 (#
useThePlatform
)
至于缺點,我們還在研究中。但以下是一些初步想法:
許多習慣于 SPA
和 SSG
的人會感嘆我們現在有服務端代碼運行我們的應用程序。然而,對于任何現實世界的應用程序,我們都無法避免服務端代碼。當然,在某些用例中,我們可以一次構建整個站點并將其粘貼到 CDN
上,但我們為日常工作而開發的大多數應用程序都不屬于這一類。
與此相關的是人們對服務器成本的關注。這個想法是,SSG
允許我們一次性創建應用,然后通過 CDN
以非常低的成本將其提供給幾乎無限數量的用戶。這有兩個缺陷。1) 我們可能會在我們的應用程序中使用 API
,因此這些用戶仍然會在訪問時觸發大量我們最昂貴的服務端代碼。2) CDN
支持 HTTP
緩存機制,所以如果我們真的能夠使用 SSG
,那么我們絕對可以利用它來提供快速響應并限制渲染服務器處理的工作量。
人們離開 SPA
時遇到的另一個常見問題是,現在我們必須應對在服務器上進行渲染的挑戰。對于習慣于只在客戶端上運行代碼的人來說,這絕對是一種不同的模型,但如果我們使用的工具考慮到了這一點,這就不是什么挑戰了。如果我們沒有這樣做,那么它肯定是一個挑戰,但是有一些合理的變通方法,可以強制某些代碼在我們遷移時只在客戶端運行。
正如我所說,我們仍在發現漸進式增強型單頁應用程序的缺點,但我認為它的好處是值得的,我們目前可以察覺到。
我還應該提到,盡管我們已經在相當長的一段時間內使用現有工具實現了 PESPA
體系結構的功能,但在共享渲染邏輯代碼的同時關注漸進增強還是新的。這篇文章主要感興趣的是演示事實上的標準架構,而不僅僅是平臺的功能。
PESPA 實踐:Remix
PESPA
的領頭羊是 Remix
,這是一個專注于 Web
基礎和現代用戶體驗的 Web
框架。Remix
是第一個開箱即用的 Web
框架,它提供了我所描述的 PESPA
提供的一切。在這方面,其他框架也可以效仿 Remix
的做法。我特別注意到 slveltekit
和 SolidStart
在他們的實現中都采用了 PESPA
原則。我想還會有更多的元框架(同樣,元框架支持 PESPA
架構已經有一段時間了,但是 Remix
把這種架構放在了最前沿,其他的也在效仿)。當我們為我們的 PESPA
建立一個 Web
框架時,情況如下:

在這種情況下,Remix
充當了跨 Web
的橋梁。如果沒有 Remix
,我們必須自己實現它才能擁有完整的 PESPA
。Remix
還通過結合基于約定和基于配置的路由來處理我們的路由。Remix
還將幫助我們逐步增強數據獲取和變更(例如 twitter
上的點贊按鈕)以及用于實現諸如掛起狀態和樂觀 UI 之類的 UI
反饋。
多虧了 Remix
中內置的嵌套路由,我們也獲得了更好的代碼組織( Next.js
也在追求)。雖然 PESPA
架構不需要嵌套路由,但基于路由的代碼拆分是一個重要部分。此外,我們通過嵌套路由獲得了更精細的代碼拆分,因此這是一個重要方面。
Remix
證明我們可以通過 PESPA
架構更快地構建更好的體驗。我們最終會遇到這樣的情況:

最后
就我個人而言,我非常期待這個轉變。同時獲得更好的 UX
和 DX
是一種堅實的勝利。我認為這是一個重要的決定,我對我們的未來感到興奮。另外我也創建了一個庫,演示了使用 TodoMVC
應用程序在各個時代移動的所有代碼! 你可以在這里找到它:
https://github.com/kentcdodds/the-webs-next-transformation
本文譯自:epicweb.dev/the-webs-next-transition
作者:Kent C. Dodds
往期精彩推薦:2022 Web 年鑒 — JavaScript
如果你有任何想法,歡迎在留言區和我留言,如果這篇文章幫助到了你,歡迎點贊和關注。
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經堅持寫了8年,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助5000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
掃碼加我微信 lxchuan12、拉你進源碼共讀群
今日話題
目前建有江西|湖南|湖北?籍 前端群,想進群的可以加我微信 lxchuan12?進群。分享、收藏、點贊、在看我的文章就是對我最大的支持~