WordPress終結者:進擊的JAMStack

blank

WordPress終結者:進擊的JAMStack

最近在研究JAMStack的一些相關內容,發現這的確是個好東西,所以想寫一篇文章把這個概念分享給還不瞭解JAMStack的同學。 這個篇文章主要包含以下的內容:

  • 什麼是JAMStack
  • JAMStack有什麼優勢
  • JAMStack適合什麼應用
  • 我的個人思考

什麼是JAMStack

概念

JAM Stack中的JAM其實是三個詞的縮寫,它們分別是JavaScript, APIs以及Markdown。 而Stack用中文的說法就是技術棧(Tech Stack),也就是我們在構建應用的時候具體使用到的技術的集合。 舉個例子,國外現在比較火的一個Stack叫做Mean Stack,它表示使用MongoDB + Express.js + AngularJS + Node.js這些技術來構建一個Web應用。 因此用最通俗易懂的話來描述JAMStack就是:使用JavaScript,APIs和Markdown三種技術來建置Web應用。 所以JAMStack是一種問題解決方案,而不是一個具體的實現。

接著我們再具體看一下JAVAScript,APIs和Markdown這三種技術在JAMStack的世界中是起到什麼作用的。

JavaScript

在JAMStack的概念中,JavaScript指的是在用戶端(client)實現動態網頁效果的JAVAScript,它既可以是React和Vue這種Web框架,也可以是原生的JavaScript。 它主要負責網頁動態的內容

APIs

這裡的API和我們平時開發調用的API是一樣的。 JAMStack的Web應用會通過JAVAScript給後端API發送AJAX請求或者GraphQL query,後端API會以某種格式(一般是JSON)返回數據給前端來實現一些使用者交互。

Markdown

Mardown是一種輕量級的標記語言。 在JAMStack的世界中,Markdown類型的檔通常是用來作為生成靜態HTML文件的數據源。 有用過hexo寫部落格的同學對這個概念肯定不會陌生,因為hexo的原理就是將我們編寫的Markdown檔根據我們指定的主題或者範本生成一些靜態的HTML然後託管在github pages或者其它類似的靜態網站伺服器來供別人訪問的。

除了Markdown檔之外,JAMStack的靜態數據源還可以是其它的東西,例如我們後面說到的Gatsby(JAMStack的一種實現)就允許通過外掛程式的方式使用SQL直接讀取資料庫的內容來生成靜態頁面。

瞭解了這三個概念的具體內容后,我們再通過一個Gatsby的小demo來體會一下JAMStack的應用是如何工作的。

Gatsby Demo

由於文章篇幅的限制,我將不在這裡為大家講述Gatsby的具體用法,不過我後面會寫一系列文章來教大家如何用Gatsby來免費構建一個比較大的內容網站(CMS),大家可以留意一下。

簡單來說,Gatsby是一個可以讓開發者使用ReactGraphQL等現代技術快速開發網站的靜態網站生成器(static-site generator)。 它是在網站建構(build)階段的工具。 為了給大家一個直觀點的認識,我使用Gatsby搭建了一個簡單的個人部落格網站,網站的原始程式碼可以在我的github倉庫找到。

部落格網站包含以下的功能: 部落格列表頁面:展示我發表的所有部落格。 (靜態內容) 部落格詳情頁面:展示每一篇部落格的具體內容。 (靜態內容) * 部落格評論列表:遊客評論部落格以及展示遊客對這篇部落格的評論清單。 (動態內容)

細心的你一定注意到了我在上面每個功能點的右邊標出了這個功能是靜態的還是動態的。 所謂靜態的內容就是那些不會經常發生變化的內容,這些內容在一段時間內不同使用者訪問的時候都會得到同樣的結果。 而動態的內容就是那些頻繁發生變化的內容,例如遊客對我的部落格的評論。 那麼我為什麼要區分開這兩種類型的內容呢? 要回答這個問題我們可以先看看如果使用服務端渲染(SSR)的方案這個部落格應用是如何運行的。 首先遊客會向SSR伺服器發送一個查看某個部落格的請求,SSR伺服器收到請求後向後端服務請求這個部落格的內容然後渲染出一個HTML頁面然後返回給使用者。 這時候如果其他使用者也向SSR伺服器請求了同樣的資源,SSR伺服器還是會做同樣的工作,請求資源 + 渲染頁面。 這個時候其實SSR伺服器消耗了很多IO和CPU資源來做這些重複性的渲染,而且隨著你的部落格訪問量的增大這些無用的資源消耗也會越來越多,在不升級服務端資源的前提下用戶體驗也會隨之變差。 到這裡你可能會問,既然服務端渲染這麼浪費資源,我們不進行SSR,直接將webpack打包生成的檔放在一個靜態伺服器然後頁面都是在瀏覽器渲染不就行了嗎? 從實現部落格功能的層面上來說這是沒有問題的,可是這對搜尋引擎優化(SEO)很不友好,百度收錄不了你的部落格,你的網站火不起來啊!

為了避免重複性的無用渲染而且能對SEO友好,Gatsby採取了區分網站靜態內容和動態內容的技術方案。 對於那些不經常變動的而且希望被搜尋引擎收錄的靜態內容,Gatsby會在Webpack打包階段就生成,這樣就不需要在使用者訪問該頁面的時候才浪費資源來渲染頁面了,而且這些靜態檔還可以通過CDN來優化用戶體驗。 而對於那些數據經常發生變化的且不需要被搜尋引擎收錄的內容,它們會等到瀏覽器實際渲染對應元件的時候才通過APIs動態獲取數據渲染出來。

我們接著來看一下部落格網站的代碼目錄結構:

blank

上面代碼中,server資料夾存放的是一個簡單的管理用戶評論的express應用,src資料夾才是Gatsby操作的前端資源,它包括以下內容: blogs:這個資料夾是用來存放部落格內容的,每一個Markdown檔都會生成一個靜態的HTML檔。 components: 存放React元件用的。 images:存放部落格的一些圖片資源。 pages: 網站的路由資料夾,這個資料夾下的每一個檔都會被生成一個對應的HTML靜態檔,當請求該路由時會直接返回該靜態檔。 例如現在pages底下有兩個路由,404的路由對應著的是沒找到資源的頁面,而index路由則是部落格的主頁面。 * templates: 網站的樣本資料夾,該資料夾底下只有一個叫做blog-post.js的範本檔,在Gatsby構建網站的時候blogs資料夾底下的每一個Markdown檔都會通過這個範本檔生成一個對應的HTML檔,這樣當使用者訪問伺服器的時候部落格的HTML檔就會被直接返回而無需進行服務端渲染了。

接著我們可以看一下Gatsby打包會生成哪些檔:

blank

由上圖可以看出,Gatsby會為每一個pages資料夾底下的檔生成一個對應的html檔,以及為每一個blogs資料夾底下的部落格生成一個靜態的HTML文件,同時還有一些在用戶端執行的JS檔。 生成的檔可以直接使用靜態網站伺服器來為使用者提供服務,同時你還可以把它們放在CDN中來讓使用者存取起來更快。

最後讓我們來看一下這個部落格網站的運行效果吧:

blank

上圖中我點擊了"如何馬上實現財富自由"這個部落格,進入到部落格詳情頁時瀏覽器沒有重新向服務端請求部落格詳情的HTML檔,而是直接在瀏覽器完成渲染,用戶體驗非常之流暢。 這其實是Gatsby應用的一個很大的亮點,那就是:Gatsby打包的應用在瀏覽器首次請求獲得提前生成的靜態HTML檔後,會演變成一個React SPA應用,接下來的使用者交互就和一般的SPA應用沒有任何差別了,換句話來說,Gatsby既保留了SSR方案SEO友好的優點又保留了SPA應用的流暢使用者體驗,可謂是各取所長,揚長補短了!

其他例子

其實JAMStack的應用現在已經有很多了,只不過我們平時沒有留意到而已。 舉個例子,React開發者十分熟悉的React官網reactjs.org就是用Gatsby構建。 那麼除了這些比較簡單的文檔性和部落格網站,JAMStack可以用來構建複雜的商業應用嗎? 答案是肯定的,除了一些簡單的CMS平臺,JAMStack還可以用來搭建諸如braun這類電商平臺,你可能想不到的是著名的程式師學習網站freeCodeCamp也是使用JAMStack技術棧來搭建的,大家可以去網上(Google)查一下關於freeCodeCamp架構設計的視頻或文章,看完之後我相信你會對JAMStack有更深入的理解的。

JAMStack的優勢

在上面的介紹中我已經大概說了一些JAMStack的優勢了,其中包括SEO友好還有流暢的用戶體驗,那麼除了這些,JAMStack還有沒有其它吸引人的地方呢?

高性能

為什麼JAMStack是高性能的呢? 這是因為JAMStack的應用將網站的靜態部分和動態部分區分開來了,那些不會頻繁發生變化的內容會被提前生成,從而無需使用額外的計算資源來進行服務端渲染。 這樣使用者首次訪問某個頁面的時候速度會變得很快,而且這些靜態的資源還可以被放在CDN來進一步提升用戶體驗。 將動態內容和靜態內容區分開來還有另外一個好處,就是我們後端介面的職責更加明確了,API介面的數量會變得更少,性能也會變得更好。

高性價比以及高可擴充性

由於我們前端的內容都是一些靜態的文件沒有服務端渲染的要求,而靜態資源伺服器對性能的要求並不高,所以我們在購買伺服器方面不需要很大的成本,我們甚至還可以使用一些諸如netlifyGatsby Cloud等免費資源來託管我們的檔。 對於後端來說由於我們已經將前後端徹底分離了,所以後端可以使用一些廉價的Baas或者Serverless服務,例如可以使用Auth0作為我們的使用者鑒權服務,使用Firebase作為我們的介面服務等等。 使用這些Baas和Serverless服務有一個好處就是它們很便宜,而且它們是按照介面使用量來收費的,你的使用者量決定了你的支出,如果你的使用者很少,你甚至不需要花一分錢。

除了極高的性價比,JAMStack還有很好的擴充性。 舉個例子,假如你現在的部落格網站因為某一篇部落格突然火了,訪問使用者激增。 如果你的前端靜態檔使用的是CDN網络的話,你的網站很容易就可以擴展了,一切都是自動的,無需你做任何東西,而後端如果你使用了Serverless和Baas的解決方案的話,一切也是自動的,使用者不會感覺到有使用體驗的差別,而你只需要給使用到的服務平臺多一點點費用而已。

更好的開發者體驗

拿我們前面提到的Gatsby來舉例,它就允許我們使用一些現代的前端技術來進行開發,例如React,Styled-components和GraphQL等,這些都是我們前端開發者十分熟悉的技術了,沒有很大的學習成本所以開發者體驗會很好。 除此之外,由於Gatsby使用了React,所以它間接上接入了React的生態系統,這樣開發者在開發Gatsby應用時就可以使用React生態的各種最佳實踐和庫實現了,這無疑可以大大提高我們的開發效率。

更高的安全性

由於JAMStack是一種前後端分離的技術,沒有了後端渲染所以可以降低被攻擊的風險。 舉個例子採用Gatsby生成的CMS平臺就比傳統的WordPress平臺安全很多:)。

JAMStack適合什麼應用

既然JAMStack有那麼多好處,我們是不是一把梭在所有的專案中都使用JAMStack呢? 答案是否定的,由於JAMStack需要我們將網站的靜態部分和動態部分區分開來,靜態部分的內容會在構建的時候就生成而動態的內容會在瀏覽器進行渲染,這個特點就註定了它不適合於構建以下類型的應用:

  • 掘金,知乎這種主要由第三方用戶創建內容的應用。 由於這些應用的內容都是由平臺使用者創建的,而且用戶可以不斷地修改和刪除已經創建的內容,如果使用JAMStack的話網站的內容就需要被頻繁構建,這顯然是不合理的。
  • 微博,推特這種社交應用。 這類應用的內容除了頻繁更新之外,還有就是動態內容多於靜態內容,例如使用者的主頁只會展示他關注的人發表的動態,所以也不適合使用JAMStack。
  • 一些不需要SEO的應用。 JAMStack一個很大的優點就是對SEO友好,如果你的應用沒有被搜尋引擎收錄的需求的話,就沒必要使用JAMStack了。
  • 內容很多的應用。 由於JAMStack需要我們每次都構建出所有的靜態資源,所以對於那些靜態內容很多的應用(例如頁面數超過50k)的話,每次構建應用都需要大量的時間,因此這種類型的網站也不適合用JAMStack。

相反JAMStack十分適合建構以下類型的應用:

  • 項目文件之類的網站,例如React的官網等。
  • 企業或者組織的官方網站。
  • 個人管理的部落格網站。
  • 中小型規模的CMS平臺。
  • 中小型的電商平臺。
  • 既有需要被SEO的靜態內容又有動態的不需要SEO的內容的混合應用。 例如一些To B的平臺,裡面既有使用者的工作台又有一些操作文檔相關的靜態內容。

當然了我在這裡列出來的無論是適用還是不適用JAMStack的應用其實都是一些很籠統的分類,我們在實際開發時還得具體問題具體分析,根據實際情況來評估我們的應用是不是適合使用JAMStack來開發。

我的個人思考

在最後我想說一下我自己對JAMStack的一些思考。

首先我個人十分看好這個技術棧,也會在日後的開發中使用這個技術棧。 因為它幫我解決了網站SEO的問題。 在不瞭解JAMStack之前,如果我想我的網站被搜尋引擎收錄要麼就是刀耕火種地硬寫HTML和原生JS,這種方案明顯開發效率十分低下。 還有一種方案就是我使用React等現代開發技術,這樣我就得學習next.js等SSR技術來實現SEO,這個方案有一個問題就是學習next.js有一定的學習成本,而且在項目上線后我得維護一個後端服務來進行服務端渲染,所以會有一定的運維成本。 可是使用了JAMStack或者說是Gatsby后這些問題就迎刃而解了,因為我可以繼續使用我熟悉的React技術棧來快速開發Web應用,還無需考慮服務端渲染的問題就可以達到SEO的效果,這不是美滋滋?

其次我覺得JAMStack這個技術棧十分有利於我們實踐一些自己想到的不確定能不能成功的點子(創業想法)。 上面在介紹JAMStack優勢的時候,我提到了一點就是使用JAMStack其實你可以免費部署你的應用,因為你可以將前端的靜態代碼放在一些免費的靜態資源託管伺服器,然後後端使用一些免費的Baas API服務,當然了這隻適合於我們平臺使用者量不大的情景,當使用者量大的時候我們還是得付費的。 可是我們網站剛起步的時候使用者量不都是不大的嗎? 如果我們一大早就買好伺服器資源和功能變數名稱,後面卻發現這個想法根本行不通的話,這些錢就算是賠進去了。 相反,使用免費服務的話,即使我們做的東西黃了,我們也不會有什麼損失。

總的來說我對JAMStack這個技術棧是很有信心的,特別是在CMS內容管理平臺這方面我相信它一定會逐漸火起來,而且有可能可以取代WordPress的地位。

個人技術動態

文章首發於我的個人部落格

歡迎關注公眾號進擊的大蔥一起學習成長

weixin.qq.com/r/Xi4oMMn (二維碼自動識別)

What do you think?

Written by marketer

blank

如何使用 Angular Static Site Generator: Scully.io

blank

2020年前端三大頂級技術趨勢是什麼?