1. 程式人生 > >靜態網站生成器將是下一個大事件

靜態網站生成器將是下一個大事件

StaticGen,我們有一個關於靜態站點生成器的開源目錄,在這一年多我們追蹤了超過一百個生成器。在那段時間裡,我們見證著這些專案的數量和流行度在 Github 上高漲得不可思議——從只有 50 個到超過 100 個,直到有關靜態站點的庫獲得了超過 10 萬的 Stars。

像 Nest 和 MailChimp 這樣專注於設計的知名公司,已經將靜態站點生成器用於其主網站的開發。 Vox Media 圍繞 Middleman 建立了一整套系統Carrot,一個大型的紐約中介、 Vice 帝國的一部分,用它自己的開源生成器 Roots 給世界的一些大品牌建站。一些 Google 的產品,像“A Year In Search

”和 “Web Fundamentals”也是靜態的。

StaticGen’s Graph of growth over the last year.(看大圖)

靜態站點不是新事物,可以追溯到 Web 伊始之時。為什麼會有爆發性的關注度?發生了什麼?為什麼是現在?

靜態是什麼時候產生的

第一個網站—— Tim Berners-Lee 的全球資訊網處女頁——就是靜態的。那時的站點僅僅由一個資料夾下的一組 HTML 文件組成,而且HTML檔案只包含18種標籤。瀏覽器只是簡單的文字導航器,它從伺服器端抓 HTML,終端使用者可以由超連結導航。Web基本上是靜態的。

隨著瀏覽器和 HTML 的演進,我們逐漸看到了純靜態站點的限制。

起初,網站只是無樣式純文件,但很快便被精心設計,帶有圖形頭和複雜導航。從那時開始,管理自己網頁的每個文件失去意義,模版語言進入大眾視野。

顯然,使用 HTML 作結構、CSS 作設計,無法抽象內容(像故事板、產品、零掛件等等)與設計分離的理念。

幾乎同一時間,基於 SQL 的關係型資料庫開始成為主流。對於許多線上公司而言,資料庫成為了他們儲存內容的聖地,由警惕的長鬍子資料庫管理員看守著。

像 Dreamweaver 和 FrontPage 一類的桌面應用也有建立內容驅動型網站的解決方案——使用所見即所得的編輯器——頁面可以被分離成可重用元件,例如導航、頭部、尾部。這些內容很大程度上也能被存到資料庫中。雖然它們有很大的缺陷,從某種程度上講,這就是最原始的靜態站點生成器

:從模版、部件、媒體庫甚至是 SQL 資料庫獲得資源建立站點,通過 FTP 釋出靜態檔案。直到 2004 年,我才得以在大型內容網站工作一段時間,成千上萬的頁面在不同的編輯組傳播,全都通過 Dreamweaver 管理。

即使 Dreamweaver 在某種程度上能夠與資料庫整合,它卻不具備內容模型,沒有內容與形式分離的概念,無法將內容與形式用合適的工具獨立編輯。

最主流的解決方案是 LAMP 棧和像 WordPress 、 Drupal 和 joomla 這樣的 CMS ,這些在推動 Web 2.0 演進有著不可或缺的作用。 2.0 時代許多網站的關鍵功能是使用者生成內容。使用者從點選超連結變成了訂購商品、參與社群,以及建立內容。

動態問題

我 15 年前第一次建立動態站點時,我遵循著 MySQL 文件的 LAMP 棧手冊。這樣建立的站點,每次有訪客時都要執行一次這種流程,意識到這些時我簡直瘋了!

Web 伺服器儘快把我的程式碼載入到 PHP 直譯器裡,然後開啟資料庫連線池,來回傳送查詢語句,使用模版中的資料並將文字字串拼接到 HTML 文件中,之後呈現給訪客。太神奇了!

不得不承認,幾年之後當我再訪問這個網站時就沒那麼有趣了。整個網頁都被黑客的訊息替換了,指出了配置中的安全漏洞。他很寬巨集大量,只是在網站上塗塗畫畫,而不是把它當作傳播惡意軟體的媒介。

動態網站的結構推動 Web 前行,但也打開了蠕蟲的蜜罐。保守估計,當下超過 70% 的 WordPress 源很容易受到已知的漏洞利用(同時 WordPress 驅動著超過 23% 的 Web 站點)僅僅幾個月前,一千兩百萬的 Drupal 站點需要緊急補丁,任何在漏洞通知7小時內沒打補丁的站點都該考慮是不是被注入了惡意軟體…不到一週,我從社交媒體到站點的超連結就成了“資料庫連線錯誤”。規模化動態網站的成本很高,想要保持站點的活力,動態站點所在的代理不得不千般戒備網路攻擊。否則的話就得殊死掙扎讓網站重新上線(往往發生在非工作時間)。

我們為跑在伺服器上每個請求的複雜程式碼付了高額費用——要是不必這麼複雜,就不用再花一分錢了。

動態網站和快取

有時,我們嘗試用快取解決問題。沒有 WP Super Cache 這類外掛的話,那些知名的 WordPress 站點不可能跑起來。大型站點無疑要依賴其上層的代理快取,比如 Varnish 、 Nginx 和 Apache Traffic Server 。

然而快取的錯誤是臭名昭著的,並且即使是相當優化的動態站點通常也會比靜態的解決方案慢幾倍。

Smashing Magazine 顯然是由最關注效能的團隊做的,大體上是深層效能優化過的。所以,為這篇文章我做了一個實驗。我用 HTTrack 抓了這個網站的一級拷貝,然後把靜態版本部署到了 Netlify 上,後者是一個基於內容分發網路(CDN)的靜態主機平臺。我除了用深度 CDN 整合把靜態版本部署到主機上之外,沒做任何優化。

Smashing Magazine 比大部分網站都快,但所有請求是一個數據中心承載的。(檢視大圖)

哪怕和高度優化的動態網站相比,靜態版本平均要快六倍以上。誠然,不是每個靜態主機都有這種差異。但不經過手動配置,這種基於 CDN 快取的動態網站是做不出來的,至少沒有相當變態的快取神器是不行的。

同樣的 HTML,執行在高效能靜態主機上(檢視大圖)

快取,更確切來說是快取失效,在動態網站上很難做好,尤其是需要充分利用 CDN 的分發快取機制。對於一個 WordPress 站點,無法保證同樣的 URL 會返回一致的 HTML,這取決於使用者登入狀態、查詢引數、多次 A/B 測試等等。跟蹤快取失效的準確時間是個困難的任務:任何評論、全域性站點設定、標籤、種類或資料庫裡其他內容的變動都可能影響到列表裡相關文章、索引頁、歸檔、評論計數器等等。

從這個角度來看,靜態網站有天壤之別。他們遵循一個十分簡單的快取規則:對於任何訪客的 URL 都返回相同的 HTML,直到對應的 URL 有了明確的更新。

在開發時遵循這些規則會有些束手束腳,但如果網站按照這些規則建立,那麼在效能、執行時和花銷上將產生巨大變化。

現代靜態網站生成器

近年來,傳統動態架構的替代品逐漸出現。靜態站點生成器不是什麼新玩意。甚至那時 WordPress 最大的競爭對手 Movable Type,如今都有切換靜態網站生成器的選項。

Google Trends 有關”靜態站點生成器”(檢視大圖

那時開始,靜態站點不再因那些限制黯然失色。如今的生成器是飽受前端開發者喜愛的、更現代、更具生命力的釋出引擎。

每週都有更多的靜態站點生成器釋出,跟上發展很難。但總的來說,最流行的靜態站點都有如下特點:

模版

靜態站點生成器的基本思路之一是把網站劃分成佈局和元件以避免重複。有許多的模版引擎可供選擇,它們各有利弊——有些是較無邏輯的、有些將模版和程式碼混用,但都能讓你擺脫重複的頭部、尾部和導航。

MarkDown 支援

MarkDown 的興起很可能是靜態站點生成器變得如此流行的主要原因之一。幾乎沒有人願意所有內容都用 BBCode 或純文字來寫,然而 MarkDown 很容易上手,用 MarkDown 編輯器來寫作、記筆記、發部落格貌似快速流行起來。

所有的主流靜態生成器都支援 Markdown。有的聲稱支援 reStructuredText,或一種可替代的標記格式。大體上講,都允許內容開發者在結構化格式中使用純文字文件。

這種方法將內容與設計分離,並保持檔案的純文字性。作為開發者,我們開始掌握神奇的工具套件來應付純文字。相比於把所有內容作為二進位制 blob 堆砌在資料庫中,這是很大的進步。

元資料

內容往往不會孤立存在。讀者總想找到博文的作者、發文日期、文章種類等等。

Jekyll 推動了靜態網站生成器的演進:現在可以由 MarkDown 模版驅動

當 Github 擁有者 Tom Preston Werner 編寫 Jekyll 作為部落格引擎時,他想到了一個代表元資料(主要用於 MarkDown 文件和模版)切實有趣的解決方案——開頭描述。

開頭描述是少量元資料,主要以 yaml 格式位於文件最前面:

XHTML
1234567 title:Titleofthedocumentcategories:CategoryACategoryB#ActualcontentThisisthedocument

這種標記使包含元資料的單檔案文件註解一目瞭然,也讓那些通常在資料庫裡儲存的不透明格式成為了簡易可讀的文字。

資源管道

如今前端開發幾乎總要涉及一些開發工具和編譯器。我們想要資源最小化打包,CSS 前處理器從小眾走向主流,CoffeeScript 和 ES6 轉譯使編譯器整合進瀏覽器。

大部分現代靜態站點生成器包括一個資源程序,處理資源編譯、轉換、最小化和打包事宜。有一些基於構建工具,例如 Grunt 、 Gulp 和 Broccoli,你可以緊緊圍繞整個生態系統的任務和構建階段。剩下的更專注於精簡其中某個過程,或讓某些工具在不經過複雜配置的條件下運作良好。寫入檔案實時重新整理瀏覽器也成為了許多生成器的標準。

彙總

通常靜態站點生成器建站時都有命令列 UI,或者把網站掛在一個本地伺服器上用於開發。

拿Jekyll來說,你用 jekyll build 命令時本地資料夾會生成一個 Jekyll 專案原始檔,在 _site 子資料夾輸出一個靜態網站。

下面是原始檔夾的樣子:

XHTML
1234567891011121314 _posts/2015-03-01-first-post.md2015-03-11-amazing-post.md_layouts/default.html_includes/main-nav.htmlindex.htmlabout.mdjs/app.coffeecss/style.css_config.yml

這個資料夾是完備的靜態網站,可以傳到任何靜態主機、跑在任何普通的 Web 伺服器上。

為什麼現在

如果所有東西聽上去很酷,那樣它的確很酷。但為什麼靜態網站技術現在興起,而早期的生成器未能給 WordPress 的統治帶來衝擊?有什麼變化?我們可以用多久?

如今的生成器和前輩們所處的生態系統完全不同,以前由於許多約束不得不選擇動態網站。如今那個基本的線上手冊已經過時了,儘管有些還能用。

瀏覽器成熟了

當 Tim Berners-Lee 釋出第一個 www 站點時,瀏覽器只是簡單的文件檢視工具,可以顯示超連結、超文字。

如今,我們在努力埋葬扯 Web 後腿的最後一個瀏覽器( IE8 安息)。現代瀏覽器本身就是一個作業系統,不只是展示從 Web 下載的文件,也可以跑成熟的 Web 應用,對任何的 CORS 相容的 API 發起外部呼叫,本地化資料儲存,向流媒體伺服器開啟 WebSockets ,甚至通過 WebRTC 處理其他瀏覽器的點對點連線。

隨著瀏覽器的成熟,許多之前需要伺服器動態程式碼環境支援的特性可以完全移到客戶端。想要站點評論嗎?新增 Disquz , Isso 或 Facebook 評論。整合社交功能?把 Twitter 或 Facebook 的 JS 外掛加進來。想要你網站有實時資料更新?用 Firebase 。想要搜尋?加上 Swiftype。想要支援線上聊天? Olark 就可以。哎呀,你都可以用 Snipcart 給站點加電商。

功能列表越來越多,基於純瀏覽器外掛的整個生態系統就形成了。除此之外,用 Ember.js 、 Angular.js 或 React 的現代瀏覽器 app 通常完全作為靜態網站部署,由一個純 API 後端的 CDN 伺服瀏覽器 UI 和移動端。

CDN 成為主流

當 Akamai 在 1999 年啟動第一個內容分發網路時,只有世界上最大的 Web 公司負擔得起由 CDN 邊緣節點分發web資產的服務。不久前 CDN 也只是 CNN 和 Facebook 規模的公司在用,而不是普通大眾。

Akamai 仍然保持企業級報價,而如今任何人都能註冊 Amazon AWS,把 CloudFront 放在自己站點前面。並且,小型企業負擔得起像 Fastly、 MaxCDN 和 CloudFlare 的 CDN 服務報價。

你可以在動態網站使用 CDN,但快取失效一直是計算機領域的一個棘手問題。至少,有關邊緣節點的快取和專門用來做請求計算的後端動態系統之間的平衡,是很棘手的。

另一方面,靜態站點可以直接部署到 CDN 上,從本地快取伺服附近終端使用者。折騰配置花時間,快取失效很棘手,但也可以用 Netlify 實現自動化。

效能很重要

移動裝置的蓬勃在很多方面改變了 Web 的面貌。越來越多的訪客從移動裝置進入 Web ,有時是 3G 連線。效能從未像現在這樣如此重要。

我們都知道: 57% 的網際網路使用者放棄載入超過三秒的頁面。人們過去願意等到 10 秒,但如今期待更高。在移動端,不能處理多工也做不了什麼,等網站載入實在是太煩了。超過 4% 的人表示,當用著一個慢悠悠的移動網站時,他們簡直要摔手機了。

無論你怎樣優化動態網站的效能,或者在這上面投入財力,它都不如精心開發一個靜態站點那樣保證效能,後者掛在一個月幾塊錢的 CDN 主機上。隨著效能愈發重要,難怪開發者尋找預生成 HTML 的方式,而不是讓伺服器把生成頁面的時間和資源花在每個 HTTP 請求上。

靜態網站生成器在開發過程中也消除了很多效能問題。

如果你在建一個數據驅動型動態網站,因為要支撐每一個 HTTP 請求,資料庫查詢的效率極其重要。即使在你的網站前方有個堅實的快取層,總要遇到這樣的風險,有的請求會成為快取剋星,觸發最壞的後端請求,引起整個系統的延時停頓。

而使用靜態生成的網站,把內容放到模版上多幾秒少幾秒無所謂:只有在你釋出時才會出現,從不會給終端使用者帶來效能問題。

構建工具到處都是

編譯器和構建工具過去是 C 和 Java 程式設計師擔心的事,不是你建站時用的。現在也不知是好是壞,情況完全變了。

如今,前端開發者採用了構建工具、包管理器和多種編譯器混搭。Grunt 是第一個成為趨勢的前端構建工具,如今大部分新專案都有構建階段。

隨著構建工具的普及,靜態站點生成器融入了前端工具包,而傳統動態站點的 php 衍生工具在現代的前端工具流眼中開始不入流。

遺失了什麼?

所有這些因素結合到一起,創造出了靜態站點生成器的潮流。難怪越來越多的站點開始靜態搭建。

但並不都是好事。在靜態站點生成器完全成為主流之前,有些東西需要進步。

初次上手靜態站點生成器的專案仍然很繁瑣,可用工具、文件、資源上有許多的細節和提升空間。

隨著靜態站點生成器生態系統的發展,離成熟的主題市場相距甚遠,對傳統動態平臺的支援也不夠。

然而,最大的困擾在內容編輯方面。在一個文字編輯器裡直接用 Markdown 然後發到 Github 上更像是前端開發者的理想工作流,並不是你會拉一個普通、不懂技術的終端使用者參與進來的事兒。

因此,許多用靜態站點生成器搭起來的的網站整合了動態 CMS。我們急切需要在在內容編輯器和靜態網站生成之間搭個橋。在那之前,生成靜態站點用於網站還只能是小眾。

其他人在致力於融合靜態站點生成和內容編輯的最佳解決方案,接下來幾年在內容和釋出方面無疑會有新的工作方式。

Contentful、 prismic.ioGatherContent 一樣的系統將 CMS 層從實際的建站工具解耦,很受多頻道內容管理者歡迎。在那裡你不是給一個特定的網站寫東西,也適用於移動 app、Facebook 頁面或白紙。釋出新內容觸發構建系統一個 Web 鉤子;然後靜態站點生成器從內容 API 取資料建站,成品直接發到 CDN。

編輯內容另一種方式是利用下面的庫:

在靜態生成器 Prose.io 上的 MarkDown 編輯器,無縫整合 Github API

prose.io 已經有一陣子了,整合 Github API ,給內容編輯者提供更友好的 UI 在 Github 裡編輯 MarkDown 檔案。

在 Netlify,我們在做一個開源 CMS ,不限定專門的靜態站點生成器、Git 主機或伺服平臺。目標是適用於目前所有的靜態站點生成器,我們認為這會是對現代靜態站點技術的一個突破。

很明顯,總會有網站不太適合靜態生成——尤其是那些核心內容持續更新的,或者那些一直在推送訊息、高度依賴搜尋和過濾的。

那也就是說,靜態站點生成器會在能力和流行度上繼續演進,基礎架構和生態系統愈發成熟。隨著工具的進步,我們會看到開發者在靜態站點技術上的突破。

在 Netlify,我們已經開始看到大型內容驅動站點。它們帶有實時搜尋、多語言支援和私有板塊,由靜態站點生成器和內容 API 搭建。靜態站點對效能和安全重要性的意識也越來越強,未來充滿期待。