1991 年 8 月,第一個靜態頁面誕生了,這是由 Tim Berners-Lee 發布的,想要告訴人們什么是萬維網。從靜態頁面到 Ajax 技術,從 Server Side Render 到 React Server Components,歷史的車輪滾滾向前,一個又一個技術誕生和沉寂。
前言
1994 年,萬維網聯盟(W3C,World Wide Web Consortium)成立,超文本標記語言(HTML,Hyper Text Markup Language)正式確立為網頁標准語言,我們的旅途從此開始。本文將沿着時間線,從“發現問題-解決問題”的角度,帶領大家了解 Web 技術發展的關鍵歷程,了解典型技術的誕生以及技術更迭的緣由,思考技術發展的原因。
Tim Berners-Lee
Tim Berners-Lee(蒂姆·伯納斯·李),英國科學家,萬維網之父,於 1989 年在歐洲核子研究組織(CERN)正式提出萬維網的設想。該網絡最初是為了滿足世界各地大學和研究所的科學家之間對自動信息共享的需求而設計和開發的,這也是為什么HTML的頂層聲明是 document,標簽名、文檔對象模型的名稱也是由此而來。1990 年 12 月,他開發出了世界上第一個網頁瀏覽器。1993 年 4 月 30 日,歐洲核子研究組織將萬維網軟件置於公共領域,把萬維網推廣到全世界,讓萬維網科技獲得迅速的發展,深深改變了人類的生活面貌。他創造了超文本標記語言(HTML),並創建了歷史上第一個網站。當然,現在只剩下了由 CERN 恢復的網站副本:info.cern.ch.
靜態網頁時代
早期的靜態網頁,只有最基本的單欄布局,HTML 所支持的標簽也僅有<h1>、<p>、<a>。后來為了豐富網頁的內容,<img>、<table>標簽誕生了。這一階段,Web 服務器基本上只是一個靜態資源服務器,每當客戶端瀏覽器發來訪問請求,它都來者不拒的建立連接,查找 URL 指向的靜態頁面,再返回給客戶端。
隨着網頁的飛速發展,人們發現要人工實現所有信息的編寫是非常困難的,而且非常耗時。設想一下,假如一個頁面有兩塊區域展示的內容是互相獨立的,那么你需要涵蓋所有的可能,需要編寫的頁面數量是兩塊區域的內容數量的乘積!此外,靜態網站只能夠根據用戶的請求返回指向的網頁,除了進行超鏈接跳轉,沒辦法實現任何交互。此時,人們想要
- 網頁能夠動態顯示
- 直接使用數據庫里的數據
- 網頁實現一些用戶交互
- 讓頁面更美觀
JavaScript 的誕生
1994 年,網景公司發布了 Navigator 瀏覽器,但他們急需一種網頁腳本語言,以使瀏覽器可以與網頁互動。
1995年,網景公司的 Brendan Eich 迫於公司的壓力,只花了十天就設計了 JS 的最初版本,並命名為 Mocha。后來網景公司為了蹭 Java 的熱度,把 JS 最終改名為 JavaScript。但實際情況是,網景公司和 Sun 公司結成聯盟,才更名為 JavaScript。
從此網頁有了一些簡單的用戶交互,比如表單驗證;也有了一些JS為基礎的動效,如走馬燈。但是讓網頁真正開始進入動態網頁時代的卻是以 PHP 為代表的后端網站技術。
擴展資料:第一次瀏覽器大戰
在網景公司推出 JavaScript 的時候,微軟以 JS 為基礎,編寫了 JScript 和 VBScript 作為瀏覽器語言,並在 1995 年的 8 月推出了 IE 1.0。由於微軟在系統里捆綁瀏覽器,而 90% 的人都在使用 Windows 操作系統,大量用戶被動地選擇了 IE。面對微軟快速搶占瀏覽器份額,網景公司無奈之下只能快速將 JavaScript 向 ECMA 提交標准,制定了 ECMAScript 標准。在這段時間,還發生過一件趣事,IE 4.0 發布當天 Netscape 的員工們發現公司的草坪上出現了一個大大的 IE 圖標,這明顯是一個挑釁的舉動。作為回應,Netscape 把自己的吉祥物 “Mozilla” 放在 IE 的圖標上,並掛上胸牌,寫着 “Netscape 72,Microsoft 18”——在當時, IE 的市場份額確實不如 Netscape Navigator。
但這無法解決份額的問題,網景公司最終在第一次瀏覽器大戰中落敗,於 1998 年,被美國在線(AOL)以42億美元收購。在 1998 年網景公司被收購前,網景公司公開了 Navigator 源代碼,想通過廣大程序員的參與重新獲得市場份額。Navigator 改名為 Mozilla。這也是火狐瀏覽器的由來,也是第二次瀏覽器大戰的伏筆。
CSS
1994 年,Hkon Wium Lie 最初提出了 CSS 的想法。1996 年 12 月,W3C 推出了 CSS 規范的第一版本。美觀是所有人的追求。HTML 誕生以來,網頁基本上就是一個簡陋的富文本容器。由於缺少布局和美化手段,早期網頁流行用table標簽進行布局。為了解決網頁“丑”的問題,Hkon Wium Lie 和 Bert Bos 共同起草了 CSS 提案,同期的 W3C 也對這個很感興趣。
早期網頁外觀早期的 CSS 存在多種版本,在 PSL96 版本你甚至可以在里面使用邏輯表達式。但因為它太容易擴展,瀏覽器廠商那么多,會變得很難統一,最終被放棄。
在眾多提案中,Håkon W Lie 的 CHSS(Cascading HTML Style Sheets)最早提出了樣式表可疊加的概念。
行尾的百分比表示這條樣式的權重,最終將根據權重計算最終值。圖中將會計算 30pt * 40% + 20pt * 60% 作為h2字體大小的最終值。為了解決 CSS 兼容性的問題,網景公司甚至還將 CSS 用 JS 來編寫。CSS 從誕生開始就伴隨着大量的 bug,不同瀏覽器表現不同坑害了無數的程序員。今天我們能用上相對靠譜的 css,不得不說這是一個奇跡。
動態網頁技術
1995 年,Rasmus Lerdof 創造的 PHP 開始活躍在各大網站,它讓 Web 可以訪問數據庫了,PHP 實現了人們渴望的動態網頁。這里的動態網頁不是指網頁動效,而是指內容的動態展示、豐富的用戶交互。PHP 就像給網絡世界打開了一扇窗,各種動態網頁技術(如 ASP、JSP)雨后春筍般的冒了出來,萬維網也因此開始高速發展,MVC 模式也開始出現在后端網站技術中。
動態網頁技術解決了以前各種令人無法呼吸的痛,生活總會越來越好的:
- 可以用數據庫作為基礎來展示網頁內容
- 可以實現表單和一些簡單交互
- 再也不用編寫一大堆靜態頁面了
PHP 等動態網頁技術的原理,大體上都是根據客戶端的請求,從數據庫里獲取相對應的數據,然后塞到網頁里去,返回給客戶端一個填充好內容的網頁。這個階段也是前后端耦合的。
網頁開發流程而當一些基礎的需求被滿足之后,動態網頁技術帶來的不足也漸漸暴露出來:
- 網頁總是刷新。用戶名密碼校驗需要刷新以展示錯誤提示;因下拉選擇器選擇不同而展示的內容需要刷新才能展示;每次數據交互必然會刷新一次頁面。
- 網頁和后端邏輯混合。相信老前端們都有過這樣的經歷:開發完HTML后,會把頁面發給后端修改,加上數據注入邏輯;聯調或者debug的時候兩個人坐在一塊看,查問題的效率很低。
- 有大量重復代碼無法復用。舉一個典型的例子,論壇。很多時候只有內容有變化,菜單、側邊欄等幾乎不會有改變,但每次請求的時候還是得再將整個網頁傳輸一遍。不僅頁面會刷新,速度慢,還挺耗流量(這個年代上網也是一種奢侈)。
然后 AJAX 站了出來。
AJAX
AJAX,Async JavaScript And XML,於 1998 年開始初步應用,2005 年開始普及。AJAX 的廣泛使用,標志着 Web2.0 時代的開啟。這同時也是各大瀏覽器爭鋒的時代。現在,我們可以通過 AJAX 來動態獲取數據,利用 DOM 操作動態更新網頁內容了。來看看加入了 AJAX 的網頁是怎么工作的:
這個時候前端路由還沒有興起,大多數情況下還是后端返回一整個頁面,部分內容通過 AJAX 進行獲取。隨着智能手機的出現,APP 開始萌芽。相比起網頁,APP 編寫好之后只需要數據接口就能工作;而網頁不僅需要后端寫業務邏輯,控制跳轉,還要寫一部分接口用於 AJAX 請求。這個階段前端能做的事情還是很少,還背負着“切圖仔”的綽號。隨着 HTML5 草案的提出,前端能做的交互越來越多,程序員們急需解決以下問題:
- 后端業務代碼和數據接口混合,還得兼容 APP 的接口(很多企業既有 APP 又有網站)
- 前端的代碼復雜度急劇增加
能不能讓前端也像 APP 一樣,只需要請求數據接口即可展現內容呢?
擴展資料:第二次瀏覽器大戰
2004 年 Firefox 發布,拉開了第二次瀏覽器大戰的序幕。同期市面上誕生的各種新興瀏覽器,如 Safari、Chrome 等,也加入了戰爭。
此前由於 XP 系統實在過於火爆,導致 IE 6 無任何競爭對手,微軟甚至解散了瀏覽器的大部分員工,只留下幾個人象征性地維護順便修補一下 bug。這讓開發人員非常痛苦。此時 Firefox 以優越於 IE 的性能和非常友好的編程工具,迅速將那些被 IE6 搞得焦頭爛額的網頁開發人員們,從水火之中救出,導致先讓前端工程師成為忠實的第一批用戶,然后,經由這些有經驗的開發人員們推廣到了普通的用戶群體。基於 webkit 內核的 Safari,借助自家產品(iOS、MacOS)的壟斷快速收割二手域名交易地圖移動端和 mac 端市場份額;同樣基於 webkit 內核的 Chrome,趁着微軟放松警惕,憑借優越於市場上所有瀏覽器的性能,如同中國歷史上的成吉思汗一樣大殺四方,快速擴展市場份額。微軟知道,自己已經失去了最初能稱霸的機會,這次它不想失去,IE 再次開始迭代,各大瀏覽器廠商又開始不顧標准,迭代再次開始,為了統一化標准,W3C 開發了 HTML5,但是遲遲得不到微軟的認可。在其他瀏覽器紛紛支持 HTML5 后,微軟發現,自己又成了孤家寡人,份額不斷縮水。2016 年,Chrome 瀏覽器份額超越 IE,第二次瀏覽器大戰結束。
瀏覽器大戰極大的推動了技術進步,正是 Google 研發出的 V8 引擎極大的提升了 JS 的運行效率,NodeJS 才有機會誕生,前端才能走向全棧。JS 其實沒有你想象的那么慢。
SPA
2008 年 HTML5 草案提出,各大瀏覽器開啟良性競爭,爭先實現 HTML5 功能。由於 HTML5 帶來前端代碼復雜度的增加,前端為了尋求良好的可維護性和可復用性,也不得不參考后端 MVC 進行了設計和拆分,后來出現了三大前端框架:Vue(2014)、React(2010)、AngularJS(2009)。
單頁應用返回一個空白的 HTML,並通過 JS 腳本進行動態生成內容,從此和頁面刷新說拜拜。后端不再負責模板渲染,前端和 APP 開始對等,后端的 API 也可以通用化了。前后端終於得以分離。(PS:最終目標是成為后端)但 SPA 因為返回的是空 HTML,所有 JS 也被打包為一個文件,需要在一開始就加載完所有的資源,
- 請求網頁后白屏時間比傳統網頁要長
- 爬蟲爬到的是空白頁面,沒辦法做 SEO
- 在業務復雜的情況下,請求文件很大,渲染非常慢。
這使得前端不得不拆分過於龐大的單頁應用,出現了框架的多頁面概念,也出現了多種解決方案。很多網頁首次加載的時候其實並不需要太多的東西,比如論壇首頁與貼子詳情頁,完全可以將其拆開,用戶在新打開的頁面閱讀反而體驗更好(多頁應用)。又比如管理后台,可以在頁面框架內,將每個菜單對應的管理頁拆出來動態加載(import)。
Server Side Render
Server Side Render,服務端渲染,簡稱 SSR,又稱服務端同構、直出,一般使用 NodeJS 實現。這里的服務端渲染和以前的不一樣,SSR 會利用已經“脫水”的首屏數據來渲染首屏頁面返回給客戶端,到了瀏覽器再注入瀏覽器事件,並且保留單頁應用的能力,對 SEO 非常友好。但學習成本高,限制較多。讓我們看看傳統 SPA 和加入了 SSR 的 SPA 在請求上的區別:
客戶端渲染示意
服務端渲染示意傳統 SPA 可以更快的返回頁面,請求響應時間更短;加載 JS 后才開始渲染,白屏時間更長,loading 結束后用戶感知到的相對可交互時間更早。而 SSR 在接到瀏覽器請求時,先從后端拉取首屏數據渲染在頁面內才返回,請求響應時間更長;因為節約了一段瀏覽器請求首屏數據的時間,白屏時間更短。由於 JS 異步加載,用戶感知的相對可交互時間變晚。但體驗上 SSR 一般更好。在極端情況下,用戶眼中傳統 SPA 會一直顯示 loading,使用了 SSR 的頁面則會出現“點不動”的情況。大多數時候 SSR 體驗會更佳,因為服務端承擔了大部分渲染工作,這也導致服務端負載變高。但在業務復雜的情況下,SSR 首屏請求的接口數很多,導致返回 HTML 變慢。歸根結底,SSR 不能很好的應付業務復雜的情況,首屏要加載的東西還是太多了。所以我們要怎樣讓用戶感知到的白屏時間變短呢?
- 減小加載體積
- 減少接口請求數
- PWA 緩存
- 分塊渲染
- …
NodeJS
說完了 SSR,必須說一下 NodeJS。2010 年 NodeJS 正式立項到現在已經 11 個年頭了,NodeJS 的誕生來自於 Ryan Dahl(下圖) 的靈感。他想以非阻塞的方式做所有事情,用完全異步方式可以處理非常多的請求(高並發)。
NodeJS 的出現讓前端向全棧的發展邁出了重大的一步。很多公司開始用 NodeJS 搞 BFF(backend for frontend),我們也開始把 Controller 層放到 NodeJS 來處理,后端只負責基礎業務數據。也就是現在的三層架構:
這種架構在跨端的時候具有良好的適配性,我們可以根據業務需求,為不同端設計不同的 Controller 和 View,而后台可以不做變更。這種架構省去了很多溝通成本,前端專注頁面的展示,后端專注業務邏輯。當然,NodeJS 還可以對后端數據進行預處理,前端根據自己的需要自己設計數據結構,頁面開發與接口調試形成閉環,還為后端分擔了壓力。
擴展資料:第三次瀏覽器大戰

智能手機的飛速發展,這張圖表現的淋漓盡致。第三次瀏覽器大戰是爭奪移動端市場份額的一戰,也是當下正在進行的一戰。Benedict Evans: “Mobile is eating the world.”(移動設備正在蠶食世界) “Mobile remakes the Internet.”(移動設備正在重構Internet)而未來,瀏覽器真正的對手不再是瀏覽器,而是小程序這樣結合了APP和網頁優點的新興技術。
未來
早在 2009 年,Facebook 的工程師就開發了 bigPipe,讓 Facebook 頁面打開速度提高了兩倍。bigPipe 使用 分塊渲染 的思想,將網頁的渲染變成了一小塊一小塊的,服務端渲染好一塊頁面就發送給客戶端。他們直接把木桶拆了,打破了短板效應。
服務端渲染 VS 流式分塊渲染時隔 11 年,也就是 2020 年 12 月,React 團隊提出了 React Server Components,算是一個可擴展的前后端融合方案。其理念和 bigPipe 類似,把組件放在服務端渲染,節省了從瀏覽器進行數據請求的開支,一些運行時也可以不用放到瀏覽器,減小了包大小(如 markdown 在服務端渲染好了,也就不再需要把工具庫發送給瀏覽器了)。React Server Components 的引入,也同步做到了自動的 Code Split。
React Server Components 原理不同的是 React Server Components 返回的不是 HTML,而是帶有結構和數據的自定義類 JSON 數據。
這種結構,是對服務端渲染的核心(結構+數據)進行抽象,結合 React 的工作方式(如 Suspense),平緩的從服務端過渡到了客戶端,維持了組件狀態,並且可以更自由的拼裝服務器組件和客戶端組件。
客戶端組件和服務端組件混用關於拆分這條思路,讓我想到微前端,雖然現在微前端還有很多問題,但微應用即服務也不乏為一條解決之道。未來前端或許會往“小而美”的方向發展,甚至形成一個以服務端組件為單位的包管理器,網頁打包大小會越來越小,更多的組件是從網絡上直接獲取。此外,我也很期待 Web Components 的發展,有了原生的支持,0kb runtime 也不是不可能了。合久必分分久必合,現存很多前端框架也可以得到統一了。當然現在 Web Components 想要投入使用,首先離不開瀏覽器的支持,而且必須有一個平緩的過渡,此外兼容性也是一個大問題(最后還是苦了程序員們)。
