前端技術(shù)演進發(fā)展簡史

前言:為什么要了解歷史

以銅為鑒齐饮,可以正衣冠 ,以人為鑒碴里,可以明得失沈矿,以史為鑒,可以知興替(李世民)咬腋。
如果說我看得遠羹膳,那是因為我站在巨人的肩膀上(牛頓)。
了解一門技術(shù)的歷史根竿,可以幫助我們從歷史的角度來看技術(shù)演進發(fā)展陵像,理解前端技術(shù)為何會變成現(xiàn)在的模樣,理解技術(shù)社會之間的聯(lián)系寇壳,從歷史的更大的視野的層面來理解技術(shù)醒颖。

一、前端起源

1990 年壳炎,第一個web瀏覽器誕生泞歉,Tim 以超文本語言 HTML 為基礎(chǔ)在 NeXT 電腦上發(fā)明了最原始的 Web 瀏覽器。
1991 年,WWW誕生腰耙,這標志著前端技術(shù)的開始榛丢。
在開始之前先看看什么是前端

  • 現(xiàn)在的前端其實是個很大的范疇(web,移動端(Hybrid App)挺庞,游戲晰赞,桌面端(electron.js, NW.js),小程序等)选侨。
  • web前端開發(fā):針對瀏覽器的開發(fā)掖鱼,代碼在瀏覽器運行,它實質(zhì)是前端代碼在瀏覽器端被編譯援制、運行戏挡、渲染成頁面。前端代碼由HTML隘谣、CSS增拥、 JavaScript構(gòu)成。
  • 后端:針對服務器的開發(fā)寻歧,代碼在服務器運行掌栅。

二、前后端不分的時代

初期靜態(tài)網(wǎng)站

互聯(lián)網(wǎng)發(fā)展的早期码泛,WWW(World Wide Web)猾封、瀏覽器、JavaScript相繼誕生噪珊,最開始大多是HTML靜態(tài)網(wǎng)頁晌缘。

動態(tài)網(wǎng)站技術(shù)階段

比較有代表性的技術(shù)有JSP 、PHP痢站、ASP磷箕、ASP.NET 等語言,它們都類似阵难,是運行在服務端的語言岳枷。
那時候沒有專業(yè)的前端,前后端開發(fā)是一體的呜叫,前端代碼是后端代碼的一部分空繁,前端寫靜態(tài)模板,后端加數(shù)據(jù)套模板朱庆。

瀏覽器展現(xiàn)頁面的流程是:
  • 1盛泡、后端收到瀏覽器的URL請求,后端路由響應
  • 2娱颊、后端生成靜態(tài)頁面
  • 3傲诵、發(fā)送到瀏覽器渲染成頁面
后端 MVC 的開發(fā)模式

那時的網(wǎng)站開發(fā)凯砍,采用的是后端 MVC 模式。

  • Model(模型層):提供/保存數(shù)據(jù)
  • Controller(控制層):數(shù)據(jù)處理掰吕,實現(xiàn)業(yè)務邏輯
  • View(視圖層):展示數(shù)據(jù)果覆,提供用戶界面
    前端只是后端 MVC 的 V颅痊,那時候前端的 V 是在服務端渲染的殖熟。
    PHP,ASP斑响,ASP.NET菱属,JSP等都是典型的這樣的模式;
JSP頁面長這樣:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鳥教程(runoob.com)</title>
</head>
<body>
<p>
   今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>
</body> 
</html>
PHP模板
<h1>Car {{ $car->id }}</h1>
<ul>
  <li>Make: {{ $car->make }}</li>
  <li>Model: {{ $car->model }}</li>
  <li>Produced on: {{ $car->produced_on }}</li>
</ul>

三舰罚、AJAX誕生

AJAX誕生是前端發(fā)展的一個里程碑纽门,Ajax 技術(shù)誕生,改變了一切营罢。

  • 1999年赏陵,微軟公司發(fā)布IE瀏覽器5.0版,第一次引入新功能:允許JavaScript腳本向服務器發(fā)起HTTP請求饲漾。這個功能當時并沒有引起注意蝙搔,直到2004年Gmail發(fā)布和2005年Google Map發(fā)布,才引起廣泛重視考传。
  • 2005年2月吃型,AJAX這個詞第一次正式提出,指圍繞這個功能進行開發(fā)的一整套做法僚楞。從此勤晚,AJAX成為腳本發(fā)起HTTP通信的代名詞。
  • 2006年W3C發(fā)布了它的國際標準泉褐。
AJAX是基于現(xiàn)有的Internet標準赐写,并且聯(lián)合使用它們:

XMLHttpRequest 對象 (異步的與服務器交換數(shù)據(jù))
JavaScript/DOM (信息顯示/交互)
CSS (給數(shù)據(jù)定義樣式)
XML 、JSON(作為轉(zhuǎn)換數(shù)據(jù)的格式)
lamp AJAX應用程序與瀏覽器和平臺無關(guān)的膜赃!
在 2005 年挺邀,Google 通過其 Google Suggest 使 AJAX 變得流行起來。
Google Suggest 使用 AJAX 創(chuàng)造出動態(tài)性極強的 web 界面 當您在谷歌的搜索框輸入關(guān)鍵字時财剖,JavaScript 會把這些字符發(fā)送到服務器悠夯,然后服務器會返回一個搜索建議的列表。

AJAX 如何工作
ajax.png
AJAX使用的進化
  • STEP1:XMLHttpRequest 原生對象
var request = new XMLHttpRequest();
request.open('GET', '/my/url', true);
request.onload = function() {
  if (request.status >= 200 && request.status < 400) {
    // Success!
    var data = JSON.parse(request.responseText);
  } else {
    // We reached our target server, but it returned an error
  }
};
request.onerror = function() {
  // There was a connection error of some sort
};
 //  send request
request.send();
  • STEP2:$.ajax 操作
$.ajax({
    type: 'GET',
    url: '/my/url',
    data: data,
    success : function(result){
        //TODO RESULT
    }
});
  • STEP3:Promise 操作
let getData = function (url) {
    return new Promsie(function (resolve, reject) {
        $.ajax({
            type: 'GET',
            url: url,
            success: function (data) {
                resolve(data);         
            },
            error: function (err) {
                reject(err);
            }
        });
    });
};
 
var data = getData('/my/url').then(function (data) {
     //TODO DATA
});
  • STEP4:生成器 Gererator (koa1 使用了此函數(shù))
let it = null;
let ajax = function(url,data){
    $.ajax({
       type: 'GET',
       url: url,
       data: data || {},
       success : function(result){
            it.next(result);
       }
    });
};
 
function *getData(){
    var data = yield ajax('/my/url');
    console.log('data=',data);
};
 
it = getData();
it.next();
  • STEP5:Async/Await 高級操作 (koa2使用了async函數(shù))
let ajax = function(url,data){
    return $.ajax({
       type: 'GET',
       url: url,
       data: data || {}
    });
};
 
async function getData(){
    var data = await ajax('/my/url');
    console.log('data=',data);
};
 
getData();

四躺坟、前后分離時代

1沦补、jQuery 時代(開始注重前后端分離)
  • 2006年,jQuery發(fā)布咪橙,它當時的競爭對手很多:Dojo夕膀、Prototype虚倒、ExtJS、MooTools产舞。
    那時jQuery的宣傳口號僅能說是它的性能上升了100%魂奥、200%、300%易猫。
  • 2009年耻煤,Sizzle選擇器引擎研發(fā)成功,jQuery才取得壓倒性的優(yōu)勢准颓。
    當時前端界首要面對的是瀏覽器兼容性問題哈蝇,jQuery在處理DOM兼容上真是知微見著, 發(fā)掘出大量的DOM/BOM兼容方案(例如Dean Edwrad的addEvent(), IE的px轉(zhuǎn)換方案攘已,domReady的doScroll方案炮赦,globalEval的兼容方案等)

jQuery也打破了前端開發(fā)者的編程思維,之前是按照后端的開發(fā)思路來的:做一個業(yè)務就先封裝一個類样勃,有了這個類后吠勘,再想辦法傳入一個DOM,然后再通過類方法操作DOM峡眶。而jQuery是DOM為中心剧防,開發(fā)者可以選一個或多個DOM,變成jQuery對象幌陕,然后進行鏈式操作诵姜。當時為了改變用戶的思維,國內(nèi)的高手寫了不少文章來引導大家搏熄。
其次棚唆,開發(fā)者們已開始注重前后端分離,并要求不能污染Object原型對象心例,不能污染window全局變量宵凌。這樣,jQuery只占用兩個全局變量止后。
再次瞎惫,jQuery非常輕量級,采用Dean Edwards編寫的Packer壓縮后译株, 大小不到30KB瓜喇。并且里面實現(xiàn)得非常精妙,以令人瞠目的手段解決各種兼容痼疾歉糜。
為了學習這些技巧乘寒,高手們翻了一遍遍jQuery的源碼,所以網(wǎng)上有大量關(guān)于其源碼詳解的書藉匪补。甚至前端工程師在面試時也會被考到jQuery的源碼實現(xiàn)伞辛,這樣烂翰,jQuery在國內(nèi)更加流行。

jQuery的流行間接帶來以下的發(fā)展:
  • 促使人們對CSS1~CSS3選擇器的學習
  • 促進了瀏覽器原生選擇器引擎document.querySelectorAll蚤氏、Element.matches的誕生
  • 提高人們對domReady(DOMContentLoaded事件)的認識
  • 促進了Promise與requestAnimateFrame 的誕生
    最重要的是降低前端門檻甘耿,讓更多人進入這行業(yè),前端工程師的隊伍越來越壯大竿滨。
    這樣的話佳恬,不斷涌現(xiàn)出優(yōu)秀的工程師,他們創(chuàng)造了大量jQuery插件與UI庫姐呐。為后jQuery時代殿怜,人們研發(fā)前端模塊加載、統(tǒng)一異步機制曙砂、 打造大型MVC框架, 甚至伸向后端骏掀,接管打包腳本而發(fā)明Node.js鸠澈,來騰出大量時間。

這個時期涌現(xiàn)了大量jQuery-like的庫截驮,其中最著名的是Zepto.js笑陈。Zepto的出現(xiàn)也標志著我們進入移動互聯(lián)網(wǎng)時代。那時配套出的著名庫還有iScroll葵袭、fastclick涵妥、Lazy Load、Modernizr坡锡、fullPage蓬网。

隨著社會的發(fā)展jQuery存在的問題:

jQuery的鏈式操作風靡一時,也帶來許多問題鹉勒,當Ajax出現(xiàn)依賴時帆锋,就不可避免就出現(xiàn)回調(diào)地獄。因此針對這方面的討論禽额,誕生Deffered與Promise锯厢。有關(guān)回調(diào)地獄的討論,在后來講Node.js異步處理時脯倒,將會再一次熱烈地討論实辑。

  • 回調(diào)地獄
// Demonstrates nesting, CPS, 'callback hell'
 $.get('api1/data', function(resp1) {
     // Next that depended on the first response.
     $.get('api2/data', function(resp2) {
         // Next request that depended on the second response.
         $.get('api3/data', function(resp3) {
             // Next request that depended on the third response.
             $.get(); // ... you get the idea.
         });
     });
 });

jQuery如此多的選擇器不好維護,隨著社會的發(fā)展藻丢,頁面的交互也越來越復雜剪撬,造就了Web Page向Web App進化,新的趨勢帶來新的開發(fā)方式郁岩。

前端的發(fā)展離不開瀏覽器的發(fā)展
  • 瀏覽器現(xiàn)狀


    llqxz.png
  • 瀏覽器內(nèi)核


    llqnh.png
值得一提的是V8引擎(JS虛擬機):
  • 2008年9月2日婿奔,Google的chrome瀏覽器發(fā)布缺狠,一并發(fā)布的Js引擎,就是V8引擎萍摊。V8使用BSD協(xié)議開源挤茄。
  • V8引擎使用 C++ 開發(fā),將JavaScript編譯成了機器碼冰木,而不是字節(jié)碼穷劈,還用很多優(yōu)化方法提高性能,因此踊沸,V8引擎 速度非承眨快。
  • V8引擎還可以獨立運行逼龟,可以嵌入到其他任何C++程序中评凝,使在服務端運行JS成為可能。
  • 2009年腺律,基于V8引擎奕短,誕生了Nodejs,這是服務器端運行JS的運行環(huán)境匀钧。
    google的V8意義重大翎碑,它間接催生了,前端工程化之斯。
2日杈、前端模塊化階段(后jQuery時代、node.js誕生)

jQuery的出現(xiàn)讓前端工程師開發(fā)更加輕松佑刷,假如工程師想實現(xiàn)一個功能莉擒,搜索出一個jQuery插件來實現(xiàn)。那時候大家在前端網(wǎng)站就整天介紹jQuery插件项乒,很少討論一些底層的實現(xiàn)啰劲。

同時也冒出很多新的問題:
  • 前端工程師通常編寫一個頁面,會引入十多個乃至幾十個jQuery插件檀何,頁面上塞滿了Script標簽蝇裤。眾所周知,瀏覽器是單線程频鉴,Script的加載栓辜,會影響到頁面的解析與呈現(xiàn),導致著名的白屏問題(當時前端用力過猛垛孔,body中的所有東西都是動態(tài)生成的)藕甩。
  • jQuery另一個問題是全局污染,由于插件的質(zhì)量問題周荐,或者開發(fā)的素質(zhì)問題狭莱,這已經(jīng)是IIEF模塊或命名空間等傳統(tǒng)手段無法解決了僵娃。

于是一些優(yōu)秀的前端工程師們決定向后端取經(jīng),引入模塊機制腋妙。早期默怨,這種模塊機制在Dojo、EXT這些框架中都是內(nèi)置的骤素,但是顯然說服不了另一個框架的用戶用對方的模塊機制匙睹,于是有人立志要統(tǒng)一這種模塊定義方式,成立了CommonJS济竹。CommonJS誕生很久一段時間后痕檬,在后端的Node.js出現(xiàn)時才有用武之地。

CommonJS

CommonJS規(guī)范是誕生比較早的送浊。NodeJS就采用了CommonJS梦谜。是這樣加載模塊:

// clock.js 定義
module.exports ={
  satrt:function(){}
}
// 引用
var clock = require('clock');
clock.start();

但不料,CommonJS內(nèi)部也有派系罕袋,誰也說不服對方改淑。終于有一個人忍不住自己獨立開發(fā)出RequireJS,其模塊規(guī)范即為AMD浴讯。AMD最大的優(yōu)勢是它支持各種插件,且簡單明了蔼啦,并且提供shim機制加載以非AMD規(guī)范編寫的JavaScript代碼榆纽。

AMD

AMD,即 (Asynchronous Module Definition)捏肢,這種規(guī)范是異步的加載模塊奈籽,requireJs應用了這一規(guī)范。先定義所有依賴鸵赫,然后在加載完成后的回調(diào)函數(shù)中執(zhí)行:

// 定義
define(function () {
    return {
        attr1: 'attr1',
        attr2: 456,
        start:function(){}
    }
});
// 引用
require(['clock'],function(clock){
  clock.start();
});

AMD雖然實現(xiàn)了異步加載衣屏,但是開始就把所有依賴寫出來是不符合書寫的邏輯順序的,能不能像commonJS那樣用的時候再require辩棒,而且還支持異步加載后再執(zhí)行呢狼忱?
而國內(nèi),則流行另一種規(guī)范風格一睁,背靠阿里的大旗钻弄,有人推出了SeaJS,號稱其規(guī)范為CMD者吁。其實無論國內(nèi)還是國外窘俺,都產(chǎn)生許多模塊加載器,但最后還是被淘汰了复凳,規(guī)范一個就夠了瘤泪,不宜過多灶泵。

CMD

CMD (Common Module Definition), 是seajs推崇的規(guī)范,CMD則是依賴就近对途,用的時候再require赦邻。它寫起來是這樣的:

define(function(require, exports, module) {
   var clock = require('clock');
   clock.start();
});
還有一種模塊引入方法 ES6 import 、export

但是前端工程師的創(chuàng)造力就是這么驚人掀宋,從無到有深纲,再到泛濫成災,一年足矣劲妙。這可能與前端代碼是開源的原因湃鹊。最后有人統(tǒng)一了前兩種規(guī)范(AMD、Node.js模塊)镣奋,同時還支持老式的“全局”變量規(guī)范币呵。
自此,JavaScript開發(fā)模式煥然一身了,大家只要在代碼外面包一層就可以全世界通用蚌讼,不用擔心全局污染的問題寥裂。
其次,jQuery開發(fā)者需要解決大段HTML的生成問題妻柒,之前jQuery有.html,.append, $before等方法,可以將一大段符合HTML結(jié)構(gòu)的字符串轉(zhuǎn)換成DOM再插入到頁面上耘分。
但現(xiàn)在我們想分離出來举塔,讓HTML獨立到不同的文件中,然后插數(shù)據(jù)求泰,這就是前端模板央渣。前端模板的情況與模板規(guī)范一樣,從沒有到多如芝麻的境地渴频。這時篩選一個好用且性能高的模板是一件讓前端工程師頭疼的問題芽丹,那時網(wǎng)上有許多評測文章來介紹它們。
前端模板技術(shù)可以用一個公式來描述:
HTML = template(vars)
有了前端模板后卜朗,又誕生了前端路由拔第,基于它們,人們發(fā)明一個新詞匯SPA聊替。作為這個時代的尾聲楼肪,來自Ruby界的高手Ryan Dahl發(fā)明了Node.js。前端工程師們歡呼:可以不用傳統(tǒng)的后端就能自己寫一個網(wǎng)站了惹悄!
Node.js的發(fā)展就不詳述了春叫,很快它就冒出海量模塊、路由、狀態(tài)管理暂殖、數(shù)據(jù)庫价匠、MVC框架都有了。這時呛每,前端就缺自己的MVC框架了踩窖。Node.js轉(zhuǎn)眼就十歲生日了。

3晨横、MVC, MVVM洋腮,SPA、小程序(前端工程化階段)

在大量的MVC與MVVM框架中手形。最先火起來的是Backbone.js啥供,使用純正的MVC模型, Backbone.js是jQuery最后的支持者库糠,它強依賴于jQuery伙狐。
Backbone.js的作者還搞了另一套編譯語言CoffeeScript, 里面的箭頭函數(shù)、類機制瞬欧、 解構(gòu)賦值等語法糖都深深影響了后來的ES6贷屎。

前端MVC

傳統(tǒng)的MVC主要分為三部分

  • View 傳送指令到 Controller
  • Controller 完成業(yè)務邏輯后,要求 Model 改變狀態(tài)
  • Model 將新的數(shù)據(jù)發(fā)送到 View艘虎,用戶得到反饋
mvc.jpg

MVC簡單實現(xiàn)

function Model(value) {
    this._value = typeof value === 'undefined' ? '' : value;
    this._listeners = [];
}
Model.prototype.set = function(value) {
    var self = this;
    self._value = value;
    setTimeout(function() {
        self._listeners.forEach(function(listener) {
            listener.call(self, value);
        });
    });
};
Model.prototype.watch = function(listener) {
    this._listeners.push(listener);
};
Model.prototype.bind = function(node) {
    this.watch(function(value) {
        node.innerHTML = value;
    });
};

function Controller(callback) {
    var models = {};
    var views = Array.prototype.slice.call(document.querySelectorAll('[data-bind]'), 0);
    views.forEach(function(view) {
        var modelName = view.getAttribute('data-bind');
        (models[modelName] = models[modelName] || new Model()).bind(view);
    });
    callback.call(this, models);
}


// html:
<span data-bind="hour"></span> : <span data-bind="minute"></span> : <span bind="second"></span>

// controller:
new Controller(function (models) {
    function setTime() {
        var date = new Date();
        models.hour.set(date.getHours());
        models.minute.set(date.getMinutes());
        models.second.set(date.getSeconds());
    }
    setTime();
    setInterval(setTime, 1000);
});

接著下來是谷歌的Angular唉侄,微軟的Knockout.js,蘋果的Ember.js這三個MVVM框架野建,MVVM就是比MVC多一個數(shù)據(jù)綁定功能美旧,但這數(shù)據(jù)綁定功能是非常難實現(xiàn)。Knockout是使用函數(shù)代替屬性的技巧實現(xiàn)贬墩,它的設計影響到后來的Mobx;Ember.js是基于Object.defineProperty妄呕;Angular是將函數(shù)體轉(zhuǎn)譯成setter()陶舞、getter()函數(shù)。

大公司將后端開發(fā)經(jīng)驗挪用過來绪励,用Node.js開發(fā)了一套CLI肿孵,里面包含了腳手架生成, 打包腳本疏魏、語法風格檢測停做、環(huán)境變量插入,代碼復雜度檢測大莫,代碼提交時自動跑單元測試蛉腌, 圖片與JS壓縮等功能。ESLint、JSLint烙丛、JSHint舅巷、CSS Lint、 htmllint等就是那時期出現(xiàn)的河咽。

但CLI的出現(xiàn)導致了前端的分裂钠右,以前大家都使用jQuery,但自CLI幫你建好項目的那一刻起忘蟹,就將你劃歸某一子陣營飒房,你是Angular?Ember.js媚值?還是jQuery狠毯?對了,jQuery沒有大公司支撐的陣營被快速邊緣化杂腰。

對于個人開發(fā)者垃你,他們是沒有能力開發(fā)這么功能完備的CLI,于是出現(xiàn)了Code Climate喂很、Travis CI惜颇、CircleCI這樣的平臺。它們的出現(xiàn)標志著jQuery小作坊時代的終結(jié)了少辣。

前端開發(fā)者也出現(xiàn)分化:有些人轉(zhuǎn)向后端凌摄,出現(xiàn)了CNode的門戶網(wǎng)站。另外一些人開始搞工程化漓帅。一時間出現(xiàn)上百種構(gòu)建工具锨亏,出名的有Grunt、Gulp忙干、FIS3器予、webpack、 Rollup捐迫、npm-script乾翔。

你方唱罷我登場,這些構(gòu)建工具均會經(jīng)歷時代的考驗施戴,如大浪淘沙般反浓,最后存活得僅為寥寥。現(xiàn)在使用較多的webpack赞哗,Rollup雷则。

jQuery的時代一去不返了,再沒有人關(guān)心拖了N年的Bootstrap 4終于發(fā)布了肪笋,沒有人知道jQuery3.5的瘦身計劃月劈,也沒有人問jQuery的源碼度迂,漸漸地,大家不關(guān)注jQuery的工具鏈了艺栈。

以React, Vue, Angular為代表的前端框架英岭,造就了如今SPA(single page application)的大勢所趨勢。同時React - React Native, Vue - Weex湿右,node.js诅妹,各種小程序等也正在拓展前端的邊界。
SPA 單頁面應用原理
  • 什么是SPA? SPA 即單頁面毅人,就是頁面整體不刷新吭狡,不同的頁面只改變局部的內(nèi)容的一種實現(xiàn)方式。
  • 瀏覽器URL丈莺,location.hash部分發(fā)生變化划煮,頁面不會重新請求,其它參數(shù)變化缔俄,均會引起頁面的重新請求弛秋,而在Js中恰恰有事件 window.onhashchange 能監(jiān)聽到 location.hash的變化,于是就利用這個原理來達到一個修改局部內(nèi)容的操作(vueRouter就是利用這一原理實現(xiàn)的俐载,還有HTML5蟹略,history.pushState實現(xiàn)history模式)。
<!DOCTYPE html>
    <head>
        <script type="text/javascript">
            window.onhashchange = function(){
                var page = location.hash;
                if(page === '#home'){
                    document.getElementById('main').innerHTML = '這是首頁';
                    return;
                };
                
                if(page === '#help'){
                    document.getElementById('main').innerHTML = '這是幫助頁面';
                    return;
                };
                document.getElementById('main').innerHTML = '404';
            }
        </script>
    </head>
    <body>
        <header>
            <a href="#home">首頁</a>
            <a href="#help">幫助</a>
        </header>
        <article id="main"></article>
    </body>
</html>
單頁面應用的問題:
  • 對現(xiàn)有的搜索引擎不友好
  • 首頁加載速度變慢
    于是遏佣,為了解決這個問題挖炬,前端又把網(wǎng)頁搬到后端去渲染了,出現(xiàn)了状婶,服務端渲染(SSR: server side render)只是這次不一樣的后端渲染意敛,跟JSP,PHP膛虫,ASP不一樣了草姻,現(xiàn)在可以前后的分離開發(fā),一套后臺多端使用稍刀,前后端代碼解耦碴倾,專業(yè)的人做專業(yè)的事!

什么是服務端渲染
簡單理解是將組件或頁面通過服務器生成html字符串掉丽,再發(fā)送到瀏覽器,最后將靜態(tài)標記"混合"為客戶端上完全交互的應用程序异雁。
需要SEO的程序捶障,就需要SSR,但是,SSR會讓服務器的開銷增加纲刀,服務器壓力比較大项炼。

webServer(可以用node服務),CGI:(Common Gateway Interface)公共網(wǎng)關(guān)接口,CDN锭部,交互圖:
  • 1暂论、紅圈1表示SSR
  • 2、紅圈2表示瀏覽器渲染


    timg.jpg

五拌禾、結(jié)語

在前后不分的時代取胎,由于靜態(tài)網(wǎng)頁完全滿足不了社會的發(fā)展對網(wǎng)頁的需求,于是湃窍,由后端工程師主導的PHP,JSP,ASP的動態(tài)網(wǎng)頁誕生了闻蛀,但是服務端渲染有很多的弊端,服務器壓力大您市,前后端代碼耦合高觉痛,交互差,頁面的交互需要刷新整個網(wǎng)頁茵休,2005年Ajax誕生薪棒,改變了一切,前端走上了第一個里程碑式的時代榕莺,前后的分離開始注重俐芯,jQuery風靡一時,它的成功是前端人的一代記憶帽撑,各種jQuery插件層出不窮泼各,問題頁誕生了,各種插件的全局變量污染亏拉,jQuery的鏈式操作的回調(diào)地獄扣蜻,導致了模塊化,延遲對象等新技術(shù)的提出及塘,2009年node.js誕生莽使,催生了前端工程化,react,vue,anguler等MVC,MVVM框架的流行讓前端SPA成為大勢所趨笙僚!
前端技術(shù)的發(fā)展芳肌,是在不斷的解決問題,誕生新的技術(shù)肋层,是社會在不斷發(fā)展中催生了新技術(shù)亿笤,同時新技術(shù)又促進社會的前進,相互交織栋猖,螺旋前進净薛!
本人學識有限,難免會存在理解錯誤的地方蒲拉,望碼友高逼格指正肃拜,勿噴痴腌。

參考資料:
前端的發(fā)展歷程
大前端的技術(shù)原理和變遷史
前端發(fā)展簡史
前端開發(fā)進化史,你經(jīng)歷過哪幾個時期
等等燃领!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末士聪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子猛蔽,更是在濱河造成了極大的恐慌剥悟,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枢舶,死亡現(xiàn)場離奇詭異懦胞,居然都是意外死亡,警方通過查閱死者的電腦和手機凉泄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門躏尉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人后众,你說我怎么就攤上這事胀糜。” “怎么了蒂誉?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵教藻,是天一觀的道長。 經(jīng)常有香客問我右锨,道長括堤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任绍移,我火速辦了婚禮悄窃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蹂窖。我一直安慰自己轧抗,他們只是感情好,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布瞬测。 她就那樣靜靜地躺著横媚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪月趟。 梳的紋絲不亂的頭發(fā)上灯蝴,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天,我揣著相機與錄音孝宗,去河邊找鬼绽乔。 笑死,一個胖子當著我的面吹牛碳褒,可吹牛的內(nèi)容都是我干的折砸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼沙峻,長吁一口氣:“原來是場噩夢啊……” “哼睦授!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起摔寨,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤去枷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后是复,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體删顶,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年淑廊,在試婚紗的時候發(fā)現(xiàn)自己被綠了逗余。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡季惩,死狀恐怖录粱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情画拾,我是刑警寧澤啥繁,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站青抛,受9級特大地震影響旗闽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蜜另,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一适室、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蚕钦,春花似錦亭病、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至邮屁,卻和暖如春整袁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背佑吝。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工坐昙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芋忿。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓炸客,卻偏偏與公主長得像疾棵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子痹仙,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容