概述
Web前端技术的发展从HTML诞生开始算,不过短短三十余载,但已经发生了翻天覆地的变化。可谓你方唱罢我登场,各自统领技术高峰几数年。
夏、商、周
HTML超文本标志语言诞生于1990年。司职配合浏览器展示网页内容和网页结构。早期纯粹HTML语言编写的网页,如同拥有了多张书签的字典一样,适合用户跳跃性阅读理解并掌握该页面所体现的知识。
CSS层叠样式表的概念于1994年提出并不断完善。当CSS样式表被结合到HTML页面时,前端世界发生了巨大变化。网页拥有了排版能力,这在视觉上的优化,让网页更容易被阅读。可谓历史上第一次用户体验的重大提升。
JavaScript脚本语言在1995年被设计出来。它真正的让网页活了起来。用户可以真切的和网页互动,良好的互动让用户更快的获取想要的知识。
夏商周在中国王朝史上延续时间最长。可以说,如果不是旧朝代最后一两位“昏君”的推波助澜,仅仅靠新朝代君主的顺天应命怕还是完不成朝代更迭。
但是,上古时期Web前端技术的改朝换代,恰恰靠的是旧朝代最后一个明君推动的。
春秋、战国
HTML和CSS,在定义初期,已经准确的描述了它们要解决的问题及其方向。同时由于它们不具备底层引擎,HTML和CSS显示的效果是受限于浏览器实现的。
通常我们只能针对不同浏览器下的标准添加相应的代码,实现跨浏览器有相同的效果,但是想要实现从0到1的创新,却不可能。它们在某种意义上,并不是真正编程语言。
JavaScript由于其交互能力,它一入场,就受到了人们的关注。由于浏览器底层有JS的引擎库,JavaScript是可以进行编程的,它自然地被人们提出大量的需求以希望将来具备强大的能力。
此消彼长,JavaScript紧紧的抓住了Web前端技术的高峰。
武无第二,自然百家争鸣。各式各样的JavaScript理论,框架,标准顺势而生。很难说究竟哪些框架会比较好,一般每个公司,每个人都有一个自己心中的白月光——util.js。
秦
2006年jQuery问世,如秦扫六合。当时前端面试常问的一个问题,瞬间可以把jQuery一统江山的气势拉回到眼前。“请你说一下,JavaScript和jQuery有什么区别?”
jQuery难道是JavaScript吗?当然不是,但当时所有接手项目的人都会优先考虑能否引入jQuery,毕竟使用jQuery的小明和不适用jQuery的小明不是同一个小明。jQuery让前端技术有了重大突破。
但,就因为好用的原因说jQuery统一前端的大千世界就有些武断了。真正让jQuery地位如此高的原因是它第一次改变了前端人的逻辑。
jQuery很自然的推动代码解耦。
早期要实现某个功能,前端逻辑是:HTML上要有对应的事件触发器,触发器里有对应的处理函数,处理函数是写在JavaScript里。一个功能要在两个语言中体现,有耦合的味道。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button onclick="message()">点我一下</button>
</body>
<script>
function message(){
alert('Hello World!')
}
</script>
</html>
使用jQuery后,很自然让我们有了解耦的做法,直接可以在JavaScript里通过选择器可以找到对应元素,然后直接添加对应的事件及其处理函数,实现功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>点我一下</button>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js"
integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
$(document).ready(function () {
$("button").click(function () {
alert("Hello World!")
});
});
</script>
</html>
解耦,让每一段代码都只关注自己。
jQuery统治时间比较长,中间也出现了一些问题,例如重复导入等问题,这推进了AMD,CMD这些模块化导入机制的发展。
汉
在jQuery统治技术高峰的后期,发生了三件大事。
第一件大事:2009年,Node.js诞生,意味着有了可以用JS编写的后端语言,JS能力更强了,这让前端世界拥有了更多的可能。
第二件大事:2015,es6标准诞生,意味着前端进入模块化技术领域。
第三件大事:这个阶段陆续诞生了“webpack”,“babel”等编译打包库。意味着你手写的代码可以通过某些预定的规则变成另外一种代码,而你无需关心变化过程。
三件大事整合在一起的结果是在浏览器无法使用es6标准的情况下,现代前端已经可以将代码编译成可被识别的代码,直接推进了技术进程。
而模块化让大家的努力都有了结果,Node.js生态上有了很多很有用的工具。
jQuery的危机出现了。
三国
直接让jQuery倒牌的原因是御三家的崛起:Vue,React,Angular。
上一节提到的三件大事,在那个时期,新旧前端技术项目是并存的,谁都没有替代对方的绝对优势。jQuery体系阵容庞大,生态完整,除了跟不上时代,其他的都久经考验。以webpack,babel,Node.js整合在一起的新前端技术,新特性让人兴奋,但是其项目构建困难,入门学习曲线陡峭。退一步说,即使整合起来的新前端技术的门槛低,我认为这两者依然无法互相取代。
因为,前端的思维逻辑没有变化。还是找DOM,操作DOM。
当React提出虚拟DOM时,情况发生了一边倒的变化。由于DOM虚拟化,这意味着开发者根本不要去找DOM元素了,而是把重点放在了组件和数据上。前端技术思维发生了第二次改变,就是把操作和数据分离。以前,我们是指令式的,告诉JavaScript要如何一步一步的做。现在我们是面向对象的,告诉JavaScript有什么样的输入,结果就会按照组件的预设返回。
JavaScript确实可以操作HTML和CSS,但是用JavaScript完全代替HTML和CSS有些过激了。HTML和CSS在结构和样式上的优势很明显,一是大家都会,二是很简单,三是代码清晰明了。
React想要在JavaScript代码中做HTML和CSS的工作。第一次我看jsx中那些template段的代码,我很不适应,这或许和后端的经验有关。好在,在React大肆攻城略地之时,Vue框架横空出世,一样是吸收虚拟DOM的思想,也是运用不一样的diff算法实现了React对应给到的功能。只是代码风格不一样。
总结的说,React和Vue谁更好,其实不用过多的去捧去压,而是看哪个代码风格更适合自己。它们所引发的思考逻辑是相同的。
明明是三国,为啥不说一下Angular呢?一是Angular的不兼容升级打击一大波人心。另外有更好的React,有国内呼声最高的Vue,Angular地位着实不高。
归晋?
Web前端技术下一个代表是谁?这个问题抛开不谈,我们先说别的。
先做一个简单题目:以下四个方案中,哪种方案我可以更早吃完沙茶面?
A. 走到楼下,点一份沙茶面,然后等上桌并吃完它。
B. 走到楼下,打车去10公里外的老字号,点一份沙茶面,然后等上桌并吃完它。
C. 走动楼下,打车去10公里外的网红店,排队,点一份沙茶面,然后等上桌并吃完它。
D. 应前文要求,强行凑一个方案选项。
是不是应该选A呢?
为什么要问这个答案很明显的问题。是想让你认真的想一想,虚拟DOM技术到底快在哪里?
首先,页面的元素变了就是真实DOM被修改了。好比上面的选择,不管怎么样,最后把面吃完的动作只能我来做,这一步和之前的下楼,打车,排队没有关系。因此,采用虚拟DOM技术的框架的快绝不是在修改真实DOM这里。
再看上面的选项,时间更长的原因是因为在吃面之前有太多的前摇,能不能减少前摇?可以,React,Vue们用的就是虚拟DOM的技术。所谓虚拟DOM技术就是建立一个语法树,通过遍历语法树而不是真实DOM进行对比找差,定位要修改的真实DOM,加速前摇过程。
聪明的你是否已经开始联想了,是否可以用别的方法来取代虚拟DOM技术,加速修改真实DOM之前的过程。建议阅读:Virtual DOM is pure overhead,文中确实给出了一种答案。
虚拟DOM技术需要建立抽象的语法树,然后以不变应万变。而svelte这样的编译器是在编译过程把源码生成了只针对当前变化的代码,将来还是修改源码通过编译生成适应未来变化的代码,是一种以变化应变化的方式,由于不再需要虚拟DOM,理论上将将更快(时间的消耗被移到编译过程了)。
或许,Vue,React,Angular这样首页白屏等待的默认潜规则要变了。
新时代的风已经吹起。