浏览器内核的故事与JQuery的没落
# 浏览器内核的故事与jQuery的没落
# 内核
⾸先得搞懂浏览器内核究竟指的是什么。
浏览器内核⼜可以分成两部分:渲染引擎(layout engineer 或者 Rendering Engine)和 JS 引擎。它负责取 得⽹⻚的内容(HTML、XML、图像等等)、整理讯息(例如加⼊ CSS 等),以及计算⽹⻚的显示⽅式, 然后会输出⾄显示器或打印机。浏览器的内核的不同对于⽹⻚的语法解释会有不同,所以渲染的效果也 不相同。所有⽹⻚浏览器、电⼦邮件客户端以及其它需要编辑、显示⽹络内容的应⽤程序都需要内核。 JS 引擎则是解析 Javascript 语⾔,执⾏ javascript 语⾔来实现⽹⻚的动态效果。
最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独⽴,内核就倾向于只指渲染引 擎。有⼀个⽹⻚标准计划⼩组制作了⼀个 ACID 来测试引擎的兼容性和性能。内核的种类很多,如加上 没什么⼈使⽤的⾮商业的免费内核,可能会有 10 多种,但是常⻅的浏览器内核可以分这四种:
Trident
、Gecko
、Blink
、Webkit
。
# Trident (['traɪd(ə)nt])
Trident(IE内核):该内核程序在 1997 年的 IE4 中⾸次被采⽤,是微软在 Mosaic(”⻢赛克”,这是⼈类历 史上第⼀个浏览器,从此⽹⻚可以在图形界⾯的窗⼝浏览) 代码的基础之上修改⽽来的,并沿⽤到 IE11,也被普遍称作 “IE内核”。
Trident实际上是⼀款开放的内核,其接⼝内核设计的相当成熟,因此才有许多采⽤ IE 内核⽽⾮ IE 的浏 览器(壳浏览器)涌现。由于 IE 本身的 “垄断性”(虽然名义上 IE 并⾮垄断,但实际上,特别是从 Windows 95 年代⼀直到 XP 初期,就市场占有率来说 IE 的确借助 Windows 的东⻛处于 “垄断” 的地位)⽽使得 Trident 内核的⻓期⼀家独⼤,微软很⻓时间都并没有更新 Trident 内核,这导致了两个后果——⼀是 Trident 内核曾经⼏乎与 W3C 标准脱节(2005年),⼆是 Trident 内核的⼤量 Bug 等安全性问题没有得到 及时解决,然后加上⼀些致⼒于开源的开发者和⼀些学者们公开⾃⼰认为 IE 浏览器不安全的观点,也有 很多⽤户转向了其他浏览器,Firefox 和 Opera 就是这个时候兴起的。⾮ Trident 内核浏览器的市场占有 率⼤幅提⾼也致使许多⽹⻚开发⼈员开始注意⽹⻚标准和⾮ IE浏览器的浏览效果问题。
补充:IE 从版本 11 开始,初步⽀持 WebGL 技术。IE8 的 JavaScript 引擎是 Jscript,IE9 开始⽤ Chakra, 这两个版本区别很⼤,Chakra ⽆论是速度和标准化⽅⾯都很出⾊。
国内很多的双核浏览器的其中⼀核便是 Trident,美其名⽈ “兼容模式”。
Window10 发布后,IE 将其内置浏览器命名为 Edge,Edge 最显著的特点就是新内核 EdgeHTML
# Gecko (['gekəʊ])
Gecko(Firefox 内核):Netscape6 开始采⽤的内核,后来的 Mozilla FireFox(⽕狐浏览器) 也采⽤了该内核, Gecko 的特点是代码完全公开,因此,其可开发程度很⾼,全世界的程序员都可以为其编写代码,增加 功能。因为这是个开源内核,因此受到许多⼈的⻘睐,Gecko 内核的浏览器也很多,这也是 Gecko 内核 虽然年轻但市场占有率能够迅速提⾼的重要原因。
事实上,Gecko 引擎的由来跟 IE 不⽆关系,前⾯说过 IE 没有使⽤ W3C 的标准,这导致了微软内部⼀些 开发⼈员的不满;他们与当时已经停⽌更新了的 Netscape 的⼀些员⼯⼀起创办了 Mozilla,以当时的 Mosaic 内核为基础重新编写内核,于是开发出了 Gecko。不过事实上,Gecko 内核的浏览器仍然还是 Firefox (⽕狐) ⽤户最多,所以有时也会被称为 Firefox 内核。此外 Gecko 也是⼀个跨平台内核,可以在 Windows、 BSD、Linux 和 Mac OS X 中使⽤。
# Webkit
⼀提到 webkit,⾸先想到的便是 chrome,可以说,chrome 将 Webkit内核 深⼊⼈⼼,殊不知,Webkit 的⿐祖其实是 Safari。现在很多⼈错误地把 webkit 叫做 chrome内核(即使 chrome内核已经是 blink 了),苹果都哭瞎了有⽊有。
Safari 是苹果公司开发的浏览器,使⽤了KDE(Linux桌⾯系统)的 KHTML 作为浏览器的内核,Safari 所 ⽤浏览器内核的名称是⼤名鼎鼎的 WebKit。 Safari 在 2003 年 1 ⽉ 7 ⽇⾸度发⾏测试版,并成为 Mac OS X v10.3 与之后版本的默认浏览器,也成为苹果其它系列产品的指定浏览器(也已⽀持 Windows 平 台)。
如上述可知,WebKit 前身是 KDE ⼩组的 KHTML 引擎,可以说 WebKit 是 KHTML 的⼀个开源的分⽀。当 年苹果在⽐较了 Gecko 和 KHTML 后,选择了后者来做引擎开发,是因为 KHTML 拥有清晰的源码结构和 极快的渲染速度。
Webkit内核 可以说是以硬件盈利为主的苹果公司给软件⾏业的最⼤贡献之⼀。随后,2008 年⾕歌公司 发布 chrome 浏览器,采⽤的 chromium 内核便 fork 了 Webkit。
# Chromium/Bink
2008 年,⾕歌公司发布了 chrome 浏览器,浏览器使⽤的内核被命名为 chromium。
chromium fork ⾃开源引擎 webkit,却把 WebKit 的代码梳理得可读性提⾼很多,所以以前可能需要⼀天 进⾏编译的代码,现在只要两个⼩时就能搞定。因此 Chromium 引擎和其它基于 WebKit 的引擎所渲染 ⻚⾯的效果也是有出⼊的。所以有些地⽅会把 chromium 引擎和 webkit 区分开来单独介绍,⽽有的⽂章 把 chromium 归⼊ webkit 引擎中,都是有⼀定道理的。
⾕歌公司还研发了⾃⼰的 Javascript 引擎,V8,极⼤地提⾼了 Javascript 的运算速度。
chromium 问世后,带动了国产浏览器⾏业的发展。⼀些基于 chromium 的单核,双核浏览器如⾬后春 笋般拔地⽽起,例如 搜狗、360、QQ浏览器等等,⽆⼀不是套着不同的外壳⽤着相同的内核。
然⽽ 2013 年 4 ⽉ 3 ⽇,⾕歌在 Chromium Blog 上发表 博客,称将与苹果的开源浏览器核⼼ Webkit 分道 扬镳,在 Chromium 项⽬中研发 Blink 渲染引擎(即浏览器核⼼),内置于 Chrome 浏览器之中。
webkit ⽤的好好的,为何要投⼊到⼀个新的内核中去呢?
Blink 其实是 WebKit 的分⽀,如同 WebKit 是 KHTML 的分⽀。Google 的 Chromium 项⽬此前⼀直使⽤ WebKit(WebCore) 作为渲染引擎,但出于某种原因,并没有将其多进程架构移植⼊Webkit。
后来,由于苹果推出的 WebKit2 与 Chromium 的沙箱设计存在冲突,所以 Chromium ⼀直停留在 WebKit,并使⽤移植的⽅式来实现和主线 WebKit2 的对接。这增加了 Chromium 的复杂性,且在⼀定程 度上影响了 Chromium 的架构移植⼯作。
基于以上原因,Google 决定从 WebKit 衍⽣出⾃⼰的 Blink 引擎(后由 Google 和 Opera Software 共同研 发),将在 WebKit 代码的基础上研发更加快速和简约的渲染引擎,并逐步脱离 WebKit 的影响,创造⼀ 个完全独⽴的 Blink 引擎。这样以来,唯⼀⼀条维系 Google 和苹果之间技术关系的纽带就这样被切断 了。
Google 和苹果在多个领域都是竞争对⼿,⽽唯独在浏览器引擎上有技术合作,利益⼀致。但为了各⾃的 利益,谁都不会拿出 100% 的 “诚意” 来做好 WebKit,因为你做出来的成果竞争对⼿可以直接享⽤。移 动互联⽹已经崛起,⼿机和平板设备端必将成为浏览器的另⼀个战场。这个时候,如果 Google 跟苹果 仍然黏在⼀起,将会严重阻碍双⽅的进步,也会阻碍 WebKit 的进步。
“ 据说 Blink 删除了 880w ⾏ webkit 代码。
⾄于为什么叫 blink?有兴趣的可以看下这篇访谈 Paul Irish on Chrome Moving to Blink,⾥⾯说
“ it fits that Blink will never support the infamous tag.
Blink 引擎问世后,国产各种 chrome 系的浏览器也纷纷投⼊ Blink 的怀抱,可以在浏览器地址栏输⼊ chrome://version 进⾏查看。⽐如在 360 下
# Presto (['prestəʊ])
Presto 是挪威产浏览器 opera 的 “前任” 内核,为何说是 “前任”,因为最新的 opera 浏览器早已将之抛弃 从⽽投⼊到了⾕歌⼤本营。
Opera 的⼀个⾥程碑作品是 Opera7.0,因为它使⽤了 Opera Software ⾃主开发的 Presto 渲染引擎,取代 了旧版 Opera 4 ⾄ 6 版本使⽤的 Elektra 排版引擎。该款引擎的特点就是渲染速度的优化达到了极致,然 ⽽代价是牺牲了⽹⻚的兼容性。
Presto 加⼊了动态功能,例如⽹⻚或其部分可随着 DOM 及 Script 语法的事件⽽重新排版。Presto 在推出 后不断有更新版本推出,使不少错误得以修正,以及阅读 Javascript 效能得以最佳化,并成为当时速度 最快的引擎。
然⽽为了减少研发成本,Opera 在 2013 年 2 ⽉宣布放弃 Presto,转⽽跟随 Chrome 使⽤ WebKit 分⽀的 Chromium 引擎作为⾃家浏览器核⼼引擎,Presto 内核的 Opera 浏览器版本永远的停留在了 12.17。在 Chrome 于 2013 年推出 Blink 引擎之后,Opera 也紧跟其脚步表示将转⽽使⽤ Blink 作为浏览器核⼼引 擎。
Presto 与开源的 WebKit 和经过⾕歌加持的 Chromium 系列相⽐毫⽆推⼴上的优势,这是 Opera 转投 WebKit 的主要原因,并且使⽤ WebKit 内核的 Opera 浏览器可以兼容⾕歌 Chrome 浏览器海量的插件资 源。但是换内核的代价对于 Opera 来说过于惨痛。使⽤⾕歌的 WebKit 内核之后,原本快速,轻量化, 稳定的 Opera 浏览器变得异常的卡顿,⽽且表现不稳定,Opera 原本旧内核浏览器书签同步到新内核上 的⼯作 Opera 花了整整两年时间,期间很多 Opera 的⽤户纷纷转投⾕歌浏览器和其他浏览器,造成了众 多的⽤户流失。时⾄今⽇现在还有上千万⼈在使⽤⽼版本的 Opera。
很多⼈都认为 Opera 浏览器终⽌在了 12.17,此后所更新的 Opera 版本号不再是原来那个 Opera。说好的 Presto Forever 呢?
# 关于移动端
移动端的浏览器内核主要说的是系统内置浏览器的内核。
⽬前移动设备浏览器上常⽤的内核有 Webkit,Blink,Trident,Gecko 等,其中 iPhone 和 iPad 等苹果 iOS 平台主要是 WebKit,Android 4.4 之前的 Android 系统浏览器内核是 WebKit,Android4.4 系统浏览器 切换到了Chromium,内核是 Webkit 的分⽀ Blink,Windows Phone 8 系统浏览器内核是 Trident。
# 总结
浏览器内核主要指的是浏览器的渲染引擎,2013 年以前,代表有 Trident(IE),Gecko(firefox), Webkit(Safari chrome 等)以及 Presto(opera)。2013 年,⾕歌开始研发 blink 引擎,chrome 28 以后开 始使⽤,⽽ opera 则放弃了⾃主研发的 Presto 引擎,投⼊⾕歌怀抱,和⾕歌⼀起研发 blink 引擎,国内 各种 chrome系的浏览器(360、UC、QQ、2345 等等)也纷纷放弃 webkit,投⼊ blink 的怀抱。
还有⼀点⽂章⾥没有说的很明⽩,就是 Webkit 其实是 KHTML 的分⽀,这⾥的 KHTML 指渲染引擎, Webkit 其实就泛指了 Webkit 的渲染引擎 WebCore,⽽ Webkit 引擎的 Javascript 引擎 JSCore 则是 KJS 的 分⽀。⽽ chrome 则搭载了⾃⼰的 Javascript 引擎 V8。引⽤ 各主流浏览器内核介绍 ⾥的⼀段话:
我们上⾯提到 Chrome 是基于 WebKit 的分⽀,⽽ WebKit ⼜由渲染引擎 “WebCore” 和 JS 解释引擎 “JSCore” 组成,可能会让你搞不清 V8 和 JSCore 的关系。你可以这样理解—— WebKit 是⼀块主板, JSCore 是⼀块可拆卸的内存条,⾕歌实际上认为 Webkit 中的 JSCore 不够好,才⾃⼰搞了⼀个 V8 JS 引 擎,这就是 Chrome ⽐ Safari 在某些 JS 测试中效率更⾼的原因。
如果说 chromium 还不⾜以脱离 Webkit 的 “帽⼦”,Blink 的出现,代表着 chrome 将⾃主研发渲染引擎 (Blink)以及 Javascript 引擎(V8)。可以期待在不久的将来,⼈们谈起 chrome 想到的不是 Webkit ⽽ 是 Blink。
# JQuery的没落
最早期的开发,⼤多都使⽤jQuery,它给我们带来了很多的便利:快速选取元素,⽅便操作DOM元素的 API,各个浏览器之间完美的兼容性,链式操作,动画、ajax等等都是jQuery为前端开发⼈员来带的好 处。为什么现在越来越少⼈⽤了呢
# 一. JS更新带来的冲击
# 1. 快速选取DOM节点
对于⼤部分使⽤jQuery的开发⼯程师来说,能够快速选取DOM节点,这个⽆疑是⼀个重要的原因,但是 就⽬前情况来说,这个优势显然已经荡然⽆存了,为什么呢?跟⼤家说两个API,这两个API已经⾮常多 的⼈在⽤了,就是document.querySelector和document.querySelectorAll⽅法。这两个⽅法可以通过传⼊ css选择器形式的字符串,就可以匹配到预期的DOM节点。以下是⽬前两个API的兼容情况:
从图中可以看到,这两个API已经很好的兼容各个浏览器。
Vue中也是使⽤此API进⾏元素获取的
所以说jQuery快速选择DOM节点的优势已经不存在了。
# 2. 方便操作DOM元素的API
可以⽅便操作DOM元素的API,⽐如addClass 、removeClass 、toggleClass。现在原⽣JS也得到了⽀持, 这个API叫做classList。
# 3. 动画
现在CSS3动画技术已经⾮常的成熟,已经完全可以取代jQuery做的动画,⽽且还能⽐jQuery的animate⽅ 法实现更复杂的动画,兼容性好,性能消耗⼩,何乐⽽不为呢?举个例⼦吧,⽐⽅说如果实现背景颜⾊ 过度,CSS3可以完美的实现,但是jQuery就不⾏。并且现在已经出现了很多优秀的CSS3动画库,⼤名鼎 鼎的Animate.css库⼤家肯定都有⽿闻吧
# 4. Ajax操作
jQuery的ajax操作,为我们省去了兼容浏览器⽅⾯的问题,并且也提供了简明的API去调⽤get和post,让 开发者从繁琐的兼容性与使⽤原⽣API上解脱出来。但是现在,这个优势也已经⾮常微⼩了。不管是原⽣ JS的Fetch API还是axios。都为我们提供了强⼤的ajax使⽤能⼒,并且axios还有拦截器这个优势。这时相 较⽽⾔,jQuery的ajax确实已经⽆法相⽐了。
当然Fetch在IE上来说,肯定是没法⽤的
Fetch兼容性
但是已经有了Fetch的Polyfill⽅案:github/fetch,这样只需要引⽤这⼀个⼩⼩的JS,就可以使⽤⽅便的ajax 了。相较于jQuery,那是⼩巧很多的
# 二. 性能问题
在原来的开发中,⼯程师们不会太纠结于性能问题。但是现在不同了,为了提⾼⽤户体现,⾸要的就是 解决浏览器绘制所带了的性能问题。最经典的莫过重绘和回流这两个概念。
重绘:就是⻚⾯重新进⾏绘制,⽐⽅说,修改⼀个元素的背景颜⾊。
回流:⼀般来说,浏览器进⼊⻚⾯的时候就已经进⾏了⼀次回流,回流其实指的就是⻚⾯重新进⾏排版 布局。
既然我们想提⾼性能,那么就可以先从这两概念⼊⼿,肯定是以最⼩的代价更新⻚⾯是提⾼性能最好的 ⼿段。但可惜的是,jQuery并没有做到。为什么这么说,请看以下分析:
当我们拿到⼀组新闻数据要渲染到ul标签⾥时,通常我们会先将新闻数据逐条进⾏字符串拼接,紧接着 使⽤$符选择ul元素,并修改ul的innerHTML的值为拼接好的字符串(使⽤html API),此时完成了第⼀次 渲染。这次⻚⾯进⾏了重绘(这时必然的),⾸先不分析第⼀次的性能好或坏,⽤下⼀个说明将更加有 ⼒。
⽐如说我们这时多了⼀个换⼀换按钮。在传统开发模式中,这时的换⼀换按钮肯定执⾏的还是上⾯的代 码,获取元素,修改元素的innerHTML,但是现在问题出现了,就是我们有必要将所有元素重新删除, 再重新添加⼀遍吗?答案肯定是不需要(下图所示,创建⼀个元素的代价有多⼤)。
⼀个li节点上的所有属性
因为这时我们只需要将每⼀个li⾥的⽂字和a标签⾥的链接修改即可,那显然是没有必要像上⾯那样重新 再添加⼀遍li的。因为⼀个DOM元素,可能包含上百条属性,这对性能开销是很⼤的。
那么现在出现的新概念 Virtual DOM(虚拟DOM),就可以解决这个问题。其实Virtual DOM就是对真实 DOM节点的描述,通过改变Virtual DOM来以最⼩变动来改变真实DOM(Virtual DOM不⼀定真的⽐jQuery 性能更好)
# 三. 现代框架对JQuery的影响
现在国内⽐较⽕的React 、Vue 、Angular框架,都是属于MV*框架的范畴,其设计特点,主要是以数据为 核⼼。可以说操作DOM的事⼉,就留给框架去做了。这⽐传统jQuery开发效率⾼,代码可维护性⾼,可 扩展性强、性能好。
打个⽐⽅: 我让jQuery去买瓶酱油,给了他100块钱,这时我们需要告诉他去⼩卖铺的路怎么⾛、怎么跟⽼板说买啥 酱油,买多少钱的酱油,找多少零钱,还得告诉他怎么回来(命令式)。
这时我让Vue去买酱油去了,这时我只需要给他钱,并且告诉他⽬的地在哪⼉,买什么酱油即可,不需 要⼿把⼿教他(函数式)。
这就是传统开发和现代框架开发的不同。
使⽤现代框架开发,可以使⽤Webpack(当然使⽤jQuery也可以使⽤Webpack),可以使⽤⼈家提供的现 成的脚⼿架,⽐⽅说create-react-app,vue-cli。极⼤提⾼了开发的效率,并且可以使⽤最新的ES6、ES7 语法进⾏开发,在编码体验上,就提⾼了⼀个档次。
现在jQuery已经完美的退出了历史的舞台,他已经完成了他所要完成的任务。