前端模板技术面面观(1)

此文已由作者郑海波授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验

此文的写作耗时很长,称之为雄文不为过,小心慢用

此文缘由

其实从发布regularjs之后,我发现在google搜索regularjs 不是给我这个画面

就是给我这个画面

突然发现取名字真是个大学问,当时就基本预计到了会有不明真相的朋友认为它只是一个照搬angularjs的家伙,对于这点,有兴趣的朋友可以看下【为什么要造Regularjs这个轮子】

而在这个文章,我不会直截了当去与angular做直接的对比,而是从最基本原理开始对现有的模板解决方案进行一个全面的分类,同时会给出它们的一些或优或劣的特性,这些特性基本都是本质性的,即它不为维护者的水平高低和勤勉与否所限制,所以是具有客观性的。

什么是模板解决方案?

你可以先简单的理解为模板引擎。

事实上前端的模板解决方案已经从 “选出一个好用的模板好难” 发展到了 “从这么多模板中选一个好难的”的阶段,Template-Engine-Chooser!似乎也开始无法跟上节奏了。再加上目前Dom-based的模板技术的崛起(angularjs, knockout等),渐渐让这个领域有乱花渐欲迷人眼的感觉。

这篇文章会对当今前端界的三种截然不同的模板方案做一个全面的对比,它们分别是

  1. String-based 模板技术 (基于字符串的parse和compile过程)
  2. Dom-based 模板技术 (基于Dom的link或compile过程)
  3. 杂交的Living templating 技术 (基于字符串的parse 和 基于dom的compile过程)

同种类型的模板技术的可能性都是相同的,即同样身为dom-based的vuejs如果愿意可以发展为angularjs的相同功能层级。

(注: 其实这么说作者后续思考后觉得并不是很妥当,因为决定这类框架的还有重要一环就是它们的数据管理层:,比如是基于脏检查还是基于setter和getter,就会有截然不同的定位)

另外需要注意的是任何一种类型的模板技术都是不可被替代的,它们甚至可以结合使用,并且很长一段时间内还会继续共存下去。

除此之外另外一种奇葩模板技术本文也会提到即react,了解后你会发现它的特性更接近于Living templating。

在进入介绍之前,我们需要先过一下不得不说的 InnerHTML,它是本文的关键因素。

innerHTML

我不认为还需要从innerHTML的细节讲起,我们对它太熟悉了,那就直接从优劣开始讲吧!

innerHTML 毫无疑问是好的

在innerHTML正是成为 web 标准 前,它当之无愧的已经是大家公认的事实标准,这是因为:

1 . 它便于书写并且直观

想象下你必须添加如下的html到你的文档里

<h2 title="header">title</h2>
<p>content</p>

直接使用 innerHTML

node.innerHTML = "<h2 title="header">title</h2><p>content</p>"

在对比使用Dom API

var header = document.createElement('h2');
var content = document.createElement('p');
h2.setAttribute('title', 'header');
h2.textContent = 'title';
p.textContent = 'content';
node.appendChild(header);
node.appendChild(content);

innerHTML 毫无疑问赢得了这张比赛.

尽管部分框架例如mootools:Element 提供了高效的API来帮助你创建dom结构,innerHTML仍然会是大多数人的最佳选择

2 . 它很快,特别在old IE

随着浏览器的发展,这个测试可能越来越不符合实际,innerHTML和 Dom Level 1创建dom结构的差距正变得原来越小

3. 它完成进行了String -> Dom的转换

这个论点有点拗口,事实上后续要提到的两类模板技术都是因为这个特点而与其有了强依赖

然而我们又清楚的被告知:

The recommended way to modify the DOM is to use the DOM Level 1 API. ——Chapter 15 of "Javascript: The Definitive Guide_"

为什么?

innerHTML 有时候又是不听话的

1. 安全问题

innerHTML 具有安全隐患.,例如:

document.body.innerHTML = "<img src=x   onerror='alert(xss)'/>"

我知道像你这样优秀的程序员不会写出这样的代码,但当html片段不完全由你来控制时(比如从远程服务器中),这会成为一个可能引爆的炸弹。

2. 它很慢

等等,你刚才说了它很快! 是的,但是如果你仅仅为了替换一个属性而用innerHTML替换了所有的Dom节点,这显然不是一个明智的决定,因为你深知这是低效的。所以说:

Context is everything

所有离开背景谈的性能、功能、性功能都是伪科学

3. 它很笨

它会完全移除所有现有的Dom,并重新渲染一遍,包括事件和状态都以不复存在,这点利用innerHTML来进行render的框架(例如Backbone)的开发者应该深有体会,为了减少损失,不能不把View拆的越来越细,从而抱着看似“解耦完美”的架构体系进入了维护的深渊。

注: 其实react的最大贡献就是它差不多是提供了一个更smart的innerHTML解决方案。

4. 有可能会创建出意料之外的节点.

由于html的parser非常的“友好”, 以至于它接受并不规范的写法,从而创建出意料之外的结构,而开发者得不到错误提示。

好了,到现在为止,我们大概了解了innerHTML这个朝夕相处的小伙伴,接下来我们正式聊一聊模板技术,首先我们从最常见的“String-based templating”开始

String-based templating

基于字符串的模板引擎最大的功劳就是把你从大量的夹带逻辑的字符串拼接中解放出来了,由于它的完全基于字符串的特性,它拥有一些无可替代的优势。

It is essentially a way to address the need to populate an HTML view with data in a better way than having to write a big, ugly string concatenation expression. --- cited from http://www.dehats.com/drupal/?q=node/107

示例

  1. mustache及其衍生: 弱逻辑
  2. Dust.js: 强逻辑 (推荐)
  3. doT.js: 超级快

基本原理

如上图所示,我们发现字符串模板强依赖于innerHTML(渲染), 因为它的输出物就是字符串。由于这篇文章的重点不在这里,我们不会再对它们如何使用作深究。

优点

  1. 快速的初始化时间: 很多angular的簇拥者在奚落String-based templating似乎遗漏了这一点。
  2. 同构性: 完全的dom-independent,即可作为用服务器端和浏览器端(客官先不要急着搬phantomjs哈).
  3. 更强大的语法支持:因为它们都是不是自建DSL就是基于JavaScript语法,Parser的灵活性与受限于HTML的Dom-based模板技术不可同日而语

缺点

  1. 安全隐患: 见innerHTML
  2. 性能问题:见 innerHTML.
  3. 不够聪明: 见innerHTML(呵呵),除此之外render之后数据即与view完全分离。

尽管在这几年的发展之下,由于异常激烈的竞争,基于字符串的前端模板技术变得越来越快,但是它们显然大部分都遗漏了一些问题

  1. 大侠们你们没有考虑进把输出字符串加载到Dom的时间,这才是真正瓶颈之一
  2. 不在相同功能前提下的对比有意义么?

Dom-based Template Engine

近几年,借着Angularjs的东风,Dom-based的模板技术开始大行其道,与此同时也出现了一些优秀的替代者,就我们国人而言,近的就有@尤小右Vuejs 和 司徒大大avalonjs。看仓库就可以发现风格也是完全不同:1) 一个简洁优雅 2)一个奔放不羁

示例

  1. Angularjs: 都28000star了还需多说么
  2. Knockout: 在此领域内,对Web前端而言是鼻祖级的

大致流程

Dom-based的模板技术事实上并没有完整的parse的过程(先抛开表达式不说),如果你需要从一段字符串创建出一个view,你必然通过innerHTML来获得初始Dom结构. 然后引擎会利用Dom API(attributes, getAttribute, firstChild... etc)层级的从这个原始Dom的属性中提取指令、事件等信息,继而完成数据与View的绑定,使其"活动化"。

所以Dom-based的模板技术更像是一个数据与dom之间的“链接”和“改写”过程。

注意,dom-based的模板技术不一定要使用innerHTML,比如所有模板都是写在入口页面中时, 但是此时parse过程仍然是浏览器所为。

优点

  1. 是活动的: 完成compile之后,data与View仍然保持联系,即你可以不依赖与手动操作Dom API来更新View
  2. 是运行时高效的: 可以实现局部更新
  3. 指令等强大的附属物帮助我们用声明式的方式开发APP

缺点

  1. 部分请见innerHTML
  2. 没有独立的Parser,必须通过innerHTML(或首屏)获取初始节点,即它的语法是强依赖与HTML,这也导致它有潜在的安全问题
  3. 信息承载于属性中,这个其实是不必要和冗余的。 部分框架在读取属性后会通过诸如removeAttribute的方式移除它们,其实这个不一定必要,而且其实并无解决它们Dom强依赖的特性,比如如果你查看[angular的todomvc]的节点,你会发现它的输出是这样的:
  4. FOUC(Flash of unstyled content):即内容闪动,这个无需多说了,只怪它初次进入dom的内容并不是最终想要的内容。

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请点击

相关文章:
【推荐】 使用Phaser开发你的第一个H5游戏(一)

原文地址:https://www.cnblogs.com/163yun/p/10064581.html

时间: 2024-10-07 16:30:23

前端模板技术面面观(1)的相关文章

互联网前端开发技术栈

互联网前端开发技术栈 前言 互联网建立60多年了,网站开发技术日新月异,但web前端始终离不开浏览器,最终还是HTML+JavaScript+CSS这3个核心,围绕这3个核心而开发出来大量技术框架/解决方案. 我从2000年初开始做网站开发,使用的技术不断迭代,一些消失了,更多的出现了. 最近写过  .NET技术大系概览 (迄今为止最全的.NET技术栈) ,相信很多网友感叹掌握的.NET技术远没有这个技术栈里面所描述的多. 问题 大家是否想过: Web前端开发究竟包含哪些技术呢? 我所掌握的技术

横瓜先生深度剖析QQ空间前端后端技术AJAX与FORM等等

[皇帝]北京-横瓜-7年(601069289)  22:06:34 [元帅]横瓜-PHP教父(601069289)  21:35:29 这里是QQ空间的图片上传方法 是FLASH 我草 [元帅]横瓜-PHP教父(601069289)  21:36:31 竟然不是JS QQ空间用FLASH 图片上传方法 [元帅]横瓜-PHP教父(601069289)  21:37:35 至此,整个QQ空间的技术,已经全部被我破解 @IT柏拉图 [元帅]IT柏拉图(2500875)  21:38:11 你真是天才,

前端模板引擎入门

模板引擎 模板引擎 起到 数据和视图分离的作用, 模板对应视图, 关注如何展示数据, 在模板外头准备的数据, 关注那些数据可以被展示. 后端模板引擎 freemarker 如下介绍,  java后台的模板引擎, freemark介绍,其图能很好标明这种关系. http://freemarker.org/ Apache FreeMarker is a template engine: a Java library to generate text output (HTML web pages, e

聊一聊前端模板与渲染那些事儿

欢迎大家收看聊一聊系列,这一套系列文章,可以帮助前端工程师们了解前端的方方面面(不仅仅是代码): https://segmentfault.com/blog/frontenddriver 作为现代应用,ajax的大量使用,使得前端工程师们日常的开发少不了拼装模板,渲染模板.我们今天就来聊聊,拼装与渲染模板的那些事儿. 如果喜欢本文请点击右侧的推荐哦,你的推荐会变为我继续更文的动力 1 页面级的渲染 在刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串

前端开发技术的发展

    作者:民工精髓 ,发布于:2013-3-21   前端开发技术,从狭义的定义来看,是指围绕HTML.JavaScript.CSS这样一套体系的开发技术,它的运行宿主是浏览器.从广义的定义来看,包括了: 专门为手持终端设计的类似WML这样的类HTML语言,类似WMLScript这样的类JavaScript语言. VML和SVG等基于XML的描述图形的语言. 从属于XML体系的XML,XPath,DTD等技术. 用于支撑后端的ASP,JSP,ASP.net,PHP,nodejs等语言或者技术

前端模板引擎arttemplate,后端模板引擎Nvelocity

It's my first blog 大家好,我叫曾岑,朋友们都叫我包子,今年21岁,湖北人,刚大学毕业,学的.net开发.去年一年,在南京工作了一年,那时候还没有拿到毕业证,找工作也是蛮难的,别人说没毕业证,也没经验,工资只能给个基础工资,不过还好,和几个朋友一起结伴去的,一起租的房子住的.在南京的工作经历就不说那么多了,至少让我看到了编程的这个世界. 今年7月份,辞掉了南京的工作,来到了深圳这个城市,重新开始找工作,运气还算不错,第二天就面试上了,第三天就正式上班了,工资待遇对于我这种新手来

JAVA模板技术

一.起源与现状: 关于Template和JSP的起源还要追述到Web开发的远古年代,那个时候的人们用CGI来开发web应用,在一个CGI程序中写HTML标签. 在这之后世界开始朝不同的方向发展:sun公司提供了类似于CGI的servlet解决方案,但是无论是CGI还是servlet都面对同一个问题:在程序里写html标签,无论如何都不是一个明智的解决方案.于是sun公司于1999年推出了JSP技术.而在另一个世界里,以PHP和ASP为代表的scriptlet页面脚本技术开始广泛应用. 不过即便如

JS之模板技术(aui / artTemplate)

artTemplate是个好东西啊,一个开源的js前端模板引擎,使用简单,渲染效率特别的高. 我经常使用这个技术来在前端动态生成新闻列表,排行榜,历史记录等需要在前端列表显示的信息. 下面是artTemplate的下载链接: https://github.com/aui/artTemplate 因为artTemplate比较简单,容易上手,项目的例子,文档又比较齐全,大家有需要可以直接参考官方文档,例子进行深入了解, 我这里就这是用简单常用的,用于快速上手的一个例子吧! 先说明,我是下载artT

前端模板与渲染方式

1 页面级的渲染 再刚有web的时候,前端与后端的交互,非常直白,浏览器端发出URL,后端返回一张拼好了的HTML串.浏览器对其进行渲染.html中可能会混有一些php(或者php中混有一些html).在服务端将数据与模板进行拼装,生成要返回浏览器端的html串. 这与我们现在做一个普通网页没什么区别.只不过现在,我们更常使用模板技术来解决前后端耦合的问题. 前端使用模板引擎,在html中写一些标签,与数据与逻辑基本无关.后端在渲染的时候,解析这些标签,生成HTML串,如smarty.其实前端与