再谈前端HTML模板技术
在web2.0此前,写jsp的时候虽然有es和JSTL,但是还是坚持jsp。后面在外包公司为了快速交货,还是用了php Smart技术。
web2.0后,前端模板技术流行。
代表有如下三大类:
String-based模板技术(基于字符串的parse和compile历程)
DOM-based模板技术(基于Dom的link或compile历程)
Living template (基于字符串的parse 和 基于dom的compile历程)
String-based templating
这是一种基于字符串的模板技术,以字符串和数据为输入,通过用正则表达式将占位符更换为所需数据的方式,构建出完全的 HTML 字符串。
字符串模板引擎主要依靠一下这几个dom API:createElement,appendChild,innerHTML。
在这些api中,innerHTML有最好的可读性与有用性,成为事实上的主要标准,虽然其他API大概在机能上更胜一筹,但原生js的字符串生成方案中,最常用的还是innerHTML。
基于字符串的模板引擎最大的功绩就是把你从大量的夹带逻辑的字符串拼接中解放出来了,由于它的完全基于字符串的特性,它具有一些无可替换的优势。
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.
快速的初始化时间: 许多angular的簇拥者在奚落String-based templating好像漏掉了这一点。
同构性: 完全的dom-independent,即可作为用效劳器端和阅读器端(客官先不要急着搬phantomjs哈).
更强大的语法支撑:由于它们都是不是自建DSL就是基于JavaScript语法,Parser的灵敏性与受限于HTML的Dom-based模板技术不成等量齐观
由于基于字符串的模板办法依靠于innerHTML的渲染,所以会带来以下问题。
平安问题:使用innerHTML 构建 DOM具有平安隐患,用于渲染的动态数据大概存在平安破绽,假如没有经过特定的转义处置,就有大概造成 XSS攻击或者 CSRF攻击。
由于innerHTML具有平安隐患.,例如:,我知道像你这样优异的程序员不会写出这样的代码,但当html片段不完全由你来操纵时(比方从长途效劳器中),这会成为一个大概引爆的*。
机能问题:使用innerHTML 更换 DOM效力较低,即便仅更换 DOM 的一个属性或文本内容,也必需通过innerHTML 更换整个 DOM,从而致使阅读器的重排和重绘。
开发效力问题:由于是通过正则表达式匹配后在特定函数中拼接字符串,所以容易造成反复运算,并且完全移除现有的 DOM,再从新渲染一遍,挂载在 DOM 上的事件和状态都将不复存
有大概会创立出料想之外的节点:由于html的parser非常的“友好”, 以至于它接受并不标准的写法,从而创立出料想之外的构造,而开发者得不到错误提醒。
代表:
mustache及其衍生handlebar等: 弱逻辑
Dust.js: 强逻辑 (引荐)
doT.js: 超级快
DOM-based模板技术
这是一种基于 DOM 节点的模板技术,通过innerHTML猎取初始 DOM 构造,再通过 DOM API层级从原始 DOM 属性中提取事件、指令、表达式和过滤器等信息,编译成 LivingDOM,从而完成数据 Model和 View 的双向绑定。 AngularJS就是 DOM-based模板技术的代表。
Dom-based的模板技术事实上并没有完全的parse的历程(先抛开表达式不说),假如你需要从一段字符串创立出一个view,你必定通过innerHTML来获得初始Dom构造. 然后引擎会利用Dom API(attributes,getAttribute,firstChild… etc)层级的从这个原始Dom的属性中提取指令、事件等信息,继而完成数据与View的绑定,使其”活动化”。
所以Dom-based的模板技术更像是一个数据与dom之间的“链接”和*“改写”*历程。
留意,dom-based的模板技术不必然要使用innerHTML,比方所有模板都是写在入口页面中时, 但是此时parse历程依然是阅读器所为。
DOM-based模板技术比String-based模板技术愈加灵敏,功效也愈加强大,到达了必然意义上的数据驱动。
是活动的: 完成compile之后,data与View依然保持联络,即你可以不依靠与手动操纵Dom API来更新View
是运转时高效的: 可以实现部分更新
指令等强大的附属物帮忙我们用声明式的方式开发APP
但其存在以下问题:
信息冗余:信息承载于属性中,这个其实是不必要和冗余的。
由于 DOM-based模板技术通过innerHTML 猎取 DOM 编译节点,信息承载于属性中,造成了不必要的冗余,同时也会影响阅读,晋升开发难度。一种解决方法就是通过读取属性后再停止删除处置,诸如removeAttribute的方式移除它们,其实这个不必然必要,并且其实并无解决它们Dom强依靠的特性,还会影响机能,落低会员体验。
初始节点猎取问题:通过innerHTML猎取初始节点,没有独立的语法解析器或词法解析器,与 HTML是强依靠关系。初次进入 DOM 的内容是模板,渲染需要时间,所以会造成内容闪动——FOUC(Flash of unstyled content)这个无需多说了,只怪它初次进入dom的内容并不是终究想要的内容。
没有独立的Parser,必需通过innerHTML(或首屏)猎取初始节点,即它的语法是强依靠与HTML,这也致使它有潜在的平安问题
代表:
AngularJS: 都28000star了还需多说么
Knockout: 在此领域内,对Web前端而言是鼻祖级的
Livingtemplate技术
Livingtemplate技术与String-based、DOM-based模板技术的最大不同是不依靠innerHTML来渲染和提取所需信息。其主要思想是:第一,结合数据绑定技术,使用成熟的词法解析和语法解析
技术,将输入的字符串解析成抽象语法树AST,而不是仅仅通过简便的正则表达式匹配特定语法,再停止字符串拼接;其次,通过对 AST停止编译,创立具有数据动态绑定功效的 Living DOM,从而幸免使用innerHTML,解决了阅读器的元素闪动问题,提高了利用的平安性,其道理如图1所示。
从图1可知,输入的字符串通过词法解析器Lexer,生成对应的词法块。词法块通过语法解析器 Parser,构建抽 象 语 法 树 AST。然 后 将 AST编译成具有动态数据绑定功效的LivingDOM,从而实现 View 和 Model的双向绑定。
与Dom-based 模板技术利用Dom节点承载信息所不一样的是,它的中心产物AST 承载了所有Compile历程中需要的信息(语句, 指令, 属性…等等).
我们可以发明Living templating几乎同时具有String-based和Dom-based模板技术的长处
利用一个如字符串模板的自定义DSL来描写构造来到达了语法上的灵敏性,并在Parse后承载信息(AST)。而在Compile阶段,利用AST和Dom API来完成View的组装,在组装历程中,我们一样可以引入Dom-based模板技术的诸如Directive等优秀的种子。
living template’s 近亲 —— React
React当然也可以称之为一种模板解决方案,它一样也奇妙躲避了innerHTML,不外却使用的是天壤之别的战略:react使用一种virtual dom的技术,它也一样基于脏检查,不外不同凡响的是,它的脏检查发生在view层面,即发生在virtual dom上,从而可以以较小的开销来实现部分更新。
轻量级, 在Dom中停止读写操纵是低效的.
可重用的.
可序列化, 你可以在当地或效劳器端预处置这个历程。
平安, 由于平安不需要innerHTML帮我们生成初始Dom
代表:
htmlbar: 运转在handlebar之后的二次编译
ractivejs: 独立
Regularjs独立
此文还需进一步整理,乃至自定义模板引擎思索标的目的与工程实践内容补充。这方面需要下的功夫还是需要蛮多的,敬请等待。
本文转载自原创文章:https://www.zhoulujun.cn/html/webfront/SGML/htmlBase/2018_0419_8098.html
相关引荐:
一个简便的HTML模板引擎
以上就是再谈前端HTML模板技术的具体内容,更多请关注百分百源码网其它相关文章!