博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ClosureTemplates(1-2):从Yaya说起
阅读量:4921 次
发布时间:2019-06-11

本文共 2951 字,大约阅读时间需要 9 分钟。

YayaTemplate

记得8个月前,我第一次在百度UED的网站上看到一篇关于前端模版的介绍。第一次并未一下就被吸引过去,而是辗转几日在项目前端复杂度逐渐增加的一个偶然机会,让我想起了一周前看到的“前端模版”这4个字眼。

那篇Blog上介绍的正是YayaTemplate这个由贵大师兄@ 所创作的优秀模版引擎,于是也会以它作为模版引擎的主要介绍对象。

yayaTemplate的github源码: 

yaya等许多模版系统其核心思想即:先向引擎传入模版字符串,然后yaya通过String.prototype.replace,转换为javascript编译器可以识别代码,利用Function将字符串转换为function对象的能力,将生成的匿名函数作为该编译过程的返回值。

作为一个轻量级的前端模版系统,以其不亚于artTemplate的速度上yaya做得相当出色,并且其源代码也足够轻,添加了注释的源代码也才122行。

具体的代码可能要等到翻译部分完成后,才能向大家贡献了,不过我想在这里提出我对于模版系统的至今不解的疑惑,或许是我自身的思考过程:

 

几个疑惑

1、最大的疑惑来自于Function,Function/setTimeout/eval等都具有根据字符串来执行js代码的能力,不过也带来了相当层度的性能问题(调试上由@糖饼哥哥 的artTemplate已得到了解决方案)。我在想是否可以通过向浏览器中添加script标签的方式来动态执行代码呢?下面的代码是我从Closure Library中的base.js摘录的:

其实这段代码来自于KIQ.js,是我对Google Library做了些许的改动。

/* customized EVAL method[by Google Closure Library] */kiQ.globalEval = function (script) {    if (kiQ.global.execScript) {        kiQ.global.execScript(script);    } else if (kiQ.global.eval) {        if (kiQ.evalWorksForGlobals_ == null) {            kiQ.global.eval("this.__test__=1;");            if (typeof kiQ.global["__test__"] !== "undefined") {                delete kiQ.global["__test__"];                kiQ.evalWorksForGlobals_ = true;            } else {                kiQ.evalWorksForGlobals_ = false;            }        }                             if (kiQ.evalWorksForGlobals_) {            kiQ.global.eval(script);        } else {            var doc = kiQ.global.document;            var scriptElem = doc.createElement('script');            scriptElem.type = 'text/javascript';            scriptElem.defer = false;            scriptElem.appendChild(                doc.createTextNode(script)            );            doc.body.appendChild(scriptElem);            doc.body.removeChild(scriptElem);        }                         } else {        kiQ.error("KIQ.globalEval not available");    }}

不过大致思路没有多少出入,19-27行即我上面提到的通过通过嵌入script的方式来执行Javascript脚本,需要注意的是在IE/Opera浏览器下,如果把23-25行改成scriptElem.innerHTML=script,将会报错,因此closure巧妙地用TextNode的方式来向script中填充js代码。

不过即使是Google,也是将这种方法作为eval不被ES环境支持的情况下的备选方案,现在的我所能想到这么做的原因即是:对于作用域的控制,eval上提供了很明确的用法,不过使用后者,我也能通过将要执行的js代码包装在一个function表达式中,然后向function传递作用域。不过对于此,我准备在翻译完Closure对模版系统有更深了解之后,写一个性能比对的测试再下定论。

2、这应该不算疑问了,算是领悟,与上一个问题紧密度很高,在上一篇做动静模版性能比对时,我将动态模版的性能消耗算在了编译期,现在仍然是编译期,不过涵盖了Function/eval函数,这也使得第一个问题最后提到的性能比对更加重要。

3、关于缓存,上面所提到的两个模版系统都提供缓存,但他们的缓存都是基于一个返回字符串的函数,而非一个灵活的DocumentFragment对象。我想说的是,如果在预编译时就将DOM生成的DOM节点转换为一个DocumentFragment的话,不是可以省去很多模版么?比如有时候我们仅仅需要改写一个ul中每个li的一个小元素,要么是将这个需要修改的节点作为参数,写入,要么是新建第一个模版。

还有更好的办法么?答案是有的,将这个模版生成的字符串转换为DocumentFragment,存储在一个Js对象中,在需要时更改,然后插入就行了。

不过为何我们不直接将其直接加入到系统的缓存中呢,直接返回DocumentFragment,也许性能上没有那么大的提升,但DOM在操作XML时永远比String要直观,不是吗?

这三个问题所提供得优化方法,都将在翻译完Closure的相关文档后,加入到我KIQ.js的动态模版库中,也会做出一系列性能比对第一时间分享给大家。

后记:很多时候真的身不由己,上一篇后记说是要在这篇写一些源码分析,不过看完yayaTemplate和artTemplate源码后,感觉我还没有能力在一个时间内将别人优秀的作品做一个现场解剖,不过提提意见总是可以的吧,这不就是"开源"的思想吗!好了,问题已经抛出来了,下周开始正式的翻译工作,相对于原创,会是比较简单的工作了吧。亲们,下周三见咯!

转载于:https://www.cnblogs.com/Mr-Jquery/articles/2795147.html

你可能感兴趣的文章
Android开发EditText属性
查看>>
String StringBuffer StringBuilder
查看>>
ZBrush中Flatten展平笔刷介绍
查看>>
深度学习的代码框架
查看>>
2017年06月30号课堂笔记
查看>>
浏览器兼容问题
查看>>
实时的.NET程序错误监控产品Exceptionless开源了
查看>>
PAT 甲级 1104 sum of Number Segments
查看>>
oracle表空间创建与用户授权
查看>>
使用用Generic.xaml加载默认的主题资源
查看>>
JavaScript高级编程——Array数组迭代(every()、filter()、foreach()、map()、some(),归并(reduce() 和reduceRight() ))...
查看>>
poj 3070 Fibonacci 矩阵快速幂
查看>>
网桥知识点学习
查看>>
Android动态改变工程依赖
查看>>
for循环变量声明为 final
查看>>
对法拉奇的看法
查看>>
linux3.4.2之DMA驱动完整程序
查看>>
AC自动机(转载)
查看>>
用IrisSkin2.dll美化你的WinForm --zt
查看>>
[leetcode](4.21)3. 最长重复子串
查看>>