阅读 169

拒绝虚拟dom!lit-html模板原理探索

前言

lite-html模板是简单的JavaScript,它结合了编写HTML的熟悉程度和JavaScript的强大功能。lite-html负责高效地将模板呈现给DOM,包括高效地用新值更新DOM。

这是从readme里复制出来,然后有道翻译了一下。因为lit就是使用lit-html来写的,所以花了一定时间去阅读了源码,看看大佬们是怎么实现这个模板语言的。

开始

模板字符串知识

模板字符串作为es6较为常用的功能,相信大家都不陌生。但是平时使用的时候,可能就是为了书写方便,把变量用${}包起来直接书写。但是其实,它还有分割变量和字符串的功能。

image.png

从控制台输入这段代码,可以发现,使用简单的tag函数,就能将模板中的字符串和变量分离出来。

由此可以看出,模板字符串中是内置了这些属性的。因此同一个模板字符串分离出来的的strings数组对象肯定是相等的,这就是后面会说到的lit-html用来缓存模板信息的原理。

image.png

简单示例分析

 const a = 'aaaa'; const b = 'bbbb'; const c = 111; const t = (name) => html`<div id="div" ${b}="222" data-name="111" .obj=${c} title="111${b}222">     <!--name${name}-->     ${name}${name}     <span obj=${c}>${a}</span>     <input id="ipt" type="text" .value=${c}>     <script>         console.log(1111)         ${a}         console.log(2222)         ${a}         console.log(3333)     </script> </div>`; const values =  t('dd'); render(values, document.body); 复制代码

这段模板中包含了lit-html中的一些简单应用。

lit-html 中的 render

在把模板字符串的信息传入到render函数中后,首先它会把strings重新拼接,并把变量的位置,用lit-html生成的随机字符串替换出来。

image.png

接着,再把变量相关的Attr从模板中分离出来。区分出不同的type,推入到parts的数组中,在后面根据不同的type用对应的函数对元素上的属性进行操作。index对应的则是node的下标。

image.png

到这一步可以说是已经将所有静态的元素模板分离出来了。

剩下要做的就是循环parts数组,将他们中的part和最开始模板字符串中values相组合,然后修改元素的内容和attrs就可以。

image.png

其实这个思想和vue3中很相似,把静态的dom看成常量,只分离出那些需要变更的那些元素,然后进行更新。

缓存

缓存是肯定要做的。但是理解了上面的做法之后,其实就很好理解。所有模板相关的内容都可以缓存下来,在需要渲染时候,调用_update(values)更新dom就可以了。

可以看看代码中是怎么做缓存的。

image.png

首先会在,父级元素中保存一份childPart的实例。控制台中打印一下也能看到。

image.png

其次,在模板实例的储存上,

image.png

因为只有同一个模板字符串的strings是相同,所以跟template实例也是一一对应的,可以放心的存入cache中,在更新时候读取。

image.png

最后,如果template实例,和上次templateInstance中的template实例相同时,可以说明是同一个模板,只需要调用_update(values)就可以实现dom的更新了,和开头说的一样。

结语

其实忽略了很多中间转化过程中的代码,包括怎么标记变量的位置,怎么将不同typepart转换成dom中所需要的样子,只讲了大致的思路和实现方法。有兴趣的大哥们可以去看下源码,就1000多行,也不是很长。

其实对我来说,最大的收获是学会了模板字符串的新用法和使用document.createTreeWalker遍历node元素的方法,和这种分离出静态常量和变量,从而对指定内容进行更新的思路和方法。

lit-element实际上就是对web-components各种生命周期的重新封装和扩展,应该不会专门再水一篇文章进行分析了。空的话还是继续写一写组件,毕竟已经一个多月没写了。人类果然无法战胜懒惰=-。


作者:懒狗小前端
链接:https://juejin.cn/post/7056291294397759519


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐