Skip to content

Commit

Permalink
Update Code
Browse files Browse the repository at this point in the history
  • Loading branch information
pipe.zkk committed Jan 12, 2024
1 parent ad60511 commit 9a8f958
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 182 deletions.
1 change: 1 addition & 0 deletions _posts/2023-10~12/2023-12-19-virtualdom.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ date: 2023-12-20
tags: [note]
---

维护 DOM 已成 WebApp 时代最大的挑战。

* 背景:是从一开始的静态页面,发展到了 WebApp
* Web Application:WebApp 所遇到的问题和挑战
Expand Down
97 changes: 0 additions & 97 deletions _posts/2023-10~12/2023-12-30-virtualdom-2.md

This file was deleted.

117 changes: 117 additions & 0 deletions _posts/2024-01~03/2024-01-10-virtualdom-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
layout: post
title: "再谈 Virtual DOM(二)"
date: 2024-01-10
tags: [note]
---


如何编写 DOM?

* [再谈 Virtual DOM(一)](https://zhoukekestar.github.io/notes/2023/12/20/virtualdom.html)
* [再谈 Virtual DOM(二)](https://zhoukekestar.github.io/notes/2023/12/30/virtualdom-2.html)


# 编写 DOM:HTML 的进化

### 原生时代

最早的 Web 开发,是以 HTML 为基础的。

随着后续动态技术的兴起,动态页面也逐渐流行起来。

### 模板语言时代

在早期的 Web 开发中,模板语言是最常用的一种技术。但由于没有规定其动态生成的规范,导致各自语言体系中,有各自的模板规范。比如:Java、C#、JS、PHP 等等。

以下是一些常见的模板语言:

JavaScript Template Engine

* [mustache](https://github.com/janl/mustache.js)

![](https://cloud.githubusercontent.com/assets/288977/8779228/a3cf700e-2f02-11e5-869a-300312fb7a00.gif)

* [handlebars](https://handlebarsjs.com/zh/)

```html
<h2>Names</h2>
{{#names}}
<strong>{{name}}</strong>
{{/names}}
```

ServerSide Template Engine

* ASP.NET

```html
@foreach (var person in members)
{
<p>@person</p>
}
```

* JSP (Java Server Pages) & JSTL ( JSP Standard Tag Library)

![image](https://github.com/zhoukekestar/notes/assets/7157346/3f8295b2-a0e2-4758-8cf7-86890ac641bd)

```html
<c:forEach items="${requestScope.empList}" var="emp">
<tr>
<td><c:out value="${emp.id}"></c:out></td>
<td><c:out value="${emp.name}"></c:out></td>
<td><c:out value="${emp.role}"></c:out></td>
</tr>
</c:forEach>
```
* [art-template](https://aui.github.io/art-template/)

```html
<% for(var i = 0; i < target.length; i++){ %>
<%= i %> <%= target[i] %>
<% } %>
```

* [Velocity](https://velocity.apache.org/engine/1.7/user-guide.html)

```html
<table>
#foreach( $mud in $mudsOnSpecial )
#if ( $customer.hasPurchased($mud) )
<tr>
<td>
$flogger.getPromo( $mud )
</td>
</tr>
#end
#end
</table>
```

### JSX

随着 React 的崛起,框架侧引入了新的 JSX 语法,力求将模板语言的语法统一起来。

因为页面大部分是前端的领域,而且随着 [前后端分离](https://www.google.com.hk/search?q=frontend+backend+separate) 的兴起,此方式受到了广泛的欢迎。

但本质上,JSX 已不再是模板语言,而是 JS 代码。所以,灵活性和模板语言已不可同日而语,其灵活性所带来的问题,也导致其优化的上限。

* [facebook/jsx](https://github.com/facebook/jsx)

### Template Literals & Tagged templates

```js
// Template Literals
`Hello ${name}`

// Tagged templates
html`
<div>
<h1>Hello ${name}</h1>
</div>`
```

* [tagged_templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates)
* [ecmascript-language-lexical-grammar](https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#sec-template-literal-lexical-components)

137 changes: 62 additions & 75 deletions _posts/2024-01~03/2024-01-10-virtualdom-3.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,97 @@
---
layout: post
title: "再谈 Virtual DOM(三)"
date: 2024-01-10
date: 2023-12-30
tags: [note]
---

解决维护 DOM 问题的各种方案。
接上次 [再谈 Virtual DOM(一)](https://zhoukekestar.github.io/notes/2023/12/20/virtualdom.html)

接上次
* [再谈 Virtual DOM(一)](https://zhoukekestar.github.io/notes/2023/12/20/virtualdom.html)
* [再谈 Virtual DOM(二)](https://zhoukekestar.github.io/notes/2023/12/30/virtualdom-2.html)
* 背景:是从一开始的静态页面,发展到了 WebApp
* Web Application:WebApp 所遇到的问题和挑战
* 维护 DOM:是最大的挑战之一
* 更新 DOM:方案与优劣
* 编写 DOM:HTML 的进化


# 编写 DOM:HTML 的进化
# 更新 DOM

### 模板语言时代
现代框架的主要工作之一,便是维护、更新 DOM,所以,不同的框架便有了不同的实现。VirtualDOM 只是其中之一。

在早期的 Web 开发中,模板语言是最常用的一种技术。但由于没有规定其动态生成的规范,导致各自语言体系中,有各自的模板规范。比如:Java、C#、JS、PHP 等等。
以下是现有主流框架对于更新 DOM 的不同实现:

以下是一些常见的模板语言:
### Virtual DOM (Facebook)

JavaScript Template Engine
此处挖坑

* [mustache](https://github.com/janl/mustache.js)
### Incremental DOM (Google)

![](https://cloud.githubusercontent.com/assets/288977/8779228/a3cf700e-2f02-11e5-869a-300312fb7a00.gif)
通过 `elementOpen`, `elementClose` 等函数,在真实 DOM 上做移动(比如 open 就进入子节点,close 就出子节点等等)、对比(tagname、属性是否相同等等)、标记(用于创建新节点、删除没有访问到的节点等等),将每次的 render 后的代码指令(就是 render 函数本身),通过 patch 做一步一步的执行,最终维护 DOM 的更新。

* [handlebars](https://handlebarsjs.com/zh/)
此方案的优势,就是节省内存(相比 VDOM,基本没有额外的大内存开销),劣势是每次都要比对(相比 Lit),且无法有效复用节点,可以查看 [此视频](https://github.com/zhoukekestar/toy-lit-html/tree/main/idom)

```html
<h2>Names</h2>
{{#names}}
<strong>{{name}}</strong>
{{/names}}
```
```js
var data = {
text: 'Hello World!',
someCondition: true
};

function render(data) {
elementVoid('input', '', [ 'type', 'text' ]);
elementOpen('div', '', null);
if (data.someCondition) {
text(data.text);
}
elementClose('div');
}

ServerSide Template Engine
patch(document.body, function() {
render(data);
});

* ASP.NET
```

```html
@foreach (var person in members)
{
<p>@person</p>
}
```
* https://github.com/google/incremental-dom
* https://auth0.com/blog/incremental-dom/
* https://github.com/zhoukekestar/toy-lit-html/tree/main/idom
* https://www.reddit.com/r/Angular2/comments/8ytfc1/reacts_virtual_dom_vs_angulars_change_detection/

* JSP (Java Server Pages) & JSTL ( JSP Standard Tag Library)

![image](https://github.com/zhoukekestar/notes/assets/7157346/3f8295b2-a0e2-4758-8cf7-86890ac641bd)
### Lit DOM (Google)

```html
<c:forEach items="${requestScope.empList}" var="emp">
<tr>
<td><c:out value="${emp.id}"></c:out></td>
<td><c:out value="${emp.name}"></c:out></td>
<td><c:out value="${emp.role}"></c:out></td>
</tr>
</c:forEach>
```
* [art-template](https://aui.github.io/art-template/)
Lit 的 DOM 维护,在目前这个时间点,个人看来是最优的,也是个人近期项目用的最多的方式。Demo 如下:

```html
<% for(var i = 0; i < target.length; i++){ %>
<%= i %> <%= target[i] %>
<% } %>
```
```js
import { html, render } from './lit.js';

const helloTemplate = (name1, name2) => html`
<div>hi ${name1} !</div>
<div>hello ${name2} ?</div>
`

* [Velocity](https://velocity.apache.org/engine/1.7/user-guide.html)

```html
<table>
#foreach( $mud in $mudsOnSpecial )
#if ( $customer.hasPurchased($mud) )
<tr>
<td>
$flogger.getPromo( $mud )
</td>
</tr>
#end
#end
</table>
render(helloTemplate('foo', 'bar'), document.body)
```

### JSX
Lit 总体上看,和 Chrome 浏览器(或者说是标准浏览器接口)做了非常多的复用,使得整体框架非常的简约、优雅。

随着 React 的崛起,框架侧引入了新的 JSX 语法,力求将模板语言的语法统一起来。
* 首先是使用 `Template Literals` 创建模板(strings、values)
* [Tagged Templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates)
* 通过 `<template>` 创建并解析生成 DOM
* 然后使用 `document.createTreeWalker` 的 walker 遍历一次 template 中的变量
* `document.importNode` 到渲染容器中,绑定 template 中的变量(引用并放置到数组中),并做实时的更新
* 后续的所有更新,直接拿 `Tagged Templates` 的 values 数组,即可做到索引级的更新
* 无需对比 diff、无需 patch、无额外高内存消耗

因为页面大部分是前端的领域,而且随着 [前后端分离](https://www.google.com.hk/search?q=frontend+backend+separate) 的兴起,此方式受到了广泛的欢迎
可以查看一下 [toy-lit-html](https://github.com/zhoukekestar/toy-lit-html) 源码,查看 Demo 的运行逻辑

但本质上,JSX 已不再是模板语言,而是 JS 代码。所以,灵活性和模板语言已不可同日而语,其灵活性所带来的问题,也导致其优化的上限。
* https://zhoukekestar.github.io/notes/2023/12/24/lit-html-flow.html
* https://github.com/zhoukekestar/toy-lit-html
* https://lit.dev/docs/templates/overview/

* [facebook/jsx](https://github.com/facebook/jsx)

### Template Literals & Tagged templates

```js
// Template Literals
`Hello ${name}`

// Tagged templates
html`
<div>
<h1>Hello ${name}</h1>
</div>`
```
### 其他

* [tagged_templates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates)
* [ecmascript-language-lexical-grammar](https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#sec-template-literal-lexical-components)
[Ember Glimmer](https://zhoukekestar.github.io/notes/2024/01/09/ember-glimmer.html)

Loading

0 comments on commit 9a8f958

Please sign in to comment.