Lit 架构解析:从 Web Components 到 lit-html 的底层原理

Lit(原名 lit-element + lit-html)并不是一个"对标 React/Vue 的框架",而是一套围绕 Web Components 的最小化渲染与响应式方案

它的设计目标非常明确:

用最少的运行时代码,解决组件化与高性能 DOM 更新问题

本文将从架构层面,逐步拆解:

  • Lit 在整个前端生态中的位置
  • Lit 的核心组成
  • lit-html 的模板与更新机制
  • Lit 与 React / Vue 的根本差异

一、Lit 在前端架构中的定位

1.1 Lit 解决的不是"应用",而是"组件"

对比常见框架的定位:

技术 核心目标
React / Vue 构建完整应用
Lit 构建标准 Web Components
Web Components 浏览器原生组件模型

Lit 的核心思想是:

不发明组件标准,只补齐 Web Components 的开发体验


1.2 Lit 架构全景

text 复制代码
浏览器原生能力
├── Custom Elements
├── Shadow DOM
├── HTML Template
│
Lit 提供
├── lit-html(渲染引擎)
├── 响应式系统
├── 生命周期封装
└── DX 改进(装饰器、模板语法)

Lit = Web Components + lit-html + 响应式封装


二、Lit 的整体架构拆解

2.1 核心模块组成

现代 Lit(v3+)主要由三部分构成:

text 复制代码
lit
├── ReactiveElement(响应式基础类)
├── LitElement(组件基类)
└── lit-html(模板 & 渲染引擎)

它们的职责非常清晰:

模块 职责
ReactiveElement 响应式属性、更新调度
LitElement 生命周期 + render 桥接
lit-html 高性能 DOM 渲染

2.2 继承关系

ts 复制代码
HTMLElement
  └── ReactiveElement
        └── LitElement
              └── YourComponent

Lit 没有虚拟 DOM 层,这是理解其底层原理的关键。


三、Web Components 是 Lit 的根基

3.1 Custom Elements

ts 复制代码
customElements.define('my-element', MyElement)
  • 浏览器原生注册
  • 生命周期标准化
  • 不依赖任何框架

3.2 Shadow DOM

ts 复制代码
this.attachShadow({ mode: 'open' })
  • 样式隔离
  • DOM 隔离
  • 原生封装能力

3.3 HTML Template

html 复制代码
<template>
  <p>Hello</p>
</template>
  • 惰性解析
  • 可复用
  • 浏览器级优化

Lit 大量依赖 <template> 的原生特性


四、lit-html 的核心思想

4.1 lit-html 是什么

lit-html 是 Lit 的渲染引擎,核心目标只有一个:

在不使用 Virtual DOM 的情况下,做到最小粒度 DOM 更新


4.2 模板是"静态的",数据是"动态的"

ts 复制代码
html`<p>Hello ${name}</p>`

模板会被拆分为:

text 复制代码
静态字符串数组 + 动态表达式数组

类似于:

ts 复制代码
[
  "<p>Hello ",
  "</p>"
]

4.3 TemplateResult 结构

ts 复制代码
{
  strings: TemplateStringsArray,
  values: any[]
}

模板结构在第一次渲染时就固定下来


五、lit-html 的底层渲染流程(Importance)

5.1 首次渲染流程

text 复制代码
1. 解析模板字符串
2. 生成 <template> DOM
3. 标记动态插槽(Part)
4. clone template.content
5. 插入真实 DOM

动态插槽被称为 Part


5.2 Part(更新单元)

Lit 将 DOM 中"可能变化的位置"抽象成 Part:

Part 类型 对应位置
ChildPart 文本节点 / 子节点
AttributePart 普通属性
PropertyPart DOM 属性
BooleanAttributePart 布尔属性
EventPart 事件

5.3 更新阶段(没有 Diff)

text 复制代码
状态变化
  ↓
重新执行 render()
  ↓
生成新的 values
  ↓
逐个 Part 对比并更新

关键点:

  • 不比较 DOM 树
  • 只更新"表达式对应的节点"

5.4 为什么比 Virtual DOM 快

React/Vue:

text 复制代码
state → vdom → diff → patch

lit-html:

text 复制代码
state → values → Part.update()

Lit 的更新路径更短,内存占用更小


六、Lit 的响应式系统原理

6.1 ReactiveElement 的核心机制

ts 复制代码
@property({ type: String })
name = 'lit'

底层原理:

  1. 将属性转为 getter/setter
  2. setter 触发 requestUpdate
  3. 更新被批量调度(microtask)
  4. 调用 update()render()

6.2 更新是异步批量的

text 复制代码
多次 set
  ↓
一次 render

类似 Vue 的 nextTick,但实现更轻量。


七、Lit 的生命周期设计

ts 复制代码
connectedCallback()
disconnectedCallback()
shouldUpdate()
willUpdate()
update()
updated()

特点:

  • 与 Custom Elements 生命周期对齐
  • 不引入额外概念
  • 更贴近浏览器模型

八、Lit 与 React / Vue 的根本差异

8.1 架构层面对比

维度 Lit React Vue
核心模型 Web Components VDOM VDOM + 响应式
DOM 更新 定点更新 Diff Diff
样式隔离 Shadow DOM CSS-in-JS Scoped CSS
运行时 极小 较大 中等
框架侵入 极低

8.2 Lit 的优势场景

  • 组件库(跨框架)
  • 微前端
  • Design System
  • 嵌入第三方系统
  • 对 bundle size 极敏感场景

8.3 Lit 的局限

  • 不适合复杂应用状态管理
  • 社区生态不如 React/Vue
  • 对 Web Components 理解有门槛

九、一个关键结论

Lit 并不是"下一代前端框架"
而是"更接近浏览器的组件开发方式"

它选择相信浏览器,而不是包揽一切。


十、总结

  • Lit 的架构极度克制
  • lit-html 是一个"模板驱动的定点更新引擎"
  • 没有 Virtual DOM 是它最重要的设计选择
  • Web Components 是它真正的护城河

如果你需要构建:

  • 长期维护的组件库
  • 跨技术栈 UI 组件
  • 低运行时成本的前端模块

Lit 是一个非常值得深入理解的方案。