当前位置: 首页 > news >正文

告别 DOM 的旧时代:从零重塑 Web 渲染的未来

引言

浏览器这玩意儿现在真够诡异的。WebAssembly 在服务器端混得风生水起,但客户端还是那副老样子,跟十年前没啥区别。

WASM 粉会跟你吹,通过点 JS 胶水代码就能调原生 Web API。但核心问题是:为啥非得用 DOM?这东西就是个默认选项罢了。本文直击 DOM 和相关 API 的痛点,为什么该让它们退场了,顺便脑洞下怎么改进。

作者不是浏览器全栈专家——没人能全懂了,这正是症结所在:东西太杂太乱

DOM 的“文档”模型:臃肿得像个大胖子

DOM 烂到什么程度?Chrome 里document.body有 350+个键值,大致分类:

  • 节点操作:appendChild、removeChild之类的。
  • 样式相关:style对象塞了 660 个 CSS 属性。
  • 事件处理:那些过气的onevent属性,比如onclick,基本没人用了。
  • 杂七杂八:innerHTML、className等。

属性和方法界限模糊,很多 getter 会偷偷触发重排,setter 藏在暗处。还有一堆历史遗毒。

DOM 不瘦身,还在发福。你是否感受到这痛苦,取决于你是搞静态页还是 Web App。作为开发者,我们大多避开直接操 DOM,转而用框架。但偶尔有纯 DOM 党吹它牛逼——纯属自欺欺人。DOM 的声明式功能,比如innerHTML,跟现代 UI 模式八竿子打不着。同一件事 DOM 有 N 种方式,全都不优雅。

Web Components 的尴尬处境

Web Components 是浏览器原生组件方案,但来得太晚,人气不高。API 设计笨重,Shadow DOM 加了层嵌套和作用域,调试起来头大。粉丝的辩护听着像在找借口。以下是一个简单的示例:

class HelloWorld extends HTMLElement {connectedCallback() {const shadow = this.attachShadow({ mode: 'closed' });const template = document.getElementById('hello-world').content.cloneNode(true);const hwMsg = `Hello ${this.getAttribute('name')}`;Array.from(template.querySelectorAll('.hw-text')).forEach(n => n.textContent = hwMsg);shadow.append(template);}
}
customElements.define('hello-world', HelloWorld);

看起来还行?但实际开发中,Shadow DOM 的复杂性和 DOM 的字符串化特性(stringly typed)让开发者头疼。相比之下,React、Vue 等框架的虚拟 DOM 完全避开了这些问题,因为它们的语法只是“长得像 XML”,而不是真的依赖 DOM。

HTML 的停滞不前

HTML10-15 年没大动静。ARIA 是亮点,但只是补语义 HTML 的漏。语义 HTML 从 2011 年就开始推,但到现在都没<thread>或<comment>标签。嵌套<article>来模拟评论?指导原则也奇葩。

HTML 总像在嫉妒纸媒,没能真正拥抱超文本本质,也不信开发者能守规矩。

WHATWG(浏览器厂商)接管后,没啥愿景,就在边边角角加补丁。CSS 甚至长出了表达式——每个模板语言都想变编程语言。

编辑 HTML?contentEditable理论上行,但实际搞成可用编辑器是黑魔法。Google Docs 和 Notion 的工程师肯定有吐不完的槽。

渐进增强、 markup/style 分离?做 App 的开发者早不信这套了。

现在 App 大多用 HTML/CSS/SVG 拼凑 UI,但开销巨大,越来越不像正经 UI 工具箱。

比如 Slack 的输入框:用一堆 div 模拟富文本。剪贴板 hack 用隐藏元素。列表/表格得手动虚拟化,自管布局、重绘、拖拽。聊天窗滚动条粘底每次都得重写。虚拟化越深,越得重造页面搜索、右键菜单等。

Web 混淆了 UI 和流式内容,当年新鲜,现在过时。UI 陈旧,内容同质化。

CSS 的“内外倒挂”:别用错心智模型

CSS 口碑一般,但问题在哪?很多人误以为它是约束求解器。看这例子:

<div><div style="height: 50%">...</div><div style="height: 50%">...</div>
</div>
<div><div style="height: 100%">...</div><div style="height: 100%">...</div>
</div>

第一个想分一半高?第二个自相矛盾?实际 CSS 忽略height,父元素收缩包裹内容。

CSS 是两趟约束:先外到内传尺寸,再内到外集内容大小。App 布局外到内:分空间,内容不影响面板大小。文档内到外:段落撑开父级。

CSS 默认内到外,文档导向。要外到内,得手动传约束,从body { height: 100%; }开始。这就是垂直对齐难的原因。

Flexbox 给显式控制:

用flex-grow/shrink做无溢出自适应布局,加 gap 间距。

但 Flex 混淆了简单模型:需先“猜测”子自然尺寸,布局两次——一次假设浮空,一次调整。递归深了可能爆栈,虽少见,但大内容一丢,一切变形。

避坑:用contain: size隔离,或手动设flex-basis。

CSS 有contain、will-change这类直击布局的,暴露底层层级本质。代替position: absolute包裹。

本质上,这些切断 DOM 全局约束流——默认太宽泛,太文档化

CSS 的好地方?

Flexbox 懂了这些坑,还挺靠谱。嵌套行列+gap,直观适配尺寸。CSS 好部分在这,但得用心打磨。Grid 类似,但语法太 CSS 味儿,啰嗦。

从零设计布局,不会这样:不会用减法 API 加屏障提示。会拆成组件,用外/内容器+放置模型,按需组合。

inline-block/inline-flex示意:内部 block/flex,外部 inline。盒模型两正交面。

文本/字体样式是特例:继承如font-size,为<b>工作。但 660 属性大多不继承——边框不递归子级,那会傻。

CSS 至少两东西混搭:继承的富文本样式系统 + 非继承的嵌套布局系统。用同语法/API 是错。

em相对缩放过时,现在逻辑/设备像素更 sane。

SVG 无缝入 DOM,动态形状/图标调色。但 SVG 非 CSS 子/超集,重叠处微差,如transform。坐标字符串化,烦。

CSS 加圆角/渐变/剪裁,有 SVG 嫉妒,但远不及。SVG 做多边 hit-testing,CSS 不行。SVG 有自己图形效果。

选 HTML/CSS 还是 SVG?基于具体 trade-off,全是向量后端。

注意一下的坑:

  • text-ellipsis只截单行文本,非段落。检测/测量文本 API 烂,大家数字母凑合。
  • position: sticky零抖动滚动固定,但有 bug。无条件 sticky 需荒谬嵌套,本该简单。
  • z-index绝对层级战,z-index-war.css 里 +1/-1 比拼。无相对 Z 概念。

API 设计难,得迭代建真东西,找漏。

SVG 与 CSS 的权衡

SVG 在 Web 中用于动态生成图形或调整图标样式,但它与 CSS 并非完全兼容。例如,SVG 的 transform 与 CSS 的变换属性有微妙差异,且 SVG 的坐标全是字符串序列化,增加了开发复杂性。

国内场景:假设你在开发一个数据可视化仪表盘,类似 ECharts 的柱状图。你可以选择用 SVG 绘制图形,或者用 CSS 实现类似效果。SVG 支持多边形点击检测(hit-testing),而 CSS 不行;但 CSS 的圆角、渐变等功能又让 SVG 显得多余。最终,你可能需要在两者间做痛苦的权衡

Canvas 上的油画:HTML in Canvas 的坑

DOM 坏,CSS 几成好,SVG 丑但必备……没人修?

诊断:中间层不合用。HTML6 先砍东西起步。

但关键解放现有功能。理想:用户空间 API 同逃生口,狗食自家。

HTML in Canvas 提案:画 HTML 到<canvas>,控视觉。不是好法。

API 形因塞 DOM:元素须 canvas 后代参与布局/样式/无障碍。离屏用有“技术关切”。

例子:旋转立方体交互用 hit 矩形+paint 事件。新 hit API,但只 2D——3D 纯装饰?问题多。

从零设计,不会这样!尤其浏览器有 CSS 3D transform,何须为自定义渲染全接交互?

未覆盖用例如曲面投影,需复杂 hit。想过下拉菜单吗?

像没法统 CSS/SVG 滤镜,或加 CSS shader。经 canvas 是剩选项。“至少可编程”?截 DOM 一好用,但非卖点。

Canvas 上复杂 UI 是为绕 DOM:虚拟化、JIT 布局/样式、效果、手势/hit 等。全低级。预备 DOM 内容反生产。

反应性上,路由回同树设循环。渲染 DOM 的 canvas 非文档元素了。

Canvas 真痛:无系统字体/文本布局/UI 工具。从零实现 Unicode 分词,就为包裹文本。

提案“DOM 黑箱内容”,但知套路:还得 CSS/SVG 拼凑。text-ellipsis仍破,得从 90 年代 UI 重造。

全或无,要中道。下层需开。

未来的方向:重新设计 DOM

DOM 和 CSS 的问题根源在于它们背负了太多的历史包袱。以下是一些可能的改进方向:

  1. 精简的数据模型:未来的 DOM 需要大幅减少属性数量(从 350+精简到几十个),专注于核心功能。类似 React 的虚拟 DOM,但直接内置于浏览器中。在开发类似头条的信息流应用时,开发者需要快速渲染大量卡片。精简的 DOM 模型可以减少不必要的 API 调用,提高性能。
  2. 统一的布局系统:将 CSS 的内外布局模式明确分开,支持更直观的“外部约束”和“内部自适应”。例如,垂直居中应该像 align-items: center 一样简单。在电商平台的商品详情页中,开发者希望轻松实现复杂的布局(例如商品图片和描述的动态对齐),而不是依赖一堆 CSS hack。
  3. WebGPU 的潜力:WebGPU 提供了更底层的渲染能力,可以完全抛弃 DOM 的复杂性。例如,Use.GPU 项目展示了一个基于 WebGPU 的简洁布局系统,代码量仅为传统 DOM/CSS 的几分之一。在开发类似 B 站的弹幕播放器时,WebGPU 可以用来高效渲染动态弹幕,省去 DOM 的性能开销。
  4. 多线程与隔离:现代浏览器已经是多进程架构,但 DOM 的设计没有跟上。未来的 DOM 需要支持更好的多线程和跨源隔离,适应复杂的 Web 应用需求。在企业级应用(如钉钉的协作平台)中,开发者需要集成第三方服务(如 OAuth 登录)。一个支持多线程的 DOM 可以显著提高安全性和性能。

结论

HTML、CSS 和 DOM 的现状就像一辆老旧的马车,虽然还能跑,但早已不适合现代 Web 应用的复杂需求。国内开发者在开发小程序、电商平台或社交应用时,常常需要用框架和 hack 来弥补 DOM 的不足。未来的 Web 需要一个更精简、更灵活的渲染模型,可能基于 WebGPU 或全新的 API 设计。

与其修补 DOM 的漏洞,不如从第一性原理出发,重新设计一个适合现代应用的 Web 渲染层。就像当年的 Netscape 开启了 Web 时代,今天的我们也有机会重新定义浏览器的未来。

http://www.lryc.cn/news/624823.html

相关文章:

  • scikit-learn/sklearn学习|弹性网络ElasticNet解读
  • LINUX 818 shell:random;for for
  • 咨询进阶——解读咨询顾问技能模型
  • 2025 年世界职业院校技能大赛汽车制造与维修赛道高职组资讯整合
  • Unity开发中的浅拷贝与深拷贝
  • 做一个答题pk小程序多少钱?
  • Golang資源分享
  • USB基础 -- 字符串描述符 (String Descriptor) 系统整理文档
  • C++中内存池(Memory Pool)详解和完整示例
  • Mongodb(文档数据库)的安装与使用(文档的增删改查)
  • 可实时交互的AI生成世界,腾讯发布的AI框架Yan
  • 对象存储 COS 端到端质量系列 —— 终端网络诊断工具
  • EMC PCB 设计规范
  • 上汽通用牵手Momenta,别克至境L7全球首发搭载R6飞轮大模型
  • 用随机森林填补缺失值:原理、实现与实战
  • 深度学习必然用到的概率知识
  • 94、23种设计模式之工厂方法模式
  • Redis--day8--黑马点评--分布式锁(一)
  • 单片机驱动LCD显示模块LM6029BCW
  • 机器学习-决策树:从原理到实战的机器学习入门指南
  • LLM - windows下的Dify离线部署:从镜像打包到无网环境部署(亲测)
  • VectorDB+FastGPT一站式构建:智能知识库与企业级对话系统实战
  • 【Python 小工具】一键把源表 INSERT SQL 转换成目标表 INSERT SQL
  • 华为认证 HCIA/HCIP/HCIE 全面解析(2025 版)
  • Next.js 性能优化:打造更快的应用
  • docker——docker执行roslaunch显示错误
  • Harmonyos之字体设置功能
  • Java任务执行队列的优化
  • 王树森深度强化学习DRL(三)围棋AlphaGo+蒙特卡洛
  • 《Python学习之第三方库:开启无限可能》