HTML已死,HTML萬歲——重新思考DOM的底層設計理念

??每周跟蹤AI熱點新聞動向和震撼發展 想要探索生成式人工智能的前沿進展嗎?訂閱我們的簡報,深入解析最新的技術突破、實際應用案例和未來的趨勢。與全球數同行一同,從行業內部的深度分析和實用指南中受益。不要錯過這個機會,成為AI領域的領跑者。點擊訂閱,與未來同行! 訂閱:https://rengongzhineng.io/

瀏覽器的發展正處于一個奇怪的時期。盡管WebAssembly在服務器端取得了顯著成功,但客戶端的體驗在過去十年間幾乎沒有根本改變。

不少技術愛好者認為,通過WASM訪問原生Web API已經不再是難題,只需極少的JavaScript“膠水”代碼即可實現。但關鍵問題并不是“是否可以”訪問DOM,而是“為什么還要”訪問它。如今,DOM似乎成了唯一的選擇,但實際上,是時候讓DOM和它那一系列錯綜復雜的API“退休”了。

“文檔”模型的真實面貌

鮮有人真正意識到DOM有多龐雜。在Chrome中,document.body對象已包含超過350個屬性,這還不包括其style屬性中660個CSS屬性。屬性與方法的邊界模糊不清,有些屬性不過是隱藏的setter方法;一些getter方法甚至會觸發即時的頁面重排。此外,諸如onloadonmouseover等早期事件處理器仍被保留在API中,盡管幾乎無人使用。

DOM并不輕盈,反而愈加臃腫。是否能感知這一點,取決于開發者是在制作網頁,還是在開發Web應用。如今多數開發者已盡量避免直接操作DOM,雖然仍有人將“純DOM”視為優于現代JS組件框架的“正統方式”。而諸如innerHTML這樣的聲明式功能早已無法滿足現代UI開發的需求。DOM存在太多實現方式,卻沒有一種是令人滿意的。

Web Components:錯失良機的原生組件方案

Web Components本應成為Web平臺上原生組件化的標準,但其出場時機過晚,加之API設計生硬,使其難以流行。其中Shadow DOM的引入更是帶來了嵌套與作用域的復雜性,使許多開發者望而卻步。其支持者往往語氣近似辯解。

DOM的根本性問題,在于其源自SGML/XML的遺產,使得一切都變成了“字符串類型”——即所謂“stringly typed”。而React等框架雖然語法上看似XML,實際上并無此限制。如今開發者早已學會,不應把狀態保存在DOM中,因為它無法勝任。

HTML十年如一日的停滯

HTML本身的問題更是根深蒂固。在過去十至十五年中,其結構幾乎未曾改變。除了ARIA(無障礙訪問)之外,鮮有實質性進展。語義化HTML未能兌現其承諾——比如至今沒有 <thread><comment> 標簽,即使這些已成為常見內容結構。語義化規范內容模糊,令人困惑。

HTML似乎始終執著于紙質出版物的模型,遲遲不愿擁抱超文本的本質,也未能給予用戶清晰且可信的規則。HTML的管理早已從W3C轉移至WHATWG,即各大瀏覽器廠商聯盟,但他們迄今未能提供明確的未來愿景,僅在邊緣上不斷堆砌功能補丁。

CSS:結構混亂的布局系統

CSS的名聲也不甚美好,但大多數人并不能準確說出其問題所在。問題的根源在于心智模型的錯位——許多人將其視為約束求解器(constraint solver),這是誤入歧途。

例如,使用百分比高度時,開發者可能以為設置兩個50%高度的子元素,父容器就會被垂直平分。但由于CSS的布局流程是自內而外的(inside-out),在不知道父元素高度的前提下,這樣的設置往往會被忽略,或者內容溢出。這是由于CSS并不會像某些布局引擎那樣進行回溯或推理,而是“自上而下傳約束,再自下而上傳尺寸”。

在構建應用框架時需要outside-in的布局,而HTML默認偏向inside-out的文檔式布局。這就是為什么垂直對齊在CSS中“很難”。

Flexbox的權衡與代價

使用display: flex確實可以解決上述問題。它允許合理劃分空間、定義彈性增長/收縮。但這也引入了額外復雜度:每個子元素需先測量“自然尺寸”,再根據空間調整布局——這相當于布局過程要執行兩次。對于嵌套結構甚至可能引發遞歸的計算爆炸,雖然在現實中很少出現。

為避免遞歸依賴,開發者需使用如contain: sizewill-change等新CSS屬性,以阻斷DOM中流動的全局約束。這類機制透露了CSS中潛在的“分層”特性,但這些設計顯然不是從頭構建的,而更像是補丁堆疊。

DOM和CSS的原罪

在CSS中,繼承(inheritance)僅適用于少數文字樣式,如字體大小,而大多數屬性(如邊框)并不會繼承。這揭示了CSS其實融合了兩種截然不同的系統:一是基于繼承的富文本樣式系統;二是基于嵌套與包含的布局系統。兩者共用一套語法,卻行為不一致。將它們合并,注定是錯誤的。

此外,早期關于相對字體單位(如em)的設計,也已被邏輯像素與設備像素的概念取代,后者更符合用戶直覺。

SVG:強大但笨重的圖形系統

SVG作為可嵌入的矢量圖形語言,提供了強大的圖形功能,如路徑、漸變、遮罩等,甚至支持多邊形命中測試,這些CSS做不到。但SVG并非CSS的子集,也不是其超集。兩者存在許多細節差異,例如變換矩陣的處理邏輯不同。SVG擁有自己的“怪癖”,例如必須將所有坐標序列化為字符串。

SVG與CSS的融合,反而造成了API設計的混亂。在許多情況下,開發者需在HTML、CSS與SVG之間權衡取舍,盡管它們本質上都作用于同一圖形棧。

遺憾的API設計決策

Web平臺中許多功能,都因版本1的設計過于倉促而停滯不前。例如:

  • text-ellipsis 僅能處理單行文本,無法應用于段落;

  • position: sticky 實用但常常出現詭異行為;

  • z-index 缺乏相對層級控制,造成混亂的“+1/-1”戰爭。

這些問題反映出早期API設計中缺乏對長期演進的思考,而后續也未能通過模塊化與可組合的方式解決。

Canvas:一個笨拙的“重繪”出口

近年來出現的“HTML in Canvas”提案,試圖將HTML內容繪制到Canvas中,以獲得完全的視覺控制。然而,這種方式本質上是將DOM強行嵌入Canvas中,為了保留布局與可訪問性,最終反而限制了用途。

例如,若要繪制一個旋轉立方體,開發者需手動綁定命中檢測區域,并響應繪制事件。這種做法無法支持3D交互,僅能提供2D層面點擊檢測。更為關鍵的是:開發者必須接管元素所有交互責任,只為自定義其渲染方式。

這種Canvas方案,看似“可編程”,實則不過是無奈之舉。當開發者想要在UI中實現DOM無法提供的功能(如內容虛擬化、定制交互、特殊視覺效果),卻又不得不借助笨拙的Canvas與DOM組合,這無疑是對系統架構的一種拷問。

真正的出路:向下開放底層能力

Canvas并非無解,但它缺乏對系統字體、文本排版API與UI工具的原生支持。開發者甚至需自行實現斷詞、換行與測量功能,僅為實現“包裹文本”。

真正的解決方案,應是開放底層圖形系統,而非繼續在HTML/CSS/SVG之上堆砌補丁。這種“自上而下”的改造注定難以奏效。取而代之的應是“向下暴露原始能力”,讓用戶空間與底層邏輯一致,這正是良好內核設計的核心原則。

例如,Use.GPU 項目展示了基于WebGPU構建的HTML-like布局渲染系統,其使用Flex模型實現高效而簡潔的UI布局——無DOM、無CSS,僅使用可組合的布局組件與著色器,定位直觀、行為明確,甚至實現了垂直居中這種CSS難題。

這一系統展示了:無需HTML/CSS/SVG的沉重歷史包袱,僅靠簡潔的樹狀視圖與渲染結構,即可完成DOM 90%的任務。

下一步該往哪里走?

從根本上重新設計DOM,去除所有歷史遺留,可以為瀏覽器帶來多線程、多來源、異步友好的全新架構。現代瀏覽器引擎已是多進程架構,但它們的設計仍然受限于1990年代的DOM模式。

另一些實驗性瀏覽器項目,如Servo或Ladybird,也許能提出更清晰的替代方案。它們實現新功能時無需顧及歷史兼容性,因此具備探索新范式的空間。

開發者應開始關注這些新興技術,并對現有HTML/CSS/DOM系統保持警惕。重新思考UI工具鏈與平臺基礎設施,是時候了。因為,舊的DOM不再適應現代Web應用的需求——而新一代的Web,不應再背負它的遺產。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94609.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94609.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94609.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

客戶管理系統的詳細項目框架結構

以下是針對客戶管理系統的詳細項目框架結構&#xff0c;整合了核心業務模塊&#xff08;客戶信息、合同管理、售前售后等&#xff09;&#xff0c;并補充了實用擴展模塊&#xff08;如數據統計、標簽管理等&#xff09;&#xff0c;嚴格遵循Django模塊化設計原則&#xff1a; c…

【01】OpenCV C#——C#開發環境OpenCvSharp 環境配置 工程搭建 及代碼測試

文章目錄一、OpenCV 介紹二、OpenCvSharp 介紹三、OpenCvSharp環境搭建3.1 創建新項目3.2 添加 NuGet組件3.3 代碼測試3.4 相較于 C OpenCV不同的之處四、LearnOpenCV有時候&#xff0c;單純c#做前端時會聯合C實現的dll來落地某些功能由于有時候會用C - Opencv實現算法后封裝成…

【解決辦法】報錯Found dtype Long but expected Float

Found dtype Long but expected Float錯誤通常發生在嘗試將一個數據類型為Long的張量傳遞給一個期望數據類型為Float的函數或操作時。在PyTorch中&#xff0c;Long和Float是兩種常見的數據類型&#xff0c;分別對應于64位整數和32位浮點數。某些函數或操作可能只接受特定數據類…

QtC++ 調用 tesseract開源庫 搭配 Opencv 實現文字識別:從tesseract庫基本介紹到實際應用實現

前言 在當今數字化時代&#xff0c;文字識別&#xff08;OCR&#xff09;技術已經滲透到我們生活和工作的方方面面&#xff0c;從掃描文檔的自動排版到車牌識別、票據信息提取等&#xff0c;都離不開 OCR 技術的支持。而在眾多 OCR 實現方案中&#xff0c;QtC 結合 tesseract 和…

數據集-目標檢測系列- 地球儀 數據集 globe>> DataBall

數據集-目標檢測系列- 地球儀 數據集 globe&#xff1e;&#xff1e; DataBall貴在堅持&#xff01;* 相關項目1&#xff09;數據集可視化項目&#xff1a;gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview2&#xff09;數據集訓練、推理相關項目&…

[Oracle] DUAL數據表

Oracle中的DUAL數據表是一個特殊的單行單列虛擬表結構&#xff1a;1行1列SELECT * FROM DUAL;輸出結果&#xff1a;列名默認DUMMY&#xff0c;值為X常見使用DUAL數據表的場景&#xff1a;1.系統函數調用測試當需要測試Oracle函數但不需要真實表數據時&#xff0c;我們可以考慮使…

第五篇: 深入解析基于 SQLAlchemy 的聊天記錄持久化模塊:`message_model` 與數據庫操作封裝

深入解析基于 SQLAlchemy 的聊天記錄持久化模塊:message_model 與數據庫操作封裝 作者:zgw 標簽:SQLAlchemy、Python、FastAPI、數據庫持久化、ORM、聊天系統、AI 應用開發 一、前言 在構建大模型應用(如聊天機器人、知識庫問答系統)時,對話記錄的持久化 是實現“可追溯…

學習游戲制作記錄(將各種屬性應用于戰斗以及實體的死亡)8.5

1.將各種屬性應用于戰斗我們希望將上節課的CharactorState腳本作為一個父類&#xff0c;而玩家和敵人的屬性狀態都是繼承自它的創建PlayerStats腳本&#xff1a;public class PlayerStats : CharactorState {private Player player;//獲取玩家腳本protected override void Star…

Higgsfield平替,地球轉場+動物豎中指AI視頻教程

大家好&#xff0c;這里是K姐。 一個幫助你把AI真正用起來的女子。 最近TikTok上的網友已經集體瘋魔了——刷到的視頻總以高空航拍開場&#xff0c;鏡頭從地球拉近后&#xff0c;要么是橘貓蹲在白宮草坪比中指&#xff0c;要么是柴犬在富士山頂比中指…… 這種堪比好萊塢運鏡…

界面規范的其他框架實現-列表-layui實現

另一個要改造的系統使用了layui&#xff0c;改造方式如下&#xff1a;斑馬線&#xff1a;.layui-table[lay-even] tr:nth-child(even) {background-color: #f2f2f2 }鼠標滑過&#xff1a;.layui-table tbody tr:hover{background-color: #8dccff }標題行&#xff1a;.layui-tab…

STM32學習筆記2-GPIO的輸出模式

GPIOGPIO&#xff1a;通用輸入輸出口&#xff1b;可配置8種輸入輸出模式引腳電平&#xff1a;0V-3.3V&#xff0c;部分引腳可容忍5V也可認為高電平&#xff0c;但是對于輸出而言&#xff0c;最大就只能輸出3.3V&#xff0c;因為供電就只有3.3V&#xff0c;能容忍5v的在以下的引…

Linux系統學習2之磁盤管理

了解磁盤內容&#xff1a;df&#xff1a;df -a &#xff08;-a是列出所有&#xff0c;-k以kb顯示&#xff0c;-h以Gb顯示&#xff0c;-m以Mbyte顯示&#xff0c;-H為用1000b代替1024b&#xff0c;-t為顯示文件類型&#xff0c;-i為用inode顯示容量&#xff09;&#xff1a;&a…

北大、螞蟻三個維度解構高效隱私保護機器學習:前沿進展+發展方向

在數據隱私日益重要的 AI 時代&#xff0c;如何在保護用戶數據的同時高效運行機器學習模型&#xff0c;成為了學術界和工業界共同關注的難題。北大團隊最新完成的綜述《Towards Efficient Privacy-Preserving Machine Learning: A Systematic Review from Protocol, Model, and…

計算機網絡:如何在實際網絡中進行子網劃分

在實際網絡中,子網劃分是通過“借位”將一個大的IP網絡分割為多個小的子網,以提高IP地址利用率、增強網絡安全性和簡化管理。以下是具體的實施步驟、原理和注意事項: 一、子網劃分的核心目的 提高IP利用率:避免大網絡中IP地址的浪費(例如一個C類地址默認支持254臺主機,若…

《第五篇》基于RapidOCR的圖片和PDF文檔加載器實現詳解

基于RapidOCR的圖片和PDF文檔加載器實現詳解 引言 在構建知識庫時,我們經常需要處理包含圖片和PDF文檔的數據。這些文檔中的文本信息通常以圖像形式存在,需要通過OCR技術來提取。本文將詳細介紹如何使用RapidOCR技術實現圖片和PDF文檔的文本提取加載器。 核心概念 RapidO…

[硬件電路-122]:模擬電路 - 信號處理電路 - 模擬電路與數字電路、各自的面臨的難題對比?

數字電路和模擬電路是電子技術的兩大基礎分支&#xff0c;它們分別處理不同類型的信號&#xff0c;并在設計方法、元件特性、應用場景等方面存在顯著差異。以下是兩者的詳細定義及異同對比&#xff1a;一、定義與核心概念1. 模擬電路&#xff08;Analog Circuit&#xff09;定義…

Linux多線程——線程控制

目錄 1.線程知識補充 1.1 線程私有資源 1.2 線程共享資源 1.3 原生線程庫 2、線程控制接口 2.1 線程創建 2.1.1 一批線程 2.2 線程等待 2.3 線程終止 2.4 線程實戰 2.5 其他接口 2.5.1 關閉線程pthread_cancel 2.5.2 獲取線程 ID pthread_self 2.5.3 線pthread_de…

Python爬蟲實戰:研究spiderfoot工具,構建網絡情報收集系統

1. 引言 1.1 研究背景 在數字化時代,互聯網公開信息已成為國家治理、企業決策與學術研究的戰略資源。據 Statista 統計,2023 年全球互聯網數據總量突破 120ZB,其中可通過公開渠道獲取的情報信息占比超 30%。傳統人工信息收集方式受限于效率與廣度,難以應對海量數據處理需…

在路由器openwrt上安裝openclas

在路由器openwrt上安裝openclas 名詞解釋 las: lash 運行效果圖 安裝 安裝教程參考&#xff1a; 官方&#xff1a;github.com 官方2&#xff1a;openclas.net 如果安裝完成后菜單上沒有&#xff0c;重啟路由后在“服務”菜單下 點擊運行會提示下載內核&#xff0c;按提示…

HIVE 窗口函數處理重復數據

窗口函數row_number()&#xff0c;結合OVER子句中的PARTITION BY和ORDER BY&#xff0c;為數據分組內的每一行生成一個唯一的序號。具體分析如下&#xff1a;函數作用&#xff1a;row_number()&#xff1a;為每個分組內的行分配一個唯一的連續序號&#xff08;從1開始&#xff…