作者: 京東科技 牛志偉
一、讓人又愛(ài)又恨的Web Components
Web Components是一種用于構(gòu)建可重用的Web元素的技術(shù)。它允許開(kāi)發(fā)者創(chuàng)建自定義的HTML元素,這些元素可以在不同的Web應(yīng)用程序中重復(fù)使用,并且具有自己的樣式、行為和功能。
Web Components并非一項(xiàng)新技術(shù),而是一組持續(xù)演進(jìn)的、由W3C標(biāo)準(zhǔn)化的組件化API。最早可以追溯到2011年左右,大約在2016年左右各個(gè)瀏覽器才實(shí)現(xiàn)了Custom Element V1版本。然而,在同一時(shí)期,諸如Vue和React等組件化框架已經(jīng)開(kāi)始主導(dǎo)前端開(kāi)發(fā)生態(tài)。
盡管近幾年Web Components標(biāo)準(zhǔn)和技術(shù)都趨于成熟,但早期面臨的兼容性問(wèn)題以及后來(lái)Vue和React等MVVM框架的崛起,導(dǎo)致Web Components領(lǐng)域一直處于低調(diào)狀態(tài)。接下來(lái),我們將從Web Components的發(fā)展歷程、優(yōu)勢(shì)以及開(kāi)發(fā)中面臨的挑戰(zhàn)三個(gè)方面更深入地了解Web Components。
1、Web Components發(fā)展歷程
?2011年:Google發(fā)布了Chrome瀏覽器,并提出了“Shadow DOM”概念,這是Web Components的一個(gè)重要組成部分。
?2013年:谷歌工程師Alex Komoroske在Google I/O大會(huì)上首次提出了Web Components的概念,并推動(dòng)了相關(guān)標(biāo)準(zhǔn)的制定。
?2014年:W3C發(fā)布了Web Components的規(guī)范草案,其中包括四個(gè)主要技術(shù):Custom Elements、Shadow DOM、HTML Templates和HTML Imports。
?2015年:Web Components的規(guī)范逐漸得到瀏覽器廠商的支持,Chrome、Firefox、Safari等主流瀏覽器開(kāi)始逐步實(shí)現(xiàn)相關(guān)功能。
?2018年:Web Components逐漸成為前端開(kāi)發(fā)的主流技術(shù)之一,越來(lái)越多的開(kāi)發(fā)者開(kāi)始使用Web Components來(lái)構(gòu)建可重用的組件。
?至今:Web Components技術(shù)不斷發(fā)展和完善,越來(lái)越多的框架和庫(kù)開(kāi)始支持Web Components,使其在前端開(kāi)發(fā)中發(fā)揮更大的作用。
2、Web Components有哪些優(yōu)勢(shì)
?封裝性:Web Components 具有良好的封裝性,可以將頁(yè)面中的功能和樣式封裝在一個(gè)自定義元素內(nèi)部,避免全局作用域的污染,提高了代碼的可維護(hù)性和可重用性。
?跨框架兼容:Web Components 是基于 Web 標(biāo)準(zhǔn)的技術(shù),可以在任何支持 Custom Elements 和 Shadow DOM 的現(xiàn)代瀏覽器中使用,與各種前端框架和庫(kù)兼容性良好。
?標(biāo)準(zhǔn)化:Web Components 的規(guī)范由 W3C 組織制定,具有較高的標(biāo)準(zhǔn)化程度,有利于統(tǒng)一前端開(kāi)發(fā)的規(guī)范和實(shí)踐,提高了代碼的可維護(hù)性和可移植性。
?性能優(yōu)勢(shì):通過(guò)使用 Shadow DOM 技術(shù),Web Components 可以實(shí)現(xiàn)更好的性能優(yōu)化,避免不必要的重繪和重排,提高頁(yè)面的渲染效率和用戶體驗(yàn)。
目前,前端開(kāi)發(fā)中有許多流行的框架可供選擇,如React、Vue、Angular、Solid、Svelte、Preact等??蚣艿倪x擇是一個(gè)復(fù)雜的決策過(guò)程。當(dāng)框架版本升級(jí)時(shí),項(xiàng)目可能需要面臨重構(gòu)的問(wèn)題。例如,從Vue2升級(jí)到Vue3可能需要付出較大的改造成本。如果不進(jìn)行升級(jí),就無(wú)法使用最新特性,甚至可能面臨框架舊版本不再維護(hù)的尷尬局面。在這種情況下,Web Components 的框架無(wú)關(guān)性可以在一定程度上改善這種局面。
就性能而言,以將 React 組件轉(zhuǎn)換為 Web Components 為例,可以優(yōu)化執(zhí)行過(guò)程,減少阻塞,提高頁(yè)面性能。在普通的 React 組件中,初次執(zhí)行時(shí)需要一次性完成所有必須的節(jié)點(diǎn)邏輯,這些邏輯的執(zhí)行會(huì)同步占用在 JavaScript 的主線程上。當(dāng)頁(yè)面變得足夠復(fù)雜時(shí),一些非核心邏輯可能會(huì)阻塞后面核心邏輯的執(zhí)行。而通過(guò)使用 Web Components 優(yōu)化 React 組件,執(zhí)行過(guò)程會(huì)變得更簡(jiǎn)潔。例如,注冊(cè)一個(gè)復(fù)雜的邏輯組件時(shí),在 React 執(zhí)行時(shí)只需執(zhí)行一個(gè) createElement 語(yǔ)句,創(chuàng)建組件只需要 1-2 微秒即可完成。真正的邏輯不會(huì)立即執(zhí)行,而是等到“核心任務(wù)”執(zhí)行完畢后再執(zhí)行,甚至可以在合適的時(shí)機(jī)再執(zhí)行,從而降低 Diff 成本。

3、使用Web Components開(kāi)發(fā)的痛點(diǎn)
雖然Web Components具有許多令人喜歡的優(yōu)點(diǎn),但在實(shí)際開(kāi)發(fā)中也存在一些棘手的問(wèn)題。以下是幾個(gè)典型問(wèn)題:
?原生開(kāi)發(fā)難題:Web Components是一項(xiàng)原生技術(shù),因此在組件編寫(xiě)過(guò)程中需要回歸到原生開(kāi)發(fā)。事件處理、狀態(tài)管理等方面都需要自行處理。盡管大多數(shù)框架都提供了對(duì)Web Components的封裝方案,但使用這些方案又需要引入相應(yīng)框架的運(yùn)行時(shí),這導(dǎo)致脫離了框架無(wú)關(guān)性這一最大優(yōu)勢(shì)。
?Form表單問(wèn)題:在Shadow DOM中,包含、或
?樣式隔離問(wèn)題:雖然樣式隔離有助于避免全局樣式污染的問(wèn)題,但在某些場(chǎng)景下,如主題顏色等,仍需要將樣式同步到Web Components組件內(nèi)部。目前可以通過(guò)CSS變量實(shí)現(xiàn)主題切換。此外,需要注意的是,slot插槽中的DOM元素樣式并未得到隔離。
針對(duì)這些問(wèn)題,開(kāi)發(fā)人員可能需要考慮采取一些額外的措施來(lái)解決挑戰(zhàn),以確保Web Components在實(shí)際應(yīng)用中能夠更加順暢地運(yùn)行。
二、目前主流的Web Components組件方案
1、頭部案例
Twitter 2016 年開(kāi)始將自己的嵌入式推文從 iframe 切換成 ShadowDOM,減少了內(nèi)存消耗、加快了渲染速度,并批量渲染的時(shí)候保持絲滑。Upcoming Change to Embedded Tweet Display on Web?
Youtube
Youtube 作為 google 系的產(chǎn)品,很早就在全站用上了 Web Components,并且開(kāi)源了自己播放器組件 GitHub - GoogleWebComponents/google-youtube: YouTube video playback web component此外 google 開(kāi)源的 Web Components 還是很多的,Google Web Components · GitHub ,包括地圖、drive、日歷等等。
Github
Github 對(duì) Web Components 的使用很早,具體可以看: How we use Web Components at GitHub | The GitHub Blog,2017 年 Custom Elements v1 版本在 chrome 和 safari 上相繼實(shí)現(xiàn)之后,Github 開(kāi)始大范圍使。要知道 Github 2018 年才剛剛完全移除 jQuery:Removing jQuery from GitHub.com frontend | The GitHub Blog 這既得益于 Github 自身項(xiàng)目組件化的架構(gòu),也得益于 Web Components 本身與框架無(wú)關(guān)的特性非常識(shí)合作老項(xiàng)目升級(jí)。
Adobe Spectrum
?Adobe Spectrum 是由 Adobe 創(chuàng)建的設(shè)計(jì)系統(tǒng),該站點(diǎn)是一個(gè)基于 Web Components 的 UI 框架產(chǎn)品。
2、方案對(duì)比
目前主流的 Web Components 組件方案有三種:
方案一:
?特點(diǎn):以React和Vue為代表,通過(guò)將React或Vue組件包裝為Web Components組件的方式實(shí)現(xiàn)。
?優(yōu)點(diǎn):利用了本身框架的特性如生命周期、狀態(tài)管理等,易于開(kāi)發(fā)者使用。
?缺點(diǎn):需要引入本身框架的運(yùn)行時(shí),導(dǎo)致組件體積增加,同時(shí)喪失了框架無(wú)關(guān)性這一優(yōu)勢(shì)。
方案二:
?特點(diǎn):以Stencil和LitElement為代表,提供了專門的編譯器、工具鏈和語(yǔ)法糖來(lái)構(gòu)建 Web Components。
?優(yōu)點(diǎn):相比第一種方案,引入本身框架的運(yùn)行時(shí)可能更小,減少了體積。
?缺點(diǎn):需要學(xué)習(xí)新的語(yǔ)法和工具,可能增加開(kāi)發(fā)者的心智負(fù)擔(dān)。
方案三:
特點(diǎn):以Svelte和Solid為代表,直接將組件編譯成原生 Web Components
優(yōu)點(diǎn):放棄了虛擬DOM,利用編譯或轉(zhuǎn)譯能力直接生成操作DOM的更新函數(shù),性能優(yōu)秀,接近原生DOM。另外Vue3中的Vapor模式,正是借鑒了這種模式,目前正在試驗(yàn)階段。
三、與SolidJS結(jié)合的“化學(xué)反應(yīng)”
1、SolidJS有何不同
SolidJS 是一個(gè)快速、靈活、可擴(kuò)展的 JavaScript 庫(kù),用于構(gòu)建用戶界面。與其他前端框架相比,SolidJS 有一些獨(dú)特的特點(diǎn)和優(yōu)勢(shì):
?Reactivity System: SolidJS 使用基于數(shù)據(jù)變化的響應(yīng)式系統(tǒng),可以精確追蹤狀態(tài)的變化,并只更新發(fā)生變化的部分,從而提高性能。
?Fine-grained Reactivity: SolidJS 提供了細(xì)粒度的響應(yīng)式更新,可以在組件級(jí)別、元素級(jí)別甚至屬性級(jí)別進(jìn)行更新,避免不必要的重新渲染。
?No Virtual DOM: 與其他框架不同,SolidJS 不使用虛擬 DOM,而是直接編譯生成操作真實(shí) DOM的函數(shù),減少了 diff 算法的開(kāi)銷,提高了性能。
?Hooks-based API: SolidJS 使用類似 React Hooks 的 API,使得組件邏輯更易于復(fù)用和組合
2、可以解決哪些問(wèn)題
?直接在編譯階段生成原生Web Components,核心庫(kù)非常小巧,沒(méi)有額外的依賴,可以幫助減少項(xiàng)目的體積。
?提供響應(yīng)式狀態(tài)管理、事件管理、生命周期等,解決原生開(kāi)發(fā)的痛點(diǎn)。
?類React語(yǔ)法,上手容易,降低開(kāi)發(fā)者心智負(fù)擔(dān),轉(zhuǎn)換成Web Components十分流暢。
四、從0到1搭建 Aura Design Web Components組件庫(kù)
1、工程目錄設(shè)計(jì)
該項(xiàng)目采用了 Monorepo 設(shè)計(jì),旨在統(tǒng)一管理各個(gè)子項(xiàng)目,避免開(kāi)發(fā)階段頻繁發(fā)布/安裝 npm 包來(lái)同步代碼。具體內(nèi)容包括:
?packages/eslint-config-aurai: 用于管理ESLint配置,集成了TypeScript和Prettier(用于JavaScript/TypeScript格式化)。
?packages/stylelint-config-aurai: 用于管理StyleLint配置,集成了stylelint-order(用于樣式屬性排序)和Prettier(用于樣式格式化)。
?packages/aura-design: 基于eslint-config-aurai和stylelint-config-aurai規(guī)范,使用Solid和Solid Element構(gòu)建的Web Components元組件庫(kù),包括按鈕、圖標(biāo)、卡片、布局等基礎(chǔ)組件。
?packages/aura-design-pro: 與aura-design類似,但封裝了一些復(fù)雜組件,通常是依賴第三方庫(kù)的組件,例如支持Markdown渲染的富文本組件、視頻播放組件等。
?apps/aura-design-docs: 基于Storybook的組件文檔庫(kù),支持查看代碼、組件預(yù)覽,并可實(shí)時(shí)預(yù)覽修改組件屬性。
?apps/react-starter、apps/vue-starter: 計(jì)劃用于驗(yàn)證Web Components在React和Vue組件中的兼容性等問(wèn)題。
?

?
?
2、部分細(xì)節(jié)展示
2.1、組件樣式編寫(xiě)
Web Components組件中的樣式是內(nèi)聯(lián)到每一個(gè)組件的Shadow DOM中,因此不能用常規(guī)的CSS Modules等方案。本項(xiàng)目中使用了大約4種不同的內(nèi)聯(lián)樣式方案,以對(duì)應(yīng)不同的應(yīng)用場(chǎng)景:
?原子化CSS方案:UnoCSS致力于將所有樣式屬性細(xì)分為最小單元的CSS,以便實(shí)現(xiàn)最大程度的自由組合和復(fù)用。此外,UnoCSS還具有自動(dòng)分析文件中使用的樣式的功能,只將實(shí)際使用的樣式打包,從而減小文件大小。
?

?
?
?CSS inline模式:利用Vite的功能,將外部樣式作為內(nèi)聯(lián)模式引入,當(dāng)需要自定義復(fù)雜樣式或語(yǔ)義化場(chǎng)景時(shí),可能會(huì)使用此模式。
import styles from './Button.css?inline';?CSS Template:CSS模板字符串類似于CSS-in-JS方案,通常用于根據(jù)prop變量動(dòng)態(tài)控制樣式。盡管這種方法會(huì)增加一定的運(yùn)行時(shí)處理邏輯,但可以有效減少CSS重復(fù)和文件大小。
const styles = css` :host { display: inline-block; } .box { height: ${props.size + 2}px; line-height: ${props.size + 2}px; position: relative; overflow: hidden; } .nums-chip { transition: transform 1.5s; transform: translate(0, -50%); overflow: hidden; } .number { font-size: ${props.size}px; line-height: ${props.size + 2}px; } `;?CSS Link:使用link標(biāo)簽引入外部樣式表,當(dāng)組件樣式比較多、體積較大時(shí),如果直接內(nèi)嵌到組件內(nèi)部,當(dāng)有N個(gè)組件時(shí),體積就會(huì)增大N倍(暫不考慮瀏覽器內(nèi)置優(yōu)化邏輯),而使用link標(biāo)簽減少體積同時(shí)也可以利用上瀏覽器緩存的特性。
... return ( ???> ?link href={`https://cdn.bootcdn.net/ajax/libs/highlight.js/11.8.0/styles/atom-one-${props.theme}.min.css`} rel="stylesheet"??>?/link??> ?style??>{styles}?/style??> ?/??> ); ...2.2、Svg圖標(biāo)集成
Icon組件引入和注冊(cè)
import { defineCustomElements, registerIcon, Icon, } from '@aura-group/aura-design'; registerIcon('/iconfont.svg'); // 自定義svg圖標(biāo)注冊(cè),使用主項(xiàng)目根目錄的svg圖標(biāo)文件,如果不注冊(cè)則使用默認(rèn)圖標(biāo) defineCustomElements({ Icon }); // 注冊(cè)Web Components圖標(biāo)組件組件使用
?ar-icon name="download" size="20px" color="#4213de"??>?/ar-icon??>2.3、組件打包
支持ES(按需加載)和UMD兩種范式,自動(dòng)生成Typescript聲明文件:
package.json
{ "name": "@aura-group/aura-design", "version": "0.3.9", "description": "", "main": "dist/aura-design.umd.js", "module": "dist/aura-design.es.js", "typings": "dist/types/components/index.d.ts", "files": [ "dist" ], "type": "module", ... }Vite相關(guān)配置
... build: { lib: { entry: 'src/components/index.ts', name: 'aura-design', fileName: (format) => `aura-design.${format}.js`, }, }, ...3、基于Storybook的組件文檔
Storybook 是一個(gè)開(kāi)源工具,用于開(kāi)發(fā)和展示 React、Vue、Angular 等前端組件的交互式 UI 組件庫(kù)。通過(guò) Storybook,開(kāi)發(fā)人員可以在一個(gè)獨(dú)立的環(huán)境中編寫(xiě)、展示和測(cè)試組件,而不必依賴于整個(gè)應(yīng)用程序。這樣可以更快地開(kāi)發(fā)和調(diào)試組件,同時(shí)也方便團(tuán)隊(duì)成員之間的協(xié)作。
Storybook 提供了一個(gè)交互式的界面,開(kāi)發(fā)人員可以在其中創(chuàng)建不同的“故事”(stories),每個(gè)故事對(duì)應(yīng)一個(gè)組件的不同狀態(tài)或交互方式。通過(guò) Storybook,開(kāi)發(fā)人員可以輕松地查看和測(cè)試組件在不同狀態(tài)下的表現(xiàn),從而更好地理解和調(diào)試組件的行為。
?

?
?
4、未來(lái)規(guī)劃
目前,我們的組件庫(kù)中包含了16個(gè)基礎(chǔ)組件和一些與AI Chat相關(guān)的組件。在 A-M 網(wǎng)站中,95% 的組件都源自 Aura Design 組件庫(kù)。未來(lái),除了繼續(xù)封裝一些基礎(chǔ)組件外,我們將優(yōu)先開(kāi)發(fā)常規(guī)組件庫(kù)中缺失的比如AI應(yīng)用的相關(guān)組件。隨著組件庫(kù)的逐步豐富和條件的成熟,我們會(huì)考慮將其開(kāi)源。如果您有任何相關(guān)組件的封裝需求或希望成為項(xiàng)目的成員,請(qǐng)隨時(shí)與我聯(lián)系。
參考文獻(xiàn)
??ChatGPT?
??Web Components從技術(shù)解析到生態(tài)應(yīng)用個(gè)人心得指北?
??2022 Web Components 趨勢(shì)解讀和展望?
??你不知道的 Web Components - 過(guò)去和未來(lái)?
?
審核編輯 黃宇
-
AI
+關(guān)注
關(guān)注
91文章
41358瀏覽量
302737
發(fā)布評(píng)論請(qǐng)先 登錄
[完結(jié)15章]Java轉(zhuǎn) AI高薪領(lǐng)域必備-從0到1打通生產(chǎn)級(jí)AI Agent開(kāi)發(fā)
嵌入式AI開(kāi)發(fā)必看:杜絕幻覺(jué),才是工業(yè)級(jí)IDE的核心底氣
AI輔助編程設(shè)計(jì)之道:從Spec到Code工程實(shí)踐
復(fù)工精神內(nèi)耗?搭建一個(gè)二次元AI伴侶陪你聊天(KouriChat+ZeroNews)
LuatOS框架的使用(上)
2025開(kāi)放原子開(kāi)發(fā)者大會(huì)AI時(shí)代數(shù)據(jù)庫(kù)創(chuàng)新實(shí)踐分論壇成功舉辦
PYQT 應(yīng)用程序框架及開(kāi)發(fā)工具
RAG實(shí)踐:一文掌握大模型RAG過(guò)程
【「AI芯片:科技探索與AGI愿景」閱讀體驗(yàn)】+AI的科學(xué)應(yīng)用
3招告別無(wú)效巡檢!AI智能巡檢讓你的門店管理效率翻倍 智睿視界
飛書(shū)富文本組件庫(kù)RichTextVista開(kāi)源
任正非說(shuō) AI已經(jīng)確定是第四次工業(yè)革命 那么如何從容地加入進(jìn)來(lái)呢?
ArkUI介紹
HarmonyOS實(shí)戰(zhàn):組件化項(xiàng)目搭建
Web Components實(shí)踐:如何搭建一個(gè)框架無(wú)關(guān)的AI組件庫(kù)
評(píng)論