【CSDN 編者按】該文章主要探討了 Web 組件的優缺點以及適用場景。作者認為 Web 組件在 DOM 樹葉子節點、設計系統和企業級應用中表現出色,但也指出了其在服務器端渲染和可訪問性方面的不足。文章強調,Web 組件不是一種全能的解決方案,而是應在其擅長的領域中得以應用。
原文鏈接:https://nolanlawson.com/2023/08/23/use-web-components-for-what-theyre-good-at/
作者 | Nolan Lawson譯者| 明明如月
責編 | 夏萌
出品 | CSDN(ID:CSDNnews)
近期,Dave Rupert 的文章《 Web 組件究竟有何優勢,我為何未采用?》引發了廣泛討論。作為一個擁有多年 Web 組件使用經驗的開發者,我想分享一下自己的看法。
在分析問題之前,我想先給出一個典型的“資深工程師”的看法:是否應該使用 Web 組件取決于具體場景的需要?,F在,讓我們首先探究 Web 組件在哪些場景表現更出色,然后再分析其存在的局限性。
DOM 樹中的葉子節點
在我看來,Web 組件特別適用于 DOM 樹中的葉子節點,也就是那些不需要服務器端渲染(SSR)和沒有內嵌內容的組件。具體而言,如富文本編輯器、日歷插件和顏色選擇器等。
在此場景中,一些常見于 Web 組件的挑戰,如服務器端渲染(SSR)、hydration、插槽(slotting),或甚至是 Shadow DOM,都不再是問題。如果你不使用框架,或者使用一個支持 Web 組件的框架,你只需要把 <fancy-component>標簽放到你的模板或 JSX 中就可以了。
以我的 emoji-picker-element 組件為例,僅需一行 html 代碼即可導入:
< type="module" href="https://cdn.jsdelivr.NET/npm/emoji-picker-element@1/index.js"></>用法也非常簡潔:
<emoji-picker></emoji-picker>emoji-picker-element 組件效果截圖
這樣,無需依賴打包工具、轉譯器或特定框架,簡單復制粘貼即可。這不僅適用于小型項目,也已成功應用在復雜的單頁應用(SPA)中,這也體現了 Web 組件的廣泛適用性。
這完全符合 Web 組件的設計初衷:使自定義 Web 組件的使用與內置 HTML 元素一樣簡單。
適配代碼:一種避免全量重構的策略
設想這樣一個場景:你手頭有一個龐大的 React 項目,它已經穩定運行了相當長的時間?,F在,團隊計劃轉向 Svelte。這是否意味著你必須從頭到尾重構代碼庫,并且還需要為每一個第三方組件找到其 Svelte 版本?
前端開發者在考慮從一個框架遷移到另一個框架時,通常會擔心巨大的遷移成本。然而,最大的誤區則是將 Web 組件也看作是與此相似的問題。
實際上,Web 組件的核心價值在于解決這種框架依賴性帶來的問題。如果你打算從 Vue 切換到 Lit,或從 Angular 切換到 Stencil,而且還計劃一次性重構所有組件,那么你無疑是在給自己制造麻煩。
更合理的做法是允許新舊代碼并存,并用 Web 組件作為中間層,實現兩者的無縫對接。這樣,你就無需一次性全面重構代碼:
<old-component> <new-component> </new-component> </old-component>Web 組件能夠進行屬性(props)傳遞和事件(events)觸發,這基本上覆蓋了它們的核心功能。如果你使用的框架支持 Web 組件,這一切都是開箱即用的。即使不支持,你也可以通過編寫輕量級的適配代碼來實現。
雖然有人可能對一個頁面上混用多個框架有所保留,但這種擔憂更多地是基于直覺而非實證數據。如果你使用的是元框架進行服務器端渲染(SSR)和客戶端數據注入(hydration),那么部分遷移的操作可能比預期更為復雜。但 Web 組件的一大優勢就是能在客戶端明確規定如何將兩個組件組合在一起。
因此,如果你和你的團隊不想再頻繁進行全面的代碼重構,那么使用 Web 組件可能是一個好的選擇。
設計系統與企業應用
如果觀看了 Cassondra Robert 在 css Day 上的精彩講解,你會發現一個展示了多個知名企業的 Logo 的頁面,這些都是 Web 組件廣泛使用的佐證。
如果這還不夠的話,你還可以參考 Oracle、SAP、ServiceNow 等其他眾多企業。
你可能沒有意識到,在多數大型企業(例如,我所就職的公司)中,Web 組件已經在其設計系統和組件庫中得到了廣泛應用。尤其是對于那些常在 Web 開發社區中活動的人來說,這樣的現象可能頗為令人驚訝。更令人震驚的是,根據某些統計數據,盡管 React 在網頁中的使用率約為 8%,Web 組件的使用率卻高達 20%。
實際上,許多大企業往往并不在社交媒體平臺如 Twitter、Reddit 等上積極推廣 Web 組件或者提供相關教程。與此相對的是,社交媒體上卻有大量技術達人在緊密跟蹤 React 的每個小版本更新和其生態系統的新動態。這一現象的背后邏輯相當直接:大企業通常更注重內部溝通,而在公開場合相對低調;反觀中小企業和自由職業者,他們則相對更活躍于社交媒體。因此,如果 Web 組件在企業內部獲得了更高的接受度,單憑頻繁瀏覽 Twitter 是難以察覺的。
那么,大型企業為何如此偏愛 Web 組件呢?首先,基于 Web 組件構建的設計系統具有跨環境的可運行性。在一個大型企業中,前端技術棧可能包括 React、Angular、Ember 以及靜態 HTML,而這些都需要與企業的主題和品牌保持一致性。對于初創企業而言,進行大規模的代碼重構或許是一種有益的嘗試,但在企業層面,這樣做并不現實。
因為企業通常維護著龐大的代碼庫,并且需要在更長的時間尺度上進行規劃,這促使了其做出與眾不同的技術決策。從我的觀點來看,這正是企業更傾向于使用 Web 組件的根本原因:穩定性和可持續性。
考慮到常規的 React 代碼庫,你可能發現更新任何依賴項(例如 React Router、Redux 或 React 本身)會觸發一系列破壞性變更,這要求你花費數周時間對代碼進行重構。在這種環境下,即使一個細微的變更也可能激活 Hyrum 法則,影響數千個組件,甚至簡單的小版本升級也需要數周的全面測試、驗證和文檔更新。在這個場景中,React 的小版本升級相當于一個復雜問題,而大版本升級則可能引發一場危機。
Hyrum 法則:如果一個 API 的實現細節發生了變化,可能會導致一些用戶的程序出現問題,因為他們已經習慣了之前的行為。因此,API 的設計者和維護者需要考慮到用戶的期望和依賴,盡量保持 API 的穩定性和兼容性。
相反,Web 平臺的向后兼容性為穩定性提供了保障。舉例來說,1996 年發布的 Space Jam 網站至今依然可運行。Web 組件強化了這種穩定性,對于那些不能頻繁進行前端重寫的企業來說,這是一個重要優勢。
當你采用 Web 組件后,其功能和特性保持穩定,包括 Shadow DOM 的樣式隔離等它所有的微妙之處也都是如此。你可以將代碼邏輯委托給瀏覽器來執行,從而長期減少維護和驗證的需求。事實上,這樣做就相當于把維護的責任交給了 google、Apple 和 Mozilla 等瀏覽器廠商。
與 Web 平臺的穩定性相符,企業通常也更加穩定、謹慎,并且注重規避風險。因此,可以理解為什么Web組件在企業界得到了如此廣泛的應用和歡迎。
Web 組件的局限性
在討論 Web 組件的優勢的同時,我們也需要深入了解其不足。以下是 Web 組件的幾個主要局限性:
- 服務端渲染(SSR):當前在 Web 組件領域,服務端渲染仍然是一個懸而未決的問題。盡管存在如 Shadow DOM 這樣的聲明式解決方案,但這只解決了問題的一部分。至今尚無統一標準明確如何在服務器端渲染 Web 組件,導致各大框架在這方面的實踐各異。例如,Lit SSR 尚處于“Lit 實驗”的研發階段。只有當未來服務器端能渲染多種 Web 組件框架,且確保這些框架能順利集成和重新渲染,我才會認為這個問題解決了。然而,解決這個問題可能還需要數年的時間。
- 可訪問性:在主文檔中的 ARIA 屬性可能無法輕易地引用或與 Shadow DOM 內部的元素進行交互,并且處理對話框和焦點也頗具復雜性。因此,如果你希望不損害可訪問性,必須從設計之初就仔細規劃你的組件結構。盡管有許多正在進行的工作試圖解決這個問題,但必須承認,到了 2023 年,這方面仍面臨很多挑戰。
此外,還有其他一些問題,例如依賴問題(如依賴特定的框架、構建工具和測試運行器)、IE11 的遺留問題(這是一些開發者極力避免但無法擺脫的問題)以及開發者的平臺疲勞(例如,“我已經熟練掌握了 React,不想再去學習其他新技術”)。對于這些問題,我能理解并非每個人都會覺得 Web 組件有吸引力。Web 是一個包羅萬象的平臺,各種應用和用途都能在此找到自己的位置,這也是它之所以令人贊嘆的一方面。
總結
不論你是選擇立即采用 Web 組件,還是選擇觀望,或是打算幾年后再重新評估,屆時網絡標準和功能可能會更加完善。
我個人對 Web 組件持積極態度,但也明白這并非人人共識。我的目的并不是要過分強調其重要性,只是認為它是開發者工具集中的一個有用組成部分。關鍵在于如何最大化其優勢,同時規避潛在不足。
Web 組件和網絡標準讓一些細微的問題可以由瀏覽器自行處理,這點我非常喜歡。組件如何組合、樣式作用域如何限定、數據如何傳遞——這些問題可以放心交由瀏覽器解決。這讓我能夠更專注于對終端用戶確實重要的因素,如性能、可訪問性和安全性。
在網絡開發領域,我常感到自己在與與業務目標無關的“附加復雜性”做斗爭。這可能包括管理 npm 依賴、調試狀態管理器,或者解決測試運行器和代碼檢查工具的兼容性問題。雖然有人可能覺得這些問題有趣,我也不時會陷其中,但這些最終只是低效的勞動,因為你的最終用戶并不在乎你的打包器是否與你的 Type 轉譯器兼容。
換句話說,在 2023 年,選擇 Web 組件會帶來一些附加的復雜性,如前面提到的 SSR 和可訪問性問題。在這些方面妥協可能會對你的最終用戶造成實際上對他們很重要的傷害,所以這種權衡可能不值得你做。我認為這種權衡通常是值得的,但同時也存在一些微妙的差異。“專用 Web 組件來發揮其優點”雖然聽起來不太吸引人,但在 2023 年,這仍是一個不錯的選擇。
參考鏈接
- 《Web 組件究竟有何優勢,我為何未采用?》:https://daverupert.com/2023/07/why-not-webcomponents/
- emoji-picker-element:https://Github.com/nolanlawson/emoji-picker-element/
- 復雜的單頁應用(SPA):https://www.npmjs.com/package/emoji-picker-element?activeTab=dependents
- 支持 Web 組件:https://custom-elements-everywhere.com/
- 輕量級的適配代碼:https://github.com/rstacruz/remount
- 更多地是基于直覺而非實證數據:https://nolanlawson.com/2021/08/01/why-its-okay-for-web-components-to-use-frameworks/
- Cassondra Robert 在 CSS Day 上的精彩講解:https://www.YouTube.com/watch?v=67bSCEEdaH8
- 根據某些統計數據:https://mastodon.social/@westbrook/110774427407999573
- 網頁中的使用率約為 8%:https://almanac.httparchive.org/en/2022/JAVA
- 20%:https://chromestatus.com/metrics/feature/timeline/popularity/1689
- Hyrum 法則:https://www.hyrumslaw.com/
- 1996 年發布的 Space Jam 網站:https://www.spacejam.com/1996/
- 它所有的微妙之處:https://lamplightdev.com/blog/2019/03/26/why-is-my-web-component-inheriting-styles/
- 尚無統一標準:https://github.com/webcomponents-cg/community-protocols/issues/7
- Lit SSR:https://lit.dev/docs/ssr/overview/
- “Lit 實驗”:https://lit.dev/docs/libraries/labs/
- 在主文檔中的 ARIA 屬性可能無法輕易地引用或與 Shadow DOM 內部的元素進行交互:https://nolanlawson.com/2022/11/28/shadow-dom-and-accessibility-the-trouble-with-aria/
- 對話框:https://nolanlawson.com/2022/06/14/dialogs-and-shadow-dom-can-we-make-it-accessible/
- 焦點:https://nolanlawson.com/2021/02/13/managing-focus-in-the-shadow-dom/
- 正在進行的工作:https://github.com/WICG/aom/pull/200
- 解決這個問題:https://github.com/WICG/aom/issues/199