精读《Web Components 的困境》

2,978 阅读6分钟
原文链接: zhuanlan.zhihu.com

本期精读的文章是:The broken promise of Web Components

以及对这篇文章的回应: Regarding the broken promise of Web Components

1 引言

我为什么要选这篇文章呢?

就在前几天的 Google I/O 2017上, Polymer 正式发布了 Polymer 2.0 版本.

来看一下 Polymer 2.0 的一些变化:

  • 使用 Shadow DOM v1 代替 Polymer.dom. Shady DOM从 Polymer 中分离出来.
  • 使用 标准的 ES6 类和 Custom Elements v1 来自定义元素.
  • 还有数据系统的改进和生命周期的变更.

可以看到, Polymer 的这次升级主要是将 Shadow Dom 和 Custom Elements 升级到 v1 版本, 以获得更多浏览器的原生支持. 下一 代Web Components - v1规范,Chrome 已经支持了,Web Components 规范中的2个主要部分 - Shadow DomCustom Elements. Safari在10版本中, 支持了 Shadow DOM v1 规范并且完成了在Webkit内核中对 Custom Elements v1 规范的实现;Firefox对 Shadow DOMCustom Elements v1规范 支持正在开发中;Edge也将对 Shadow DOMCustom Elements 支持规划到他们的开发roadmap中.

这段时间, 大家都在讨论 react, vue, angular, 这些框架. 或者 该使用 redux 还 是 mobx 做数据管理. 在这个契机下, 我想我们可以不单单去思考这些框架, 也可以更多地去思考和了解 Web Components 标准. 对于 Web Components标准有一些思考. 所以我选了一篇关于 Web Components 的文章, 想让大家对于 Web Components 的发展, 和 Web Componets 与现在的主流框架如何协作有更多的思考和讨论.

2 内容概要

The broken promise of Web Components 原文作者dmitriid主要是在喷Web Components从2011年到2017年这6年间毫无进展, 一共产出了6份标准, 其中两份已经被弃用. 几乎只有一个主流浏览器(chrome) 支持.

  • Web Components 这些规范强依赖 JS 的实现
    • Custom Elements 是 JS 脚本的一部分
    • HTML Templates 的出现就是为了被JS 脚本使用
    • Shadow Dom 也需要配合 JS 脚本使用
    • 只有 HTML imports 可以脱离 JS 脚本使用
  • Web Components 操作 DOM
    • 属性都是字符串
    • 元素的内容模型(Content Model)比较奇怪
  • 为了突破限制使用不同的方法来传递数据
  • CSS 作用域, 可以见上次精读《请停止 css-in-js 的行为》

来看一下Polymer 的 核心成员 Rob Dodson 对于本文的回应: Regarding the broken promise of Web Components

  • Web Components 特性需要被浏览器支持,必须有平缓的过渡,良好的兼容,以及成熟的方案,因此推进速度会比较慢一些.
  • React 很棒, 但是也不要忽略其他基于 Web Components 的优秀库比如 Amp
  • 对于 DOM 更新的抽象比如 React/JSX很赞, 但是也带来了一些损耗. 在旧的移动设备上, 加载一个大的js 包性能依旧不理想, 最佳的做法是拆分你的 JS 包, 按需加载.
  • 使用 JSX 和 虚拟 DOM是很酷, 也可以直接把 JSX 用在 Web Components 内, 像SkateJS库, 已经在做这个事情了.
  • 没有标准的数据绑定, Polymer的数据绑定, 现在是基于MDV, 很多开发者更倾向于基于 Observables或者 ES6 Proxies的数据绑定方案.
  • 处理组件的字符串属性是很烦人, 但是由于每一个组件都是一个类的实例, 可以利用ES6 的 getters/setters来改变属性.

Rob Dodson对于 Web Components 依然充满信心, 但是也承认推进标准总会有各种阻碍, 不可能像推荐框架一样快速把事情解决.

3 精读

本次提出独到观点的同学有: @camsong @黄子毅 @杨森 @rccoder @alcat2008 精读由此归纳.

# 标准与框架

Web Components 作为一个标准,骨子里的进度就会落后于当前可行的技术体系。正如文中所说,浏览器厂商 ship 一个新功能是很严肃的,很可能会影响到一票的线上业务,甚至会影响到一个产业(遥想当年 Chrome Extension 禁用 NPAPI时的一片哀鸿遍野,许多返利插件都使用了这种技术)。那么 Web Components的缓慢推进也在情理之中了. 即使真的有一天这个标准建立起来,Web Components作为浏览器底层特性不应该拿出来和React这类应用层框架相比较. 未来Web Components会做为浏览器非常重要的特性存在。API偏低层操作,会易用性不够. 在很长时间内开发者依旧会使用 React/Vue/Angular/Polymer 这样的框架,Web Components可能会做为这些框架的底层做一些 浏览器层面上的支持.

# 不局限于框架的组件复用

在 Webpack 大行其道的时代,想在运行时做到组件即引即用变得很困难,因为这些组件大多是通过 React/Vue/Angular 开发的. 不得不考虑引入一大堆 Vendor 包,这些 Vendor 里可能还必须包含 React 这类两个版本不能同时使用的库. 目前我们团队在做组件化方案时就遇到这个问题,只能想办法避免两个版本的出现. 你可以说这是 React 或 Webpack 引入的问题,但并没有看到 Web Compnents 标准化的解决方案. 我想未来Web Components可能会作为浏览器的底层, 出现基于底层的标准方案来做组件间的相互应用的方法.

# 为什么对 Web components 讨论不断

俗话说,成也萧何,败也萧何. 正如原文提及的,现在网页规模越来越大,需求也越来越灵活,html 与 css 的能力已经严重不足,我们才孤注一掷的上了 js 的贼船:JSX 和 Css module,因为 Web components 依托在 html 模版语言上,当然没办法与 js 的灵活性媲美.

但使用前端框架的问题也日益暴露,随着前端框架种类的增多,同一个框架不同版本之间无法共存,导致组件无法跨框架复用,甚至只能固定在框架的某个版本,这与前端未来的模块化发展是相违背的,我们越是与之抗衡,就越希望 Web components 能站出来解决这个问题,因为浏览器原生支持模块化,相当于将 react angular vue 的能力内置在浏览器中,而且一定会向前兼容(这也是 Web components 推进缓慢的原因).

4 总结

我觉得 Web Components作为浏览器底层特性不应该拿出来和React, vue 这类应用层框架相比较. Web Components 的方向以及提供的价值都不会跟 应用框架一致. 而 Web Components 作为未来的 Web 组件标准 , 它在任何生态中都可以运行良好. 我倒是更加期待应用层去基于 Web Components 去做更多的实现, 让组件超越框架存在, 可以在不同技术栈中使用.

讨论地址是:精读《Web Components 的困境》 · Issue #15 · dt-fe/weekly


如果你想参与讨论,请点击这里,每周都有新的主题,每周五发布.