原文html
昨天,在和个人狗一块儿散步回来以后,我在推特上看到了一些通知,人们艾特我,要求我分享对 Dan Abramov 关于微前端 的想法: 前端
若是你关注了我,你就知道我对微前端很是热衷,我和他们一块儿工做了一段时间,而且也保持着开放的心态,分析不一样的方式,来理解他们的利弊。git
若是你没有关注我,而是从技术角度对这个主题感到好奇,请查看个人 Medium 主页,除此以外,还有许多其余的关于微前端的资源,只需在 Medium 搜索或使用你最喜欢的搜索引擎就好。github
我无法涵盖 Twitter 中讨论的全部主题,但让咱们从头开始,看看我是否能够帮助添加一些 上下文(在本文中你会愈来愈多地听到这个词😁)微前端话题。web
首先,我不是经过写这篇文章来指责或攻击任何人,甚至不是为了在社交平台上引战,我尊重任何观点,有时候我和其余人有一样的观点,有时候也没有,这种行为带来了创新和新想法,因此我彻底赞同它。后端
考虑到有些人是由丹开始的推文提到我名字的,因此我想分享个人想法,由于我真的相信咱们能够真正讨论微前端,为每一个人提供我在每周收到的常见问题的好处。社交,我的电子邮件,演讲后等等。浏览器
其余人就上述推文与我取得了联系:我没有直接回复推文,由于讨论一个有趣的话题的话,像 280 个字符中的主题其实是限制性的,容易被误解或省略一些重要的细节。缓存
组件绝对是有效的解决方案,许多公司天天都在使用它们,并取得巨大成功,但它们并非万能的灵丹妙药;项目,团队,业务,更通常来讲,它们的上下文必须适合,不然咱们就像试图将一个正方形放入一个圆同样,咱们并不老是能符合预期的。性能优化
探索新的可能性,挑战咱们的信念和“标准的作事方式”,推进咱们的行业向前发展,巩固现有标准或引入新标准。服务器
让咱们从这开始,微前端并无试图取代组件,咱们有可能没有适合全部项目的东西,好比组件,它就不是银弹。
使用正确的工具来作正确的工做,这应该是咱们的目标。 请记住,开发软件是经验性的,而不是科学的。
我曾见过大型组织里,有着可怕的代码库和一个实际成功的产品,我也看到过彻底相反的状况,咱们不能只看到硬币的一面。
到目前为止,我只尝试过大规模的微前端(大约200人 - 前端和后端工程师 - 在同一个项目上工做),结合微服务和团队全部权,与咱们公司之前的模型相比,效果很是好。
他们能在较小的项目中工做吗?理想状况下能够,但我想先尝试一下。
在理论上,一切看起来都很好,当它进入到细节中时,你就会意识到局限性并找到新的挑战。若是您有任何经验,我很乐意听取您的意见!
关于微前端,有不一样的风格,例如,咱们可使用 iframe 来组成最终的视图,或者使用 Edge Side Include 或 Client Side Include,甚至使用预渲染策略,如 Open Components 或者 Interface Framework 并将结果缓存在 CDN 级别上。 另外一种方法是使用一个协调器(orchestrator),它正在为 SPA,单个 HTML 页面或 SSR 应用程序提供服务,协调器能够处于边缘,起点或客户端,协调器的一个例子能够是Single-SPA。
这些方法代表咱们有两种主要方法来肯定微前端的大小:
它们有各自的利弊,我我的更喜欢后者,但它也不是防弹的,了解每种方法的局限性,以及这些限制是否会影响最终项目结果很是重要。
微前端绝对是一种影响你所在组织的技术,它能够提供团队之间的隔离,避免过多的集中化,并使团队可以采起 局部决策 。
这并不意味着这些团队就没法追求战略或 API 约定达成一致意见,微前端使团队可以采起能够遵循的路径,而无需与其余团队协调每一项技术决策,这些决策可能会影响代码库,但咱们容许它们快速失败,独立构建和部署,遵循组织定义的某些边界(公司支持的语言,最佳实践等)。
我我的在不一样的组织中工做过,新的加入者会提供关于如何更改“核心库”但一般用于政治的好的看法,由于这些改变不会当即带来好处,这些建议在积压的内部停留在等待状态中。
将团队决策权下放多是公司能够作的最好的事情之一,由于这个团队与产品团队和业务专家共同生活,天天都在说同一种语言,他们处于博弈的领先地位,集中化反而输了上下文,提供的一些约束有时候也是没必要要的。
当公司可以在特定业务领域内提供一些技术界限时,团队能够以最佳方式表达本身,可能会犯一些错误,可是恢复速度很是快,由于要改变的工做范围小于完整的应用程序。
丹在他的例子中是正确的,但他没有考虑谈话的背景,他试图推广一个必须适用于全部事情的解决方案,但实际状况并不是如此。
任何决策的背景,最重要的事情,是去理解一个由我的贡献者,团队或组织进行的技术实现。
在过去的十年中,我看到许多项目以相似的方式,相同的架构,类似的模式编写......可是在旅途中遇到了不一样的结果和不一样的挑战,正如我以前所说,软件开发是经验性的,而不是科学的。
如今,咱们能够更好地了解咱们可使用哪些方法成功交付项目,咱们再也不使用适合全部项目的框架或架构,咱们正在尝试使用正确的工具来完成正确的工做。
若是一个项目应该使用高度共享的组件,项目从而成功,那就绝对没问题,可能项目的最终结果,环境,所涉及的参与者以及为交付项目而创建的过程使共享组件库成为了合适的解决方案。
与此同时,其余情境可能须要不一样的方法,在盒子外思考,由于传统方法没法提供可预测的结果。
背景是关键,理解业务,咱们运营的环境,咱们所瞄准的结果都与咱们的背景相关联。
所以,拥有一个组件库来抽象数百个(若是不是数千个)组件的功能,就像拥有多个 SPA 同样,代码被复制而不是包含在库或其中的许多中。
上下文迫使咱们作出有时不是其余人指望的决定,咱们过去已经学到了许多规则/指导,例如 DRY(不要重复本身)或 DIE(复制是邪恶的),这些是彻底适用的,但不是咱们须要尊重的教条,无论是什么缘由。由于有时咱们有充分理由那样作。
不要误解个人意思,我不是在提倡复制大量代码是一种最佳实践,但有时候这是一种必要的恶行,它能够更快地向前推动。
代码重复可使咱们的团队更加自主,由于他们不会共享因为抽象而变得更加复杂的代码,而且他们不依赖于外部团队。
与往常同样,咱们在复制代码时须要深思熟虑,抽象代码和复制哪一个更合理,上下文驱使咱们作出决定。
抽象一般比代码重复更昂贵,若是你大规模地应用错误的抽象,咱们就会生成复杂的代码,致使团队成员产生挫败感,转而致使更糟糕的行为,例如忽略集中式方法,转而采用更小的“适合目标“ 的方法,由团队在其本身的代码库中实现的方法,其结果是对总体解决方案的控制较少。
因此,是的,让咱们避免代码重复,但要在你的决策中保持平衡,由于若是你在应用程序的正确部分解决这些问题,你会感到惊讶。
我彻底赞成 Federico 的观点,咱们可以选择的想要的任何技术,它们均可能成为灾难的源泉......那若是咱们只使用最好的部分呢?
微前端并无强加不一样的技术堆栈,事实上它们支持这种方法,并不意味着咱们须要遵循它。
就像在微服务世界中同样,咱们在同一系统中最终不会有20种不一样的语言,由于它们中的每一种都是执拗己见的,而且在系统内部带来了本身的愿景,维护不一样的生态系统是很是昂贵的,而且可能会形成混乱,从而不会提供太多的好处。
可是权衡可能会有所帮助,咱们能够从中选择有限的语言或框架列表,那些真正起做用的部分。
猛不及防,咱们并无与一个技术栈紧密耦合,咱们能够重构支持前一个堆栈的旧项目,以及一个缓慢但稳定地进入生产环境而不须要大爆炸版本的新项目(参考扼杀模式),咱们能够在生产环境中使用相同的库或框架的不一样版本而不影响整个应用程序,咱们能够尝试新的框架或方法,观测到实际的性能在运行,咱们能够雇用最好的来自多个社区的人等等许多其余的优点。
当咱们具备使用多个技术栈的能力时,有一些准则确实有助于从中得到巨大的好处,只有当存在混乱而不是共同的目标时,缺点或灾难才成为现实。
我对 Dan Shappir 很是敬重,去年我在 Fluent 会议期间参加了在圣何塞举办的研讨会。
他提供了大量关于如何优化咱们的 Web 应用程序的好看法,绝对是性能优化的大师。
我认为 Dan 在这里分享的评论确实依赖于(再次强调)上下文,例如,使用微前端并在多个 SPA 中切分应用程序,只容许下载部分应用程序,从应用程序代码库中拆分库,容许咱们若是用户须要快速往返(roundtrips),增长服务供应商文件的 CDN 上的 TTL,浏览器也加强了直接从磁盘提供文件的缓存策略,而不是执行屡次往返。
最后,服务端的 workers 能够经过针对依赖关系的缓存策略来缓解此问题,若是它对用例是明智的。
如今,没法避免的是,若是咱们将依赖关系打包得很糟糕,这会影响加载时间,但它不会影响微前端,它会影响 SPA。
可能与微前端同样,你也能够共享依赖关系(看看Single-SPA)或者你说不的话,在后一种状况下,取决于你的应用程序使用方式,例如,若是咱们能了解用户在咱们的应用程序中的行为,咱们能够将应用程序“切片”到咱们的用户正在消费微前端内部的“旅程”,并在另外一个内部开始新的旅程。
咱们能够发现的是,咱们的用户来到咱们的平台执行一次旅程,在这种状况下,他们将只下载微前端中所需的依赖项和代码,而不是整个应用程序中使用的全部依赖项。
同理,用户能够在咱们的应用程序中随机导航,这样的话他将屡次下载一些依赖项,但在这种状况下,这取决于团队如何减轻他的旅程并改善性能以提供更好的体验。
帕累托法则 (80/20 规则) :“......对于许多事件,大约 80% 的影响来自 20% 的缘由”。
使用微前端的 API 管理多是具备挑战性的,但不比与其余架构协同工做重要,在咱们的案例中,咱们正在从服务字典中移动,咱们列出了全部可用的 API 到专用于每一个微前端的列表,它须要一点点更多的工做,但它优化了服务器和客户端之间共享的有效负载,只显示对该微前端感兴趣的 API。 显然,并不老是可让 API 只与一个微前端相关,在这种状况下,咱们须要在团队之间拥有外部依赖关系和沟通,但与平常工做相比,它很是有限。
我想在此强调的是,微前端并不完美,但良好的实践组合可使咱们的项目以高标准交付:正确的工做,正确的工具,还记得吗?
我真的相信,正确的工做使用正确的工具是必不可少的,总体,微服务,组件,库,微前端是表达本身的工具和技术,咱们的意图只是“解决方案”的一方面(技术侧),另外一方面显然是使用这些技术和工具产生的业务影响。
微前端能够真正帮助组织更快地行动,在业务领域内进行创新并隔离故障,同时我不反对任何形式或形状的总体应用程序,我不(彻底)反对集中化,尽管我常常看到任何类型的库都过于优化而没有真正关注业务的发展方向,但却增长了必定程度的无心义抽象,从而下降了开发人员的工做效率,而不是加速它。
因为团队不能过多地影响另外一个团队的工做,所以集中化一般会致使团队失望,由于外部依赖很难解决。
我知道有一些方法能够经过内部开源缓解这个问题,我也不能提供太多关于这种方法的看法,可是从我了解到的几个谈话和我有的聊天,对于在公司中使用内部采购的一些工程师而言,若是你有不一样代码库的共同责任,这绝对是一个很好的方法,若是你有这方面的经验,请随时评论这篇文章。
采起平衡决策是成功的秘诀。
最后,请记住 背景是理解决策的关键。 建筑师常常编写ADR(架构决策记录)。这些文件正在帮助公司中的任意员工理解为何作出描述上下文,可用选项,所选择的选项以及最终由此决定产生的后果的决策。
我常常看到人们判断其余公司或同事的决定,而不理解作出决定的背景,实际上,背景对决策自己更为重要,由于尽管它听起来很可怕或彻底不合适,但实际上可能有是该特定背景的最佳(或惟一)选项。
像往常同样,我愿意讨论,我相信人们会不一样意这篇文章中分享的一些观点,但这就是分享咱们的经验和信念的所有意义! 🤓