可扩展架构取舍

引言:“架构”是前端开发中一直以来都缺乏的。因为近几年Web应用日趋复杂,前端架构开始流行起来。成熟的工具使得开发人员能够针对要解决的问题设计出可扩展的架构。
构建可扩展的软件,能够从不少角度来思考软件架构。可是若是每一个角度都去考虑,根本不可能作出想要的软件。这就是为何须要从架构的角度对设计进行取舍:取咱们最须要的,舍次要的。
本文选自《大型JavaScript应用最佳实践指南》。前端

肯定不可变内容

  在作出取舍以前有一点很重要:列出那些不能舍弃的需求——咱们的设计的哪些方面对实现可扩展是相当重要的、不能改变的。好比,被渲染页面中的实体个数或者函数间接调用的最大深度就不能改变。虽然不可变的内容不会太多,可是它们确实存在。最好的办法是缩小这些内容的做用范围,减小它们的数量。若是有太多严格的设计原则不能被打破或改变以迎合需求,就不能更好地适应不断变化的可扩展性影响因素。
  考虑到可扩展性影响因素的不可预测性,没法改变的设计原则是否还有意义?答案是确定的,但只有在它们浮现出来,而且显而易见时才成立。因此这可能不是前期的原则,虽然咱们常常要遵照至少一两个前期原则。这些原则多是从早期代码重构或后期软件的成功中总结出来的。在任何状况下,这些不可改变的内容必须明确下来,并和全部相关人员达成一致。性能优化

从开发的便捷性考虑性能

  性能上的瓶颈须要在一开始就被修复或避免。一些性能瓶颈是显而易见的,会对用户体验形成明显的影响,这些就须要当即修复。由于这些瓶颈意味着咱们的代码因为某些缘由没法扩展,而且可能引出设计上更大的问题。
  其余性能问题相对较小,一般是开发者为了经过各类手段提升性能,对代码进行基准测试时发现的。这些没法很好地扩展,由于这些小的性能瓶颈没法被用户察觉,可是修复起来很是耗时。即便应用程序大小合理,又有很多开发人员,可是每一个开发人员都在修复这类小问题,就没法继续开发新的功能。
  一方面,这种细微的优化会引入对特殊状况进行处理的代码,而这类代码对于其余开发者来讲就没那么容易理解了。另外一方面,若是不进行这种细微的优化,代码就会相对简洁,容易维护。在必要时,需舍弃性能优化来保证更好的代码质量。这样才能加强咱们在其余方面提升可扩展性的能力。微信

性能的可配置性

  若是有几乎每一个方面均可配置的通用组件天然是极好的。然而,设计通用组件的代价须要牺牲性能。这在一开始只有少许组件时是没法察觉的,可是当软件功能、组件数量、组件配置项开始增长时,问题就显现出来了。随着每一个组件尺寸(复杂度、可配置项的数量等)的增加,组件的性能就会呈指数递减,以下图所示。
【图1】
  只要性能问题没有影响到用户,就能够保留配置选项。不过须要注意的是,可能会在消除某个性能瓶颈时不得不删除某些可配置项,不过可配置项不太可能成为性能瓶颈的主要来源。在不断扩大和增长功能的过程当中还容易过于投入,回顾起来你会发现,在设计时建立的自认为有用的可配置项,最终并无什么用,反而加大了开销。因此,当配置项没有带来确凿的好处时,为了保证性能,应该果断舍弃。架构

从可替换性考虑性能

  一个与可配置性相关的问题是可替换性。如今咱们的用户界面运行良好,可是随着用户数量和功能的增长,咱们发现某些组件没法轻易地被另外一个组件替换。这多是一个软件成长问题:想设计一个新的组件用来替换已有组件,或者可能须要在运行时替换某些组件。
  替换组件的能力基本上由组件通讯模型来决定。若是新的组件能够像已有组件那样发送/接收消息/事件,那么替换起来就至关简单了。可是并非软件的全部方面都须要能够替换,为了保障性能,可能根本没有可替换的组件。
  但当扩展应用时,可能须要考虑将大组件重构为较小的可替换组件。可是这样作会引入新的间接层,从而影响性能。不过牺牲一点点性能换来可替换性,能够帮助咱们在其余方面得到架构的可扩展性。框架

可寻址性的开发便捷性

  为应用程序中的资源分配可寻址的URI 必然会增长功能实现的难度。真的须要为应用暴露的每一个资源分配URI 吗?也许不须要。从保持一致的角度看,为每一个资源分配URI是合理的。可是若是针对某些资源,没有路由以及统1、易于遵循的URI 生成方案,那么更倾向于不为这种资源分配URI。
  为应用中的每一个资源分配URI 带来的负担是值得的,由于不支持可寻址资源更糟糕。URI 让咱们的应用和用户熟悉的其余页面表现一致。也许URI 的生成和路由在应用中是不可改变的、不可舍弃的,因此几乎老是牺牲开发的便捷性来换取可寻址性。相较于URI,开发的便捷性能够随着软件的成熟更深刻地解决。函数

性能的可维护性

  功能开发的难易程度最终取决于开发团队和可扩展性的影响因素。例如,可能出于预算的压力不得不招聘初级开发人员。这样是否能适应后期要求,则取决于代码。当须要考虑代码性能时,极可能会引入一些对于缺少经验的开发者难以理解的代码。很显然,这会阻碍新功能的开发。若是新功能开发难度比较大,那就会花费更长的时间,这显然不能适应用户的需求变化。
  开发人员并非总须要费力理解这些用来解决特定领域性能瓶颈的晦涩代码。固然能够经过编写高质量、易于理解的代码,甚至编写文档来缓解这个问题。但这一切都是有代价的,随着团队的壮大,须要短时间内完成对开发者的培训、指导,这些都是在生产效率方面须要付出的代价。
  在关键代码上常常是优先考虑性能而不是开发的便捷性。不能老是逃避代码性能带来的代码丑陋,可是若是这些丑陋的代码能很好的被隐藏,就能够获得更易理解和自解释的代码。好比,底层JavaScript 库性能良好,API 紧凑易用,可是若是你看一下底层的源码,就会发现并非那么优美。这就是咱们的收获——让别人维护出于性能缘由而看起来丑陋的代码。
【图2】工具

减小功能以提升可维护性

  当全部其余手段都失败时,须要退后一步,全面审视应用中的全部功能。架构是否可以支持全部的这些功能?把投入了大量时间来开发的架构废弃掉是毫无道理的,但也确实会发生。大多数时候,会被要求实现一组颇具挑战的与咱们结构相悖的功能。
  这种状况发生时,其实是在打乱现有的稳定功能,或者在应用中加入一些低质量的东西。两种状况皆无益处,但值得投入时间,花费精力,与投资人沟通以决定哪些必须被删除,尽管这个过程并不愉快。
  若是已经作出折中的选择而且花时间理清了咱们的架构,那么应该有一个合理的理由来解释为何咱们的软件不能支持上百个功能。
【图3】性能

利用框架

  框架的存在是为了经过采用一套紧密聚合的模式,帮助咱们实现架构。框架具备极大的多样性,选择哪一个框架是由我的偏好以及与设计的契合度来决定的。例如,一个JavaScript应用框架能够实现更多创造性,而另外一个框架拥有更多功能,但其中大部分功能是咱们不须要的。
  JavaScript 应用框架有不一样的大小和成熟度。有些内置了不少套件,有些则倾向于机制而非政策。没有一个框架是专为咱们的应用设计的,对于每一个框架所声称的功能要持有存疑态度。框架标榜的功能只适用于简单的通常状况,而在咱们架构中的应用则彻底是另一回事。
  尽管如此,固然能够用一个本身喜欢的框架做为设计过程的输入。若是咱们真的喜欢这个工具,团队也有使用经验,可让它来影响决策者。只要咱们明白,框架不会自动地响应扩展影响因素,由于这个部分是由咱们来负责的。
  本文选自《大型JavaScript应用最佳实践指南》,点此连接可在博文视点官网查看此书。
                     图片描述
  想及时得到更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。
                       图片描述测试

相关文章
相关标签/搜索