前端架构之熵

前言

架构,又名软件架构,是有关软件整体结构与组件的抽象描述,用于指导大型软件系统各个方面的设计。 架构描述语言(ADL)用于描述软件的体系架构。

在谈这个话题前, 首先回答一个问题, 前端需要架构吗?

架构从概念上包含三个部分, 一个是整体结构,另一个是个体,还有就是个体之间的关系。 本质上来讲, 只要复杂的软件系统就需要架构, 因为复杂度会带来“熵”,不利于项目整体的开发和维护,容易滋生潜在的问题。当然架构也不是银弹,在不同的软件体系里架构所做的是一个权衡, 在不同的方面做取舍,达到一个动态的平衡。那么对于前端来说,复杂度体现在哪些方面?

  • 页面多
  • 业务逻辑复杂
  • 终端类型多: 不同的浏览器内核,分辨率,ES规范支持度
  • 请求多:资源文件,异步数据,WebSocket等
  • 第三方的服务
  • 浏览器插件交互:截图,获取数据,网络代理等
  • 网络安全:XSS,CSRF,SQL注入

以上我只是列举了一部分内容,在现代化的大型开发项目中,大家可以看到前端的复杂度可能已经超过了后端的复杂度,所以说前端目前需要架构。

前端发展历程

  • 单web页面

    在这个时代页面所有的逻辑都放在一起,一个页面包括所有的JS/CSS/HTML, 甚至是后台代码,典型代表:ASP/JSP/PHP等

    • 优点:整体页面逻辑清晰,方便修改
    • 缺点:不利于多方协作开发
  • 逻辑展现结构分离

    随着页面逻辑越来越多,但页面已经无力维护,这时候需要迫切拆分样式(CSS)和逻辑(JS)、以及结构(HTML),并分别维护

  • 优点:分离关注点
  • 缺点:业务逻辑还是放在一起,不易维护
  • 组合和插件化

    业务逻辑变得越来越多,单个JS已经无法支撑,这个时候迫切需要对逻辑进行拆分,以适应复杂页面的需要。拆分的总体思路是提供一个基础的系统,对外扩展开放,对内修改关闭,就是常说的开闭原则。常见的做法有两种方式:

  • 提供一个Base基础类,然后基于Base类进行Compose扩展新功能, 如:TroopJS
  • 提供一个微内核,外围功能通过插件的方式注入,如:jQuery UI

优点:面向变化
缺点:无法体系化和规范化

  • AMD/CMD/UMD/MVC/MVVM/ES Module

    项目中外围功能越来越多,单纯的插件和组合方式已经难以满足业务的需求, 最明显的一个问题是首次加载的库依赖过大,另一个是项目如果对第三方有依赖,很难按照统一的规范来引入。所以在这个阶段出现了:

  • AMD:异步模块依赖加载,解决浏览器端模块加载和模块规范问题, 例如: RequireJS
  • CMD:通用模块依赖加载,用于服务端module加载, 例如:NodeJS
  • UMD:统一模块依赖加载,主要解决多端统一模块加载规范, 例如:Rhino/NodeJS/浏览器端用同一套规范
  • MVC:后端的经典架构模式, 拆分Model/View/Controller,职责模块分离。 例如:Backbone/Konckout
  • MVVM:在MVC的基础上去除了Controller层,增加了ViewModel层,主要解决Model和View变化响应的问题, 典型代表:AngularJS 1.0
  • ES Module: ES6自带模块加载器

优点: 模块拆分清晰,加载分明,外部依赖加载规范
缺点:每个模块的JS和CSS修改需要到统一的目录去修改,对于公用的模块加载还是会有冗余, 对于复杂项目无法快速拼装

  • 组件化

    组件化的发展起源于Facebook,由于Facebook页面Widget非常的多, 每个Widget加载都有相关的细粒度的依赖,所以Facebook提出了BigPipe的概念,把页面的每个部分分别作为一个独立的部分异步加载, 包括JS和CSS。随着项目的推进和不端规范化, 开源了React组件开发框架。React的优秀之处在于几个创新:VirtualDom,数据彻底分离出去,把JS/CSS/HTML当成一个组件处理。这样做的好处显而易见:

  • 页面按需渲染
  • 搭积木的方式构建
  • 不包含业务逻辑
  • 响应式变化

作为后起之秀的VueJS, 充分吸收了React的VirtualDom概念,并提供数据双向绑定机制, 通过依赖跟踪Check提高了脏检查的效率,同时在API层做到了精简,拨洋葱式的架构组合,在选择上灵活多样。

未来的发展趋势

  • 组件标准化: 随着WebComponents标准的建立和Polymer等优秀框架的实践,在前端的架构体系和标准化方面逐渐完善
  • 服务本地化:以Amazon Lambda服务为首的Serverless概念对于前端开发是一个大的变革,结合ServiceWorker打造PWA应用是一个应用趋势
  • 语言静态化:JS最为人诟病的是运行时异常, 通过引入类型系统做到在开发时异常检测,避免线上出现未知的运行时异常, 主要代表: TypeScript/Flow/Elm
  • 构建智能化:自动解析前端的资源文件,第三方的依赖并打包,不同环境的代码自动化部署、测试、集成,以及前端AI等技术的出现会在一定程度上会改变现有的前端开发流程
  • AR/VR:WebAssembly将会是的浏览器端能够负担更多的底层工作,对于内存管理更加高效,对于复杂高密度的工作放在前端执行增加了可能性, 典型的应用:VR/AR游戏,实时视频电话会议等

结语

前端的复杂性表现在各个方面,这里篇幅有限,介绍还不够细致。不过可以肯定的是,作为前端开发人员,已经远远不是会写JS代码这么简单,需要不断的参与到社区的学习中去,并加以实践,总结提炼出适合项目的架构方式, 提高自己开发和协作效率变得尤为重要。接下来,我会带领大家逐个学习前端的方方面面,体验前端开发的乐趣, 敬请期待

由于水平有限,有不当之处请批评指正,一起学习!