查看原文
其他

【第838期】微影时代前端的技术架构

2017-02-06 尹锋 前端早读课

前言

周一了,应该都上班了吧,要是还在放假的童鞋,你们可以爆出你们公司名称了。今天早读文章由微影时代前端基础平台建设部负责人@尹锋分享。


正文从这开始~


技术架构不是面向具体功能的,而是面向业务开发团队的需求,解决开发共性,简化开发流程,提供一个舞台,业务开发团队在舞台之上放肆舞动。架构是体系化的,完备的,能够满足一类软件全部元需求的运行平台和构建平台,具体功能运行于其上。


前端技术架构的范畴


如果一个 4年前的前端穿越到现在,就会像一个清末年间的内地人来到了民国期间的上海,完全是另一幅模样,茫然不知所措。所以隔壁部门老王经常问我们,你们前端一天一个样,最近又在搞啥。


前端领域风云涌动,移动终端领域突飞猛进,前端的知识领域已由之前的三剑客(HTML、CSS、JavaScript)发展到现在的大前端,开发方式也由简单的切页面发展到工程级协作开发方式。如此快和剧烈的变化,超出你和我的预期,就像爬山的时候,觉得自己已经登上青峰之巅,然而拨开云雾,发现只是一个小土堆,崇山峻岭就在不远处,再征服两座高山之后,发现自己已经老了……


如果现在还使用传统的开发方式,效率将极其低下,所以我们需要一套前端技术架构来指导开发。


一个完备的技术架构应该包含以下几个方面:

  • 流程规范(涵盖开发、测试、构建、部署、运行的各个环节)

  • 技术栈

  • 组件库(UI 组件库,业务组件)

  • 部署流程

  • 监控体系


从 2015年年底开始,在接触了几个业务产品线以后,我们开始来构建这个体系。前端架构体系归根结底是要围绕业务发展、团队规模和团队特点量身打造的,主要目的是为了提升团队整体的研发效率,提高网站的加载速度,确保线上的质量和稳定性。说这么多其实就是为了两件事:一是为了更好地写代码,二是为了写出更好的代码。


前端开发模式


考虑到公司的产品形态,业务逻辑越来越复杂,整个网站已经越来越大,加上前后端耦合比较严重,很多功能和优化已有心无力,所以引入 SPA 的 开发方式。整个站点是一个单页,以前的每个页面会拆分成一个一个的逻辑页,首页仅需加载核心部分 JavaScript,逻辑页按需加载当前页面的 JavaScript 和本页面需要的数据,逻辑页面之间还可以共用数据。在底层做好 JavaScript 文件加载、路由控制、数据请求和封装,对于业务开发来说,这些都是透明的,只需要关注上层业务开发即可。


经过一番预研和 DEMO 之后,决定基于 React  & Redux 来构建整个技术栈。前端底层是数据逻辑层,使用单一数据源,基于 Redux 实现,管理整个 Web App 的数据 model 和业务逻辑,处理与服务器端数据交互,以及数据的加工。上层为 UI 层,完全采用组件化的开发方式,React 天生就处理这个事情。同时我们根据视觉部门提供是设计稿,整理出一套前端 UI 规范,抽离出了前端基础组件,这极大的提高了后期的开发效率。


整体服务关系图如下,A、B、C 为逻辑页面


按照业务逻辑来组织 State,那么就可以设计如下的数据结构:


这样,所有的数据结构一目了然,方便理解和记忆。数据存储好了以后,所有的页面都从这个 State 里面获取数据,如果使用传统的 select 来计算,当页面比较大的时候,会存在性能问题,所以引入了 Reselect。Reselect 库能够创建可记忆的、可组合的 selector 函数。Reselect selectors 可以用来高效地计算 Redux Store 里的衍生数据。


所以,我们在 State 和页面中加了一层 selector。在 selector 里面在组装页面需要的数据以及数据的计算,这个数据可能会来自多个业务 model。比如说,在选座页会呈现出影片的信息、影院的信息、座位图的信息,就可以从三个业务 model 中获取数据,然后计算,传递给选座页使用。


构建方式


鉴于目前的 ECMA 标准委员会是一个非常靠谱的委员会,发布非常靠谱的 ES6,该委员会旨在 ES6 之后短短的 12 个月内发布 ES7,随后该标准将形成每 12 个月发布一个版本的节奏。


所以我们使用 ES6 和 ES7 来编写我们的项目,对滴,我们已经开始在线上项目中引入 ES7 了。使用 Babel 来编译代码,以转换成浏览器兼容的 ES5代码,使用 NPM 作为包管理工具(现在已经升级为 Yarn), 使用 Webpack 打包构建,他可以将任意资源作为一个模块来引用和处理,降低了资源处理的复杂性,使用 Sass 座位 CSS 的预编译工具,使用 ESLint 作为代码检查工具,保证代码一致性和可读性。


以上所有我们封装到一个命令行工具 Pepper。使用 Pepper,开发者可以快速构建出一个基础项目,一个页面,一个组件,启动一个小型的本地服务(本地开发是使用到)调试代码,构建打包代码。不用关注 Webpack、不用关注 Router,不用关注资源按需加载,不用关注静态资源优化······所有这些都已经封装好了,开发者只需要开发上层业务代码就好(React & Redux & Sass 还是需要学习的),瞬间觉得世界就清静了。


部署流程


这里的部署包括测试环境、预上线和线上环境的部署,这是前端技术架构不可缺少的一环。为了提高产品测试研发的整体开发效率,我们设计出了一个页面,用户只要一点,就能够进入到对应的环境中去。

其核心就是所有环境访问域名一致,都是 http://wechat.show.wepiao.com ,(这样也方便在测试环境测试分享、支付等对域名有限制的项目,甚至可以在4G 网络下访问测试环境)然后通过一个 cookie(cookie 的 key 为 env) 标识需要访问的环境,上面那个页面就是来配置这个 cookie 的,当选择了一个环境后,会将该环境对应的值种到 cookie env 中,Nginx 通过解析这个 cookie,然后把请求 proxy_pass 到对应的那个环境去。


实战


说完了技术架构,想说一下今年的两个重点项目,这两个项目是经过几波人维护后的代码,可维护性或者高并发存在比较大的问题。


微信演出票:重构前,演出票是后台 PHP 渲染,前端提供模板,同时前端也有很多业务逻辑,前后端耦合很严重,重构与前后端分离并行进行,同时还上线了爆款项目 BigBang,上线后抗住了巨大访问量,同时在线人数高达158万,以及针对爆款项目的防黄牛设计,有效狙击黄牛党,维护粉丝利益。


微信电影票:电影票重构和后台接口重构、升级 HTTPS 一起上线,上线后,性能不降反升,首页性能有比较大的提升,打开时间减少了20%,后续的页面访问特别快,只有稍许延时,页面间前进后退的切换更是顺滑,就像德芙巧克力一样,可通过文末左下角“阅读原文”体验。


除了微信电影票演出票项目以外,Pepper 还支撑手 Q 电影票演出票和格瓦拉电影等线上重要项目。


做基础建设,最难的一点就是是否真的解决了业务线的需求,以及能够实施落地。幸运的是,我们都是在两三个高级工程师的指导下,领着五六七八个 React 新手,完成微信电影票和微信演出票的重构工作。


架构设计一定要降低开发的复杂度,需要考虑多方面的关注点。漂亮的架构设计让这些关注点尽可能分离,然后以最简单的机制结合在一起,从而得到高内聚、低耦合的系统。并且考虑到开发团队的实际情况,大部分团队都会是少数高级工程师和多数普通工程师,如何让他们快速进入角色,完成业务开发,这是非常重要的一点。


重构之后我们和老项目进行了一个对比

  • 代码量减少至                  30%

  • 客户端请求大小减少至   24%

  • Nginx 流量减少至           5.5%


代码量(HTML,CSS,JavaScript)减少至30%,这意味着可维护性的提高,同样的团队我们可以实现更多的产品需求。后两个是因为静态资源全部部署到 CDN 上了,所以流量都打到 CDN 了,这样能够大量减少后台服务的带宽,提高服务并发数。


自动化 & 组件化


我司前端团队目前近50人的规模(其中基础工程建设团队不到10人,招资深前端开发哦),通过自动化、组件化的开发方式,极大的提高团队生产力,让工程师不需要关注底层的实现,聚焦在业务开发、技术创新上。因为使用一致的技术栈,从而能够在技术上积累和深耕。


不忘初心,不畏将来,这是2016年阿里 D2 会议的口号,我觉得确实能反应当下前端的情况,前端发展迅猛,Web 全端全栈势不可挡。作为距离用户最近的工程师,我们应该去构建去优化我们的技术体系,为用户提供更优的用户体验,支撑业务的快速发展。


最后,推荐看看美团酒旅的技术架构:

【第778期】美团点评酒旅前端的技术体系


关于本文

作者:@尹锋

原文:http://dwz.cn/5daYHz

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存