写给后端开发工程师的 H5 前端开发知识
一、引言
web 发展到目前为止已经有将近 30 年的历史,在 web 兴起的早期,并没有前端这个概念。最初所有的开发工作都是由后端开发工程师完成,随着业务越来越复杂,工作量逐渐的增加,项目中的可视化部分和一部分交互功能的开发工作逐渐从业务中剥离出来,形成了前端开发。大约在 2000 年左右,雅虎等公司开始设立前端工程师职位,从 2005 年开始,正式的前端工程师角色被行业所认可,到了 2010 年,互联网开始全面进入移动时代,前端开发的工作越来越重要,前端领域的技术发展也越来越快,各种新的思想、设计模式、工具和平台都快速发展,对前端工程师的技能要求也越来越高。此时国内各大互联网厂商也都设立了前端开发工程师的岗位。
那么什么是前端工程师?这里可以拆分“前”和“端”来理解,“前”很好理解,相对于“后”的概念,而“端”则有不同的含义,如下图所示:
![](https://static001.geekbang.org/infoq/47/471417c28794e7307346c75aecedc3cb.png)
广义上讲,所有负责在端布局、排版、展示页面的工程师,都可以称为前端工程师。不同的端使用不同的语言,其中:
在浏览器端,使用 JavaScript、HTML 和 CSS 语言开发
在 IOS 端,使用 Swift 或 Objective-C 语言开发
在 Android 端,使用 Java 语言开发
在微信端,使用小程序开发
由于浏览器是历史最久远、最出名的端,所以将使用 JavaScript、HTML 和 CSS 语言,在浏览器端负责展示页面的工程师,称为前端工程师。
二、入门阶段--web 基础
1、web 三层结构
在 web 1.0 信息共享时代,web 发展的第一个阶段就是静态技术阶段,在这个阶段,HTML 语言就是 Web 向用户展示信息的最有效载体。此时常见的写法就是将 HTML、CSS 和 JavaScript 代码掺杂到一个单独的文件中,命名为 index.html,并称其为网页。今天仍然有很多网页将 HTML、CSS 和 JavaScript 代码写在一个文件里面,但是当网页内容逐渐复杂之后,不同的代码写在一个文件里面会使文件内容变得越来越臃肿,难以维护,于是出现了 web 三层结构的概念。web 的三层结构如下图所示:
![](https://static001.geekbang.org/infoq/7d/7da67d52366bf0ca479b3f053398f855.png)
结构层:即 HTML 标签,标签互相组合,构建了网页的基本结构;
表现层:即 CSS,为标签添加样式,比如标签的颜色、大小、位置等等;
行为层:即 JavaScript,用来实现网页上的特效效果,可以在 script 标签中动态修改页面。
在同一个网页中,对不同层的代码进行分离,可以在不同的项目中共用通用的代码模块,减少代码的冗余。当然如何更加合理的对不同层的代码进行拆分,需要根据不同的项目具体分析并探寻代码拆分的最佳方案,这里就不过多的去阐述了。
2、DOM 与 BOM
在前端领域 DOM 和 BOM 这两者的概念非常重要。DOM 是文档对象模型,即把文档当做一个对象来看待,主要处理网页内容的方法和接口;BOM 是浏览器对象模型,即把浏览器当做一个对象来看待,与浏览器交互的方法和接口。两者的关系如下:
![](https://static001.geekbang.org/infoq/ef/ef35801f07c2ef6d244b723db34ec822.png)
BOM 的核心对象是 Window,比如访问屏幕物理分辨率的宽和高,如下:
DOM 的根本对象是 document,这个对象是 window 对象的属性,即 window.document,可以通过 document 对象获取文档中的节点同时也能操作节点,如下是一棵简单的文档对象树:
![](https://static001.geekbang.org/infoq/90/903595e3d911991435d74a9f128cc9ce.png)
可以通过属性 id 获取 a 标签文档节点对象,如下
也可以直接给 a 标签添加属性,如下:
3、前端基础体系
![](https://static001.geekbang.org/infoq/5f/5fb4a49c58e966d8251b1b9e41a72b96.png)
上图主要展示做为前端开发在前端的基础体系里面需要熟悉的基础内容,实际前端基础体系相关内容的细分或者扩展远比上图汇总的多。
三、进阶阶段--单页应用与微前端
1、AJAX 与单页应用
在 Web1.0 阶段,服务器会返回整个页面或者文档,前端页面想要获取后台数据需要刷新整个页面,这是很糟糕的用户体验。进入 Web2.0 之后,动态网页逐步发展,其中最主要的代表性技术是 AJAX,AJAX 允许客户端的 JavaScript 脚本为局部页面内容提供请求服务,然后可以在无需回到服务器的情况下动态刷新部分页面内容,也就是更新浏览器中的 document 对象,即 DOM。在 Web2.0 阶段加强了网站与用户之间的互动,网站内容基于用户提供,网站的诸多功能也由用户参与建设,实现了网站与用户的双向互动交流。
在 2004 年和 2005 年,Google 分别发布了两款重量级的 Web 产品:Gmail 和 Google Map,都大量使用了 AJAX 技术。随着 AJAX 技术的流行,越来越多的网站使用 AJAX 动态获取数据,这使得动态网页内容变成可能,加上当时 CDN 开始大量用于静态资源存储,于是出现了 SPA (Single Page Application 单页面应用),大致的模式如下图所示:
![](https://static001.geekbang.org/infoq/b3/b3cab89c9f548eef201fb8983bffab70.png)
如上图所示,在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS,一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转,取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。这样 SPA 存在的优点如下:
前后端分离开发:前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理,单页 Web 应用可以和 RESTful 规约一起使用,通过 REST API 提供接口数据,并使用 AJAX 异步获取数据;
良好的交互体验:能提升页面的切换体验,用户在访问应用页面不会频繁的去切换浏览页面,从而避免了不必要的跳转和重复渲染。
单页应用的开发模式实现了前后端的分离,使得整个业务系统架构变得清晰,可以单独开发和测试。但是当中后台单页应用有多个不同的子模块,并且子模块之间有相对独立完整的功能体系时,一旦子功能模块越来越多,那么整个单页应用将变得非常庞大且臃肿,开发和维护成本将大大提高,如果在这种场景下,还在用 SPA 的模式开发,那么项目后期的维护将变得不可想象,这个时候微前端的概念应运而生。
2、微服务与微前端
提到微前端就离不开微服务,后端同学对于微服务应该非常的熟悉,微服务允许后端体系结构通过松散耦合的代码库进行扩展,每个代码库负责自己的业务逻辑,并公开一个 API,每个 API 均可独立部署,并且各自由不同的团队拥有和维护。其带来的好处是:
将一个庞大的单体拆解成多个子服务,大大降低了开发复杂度;
任务边界划分明确,每个子服务之间单独开发,不同服务之间可并行由不同的开发人员开发,提高开发效率;
更细粒度的加强了模块化进程,可维护性和可读性更高;
每个微服务可独立部署发布,使得自动化 CI(持续集成)/CD(持续交付)成为可能。
微前端的思路是把微服务的架构引入到前端,主要应用于浏览器端,其核心是对 web 应用进行拆解,最后将不同子系统或者子模块聚合成一个完整的应用。在早期,也可以使用 iframe 嵌套的方式实现单个应用集成多个独立的功能模块,以目前客服域一站式工作台现有的架构所示:
![](https://static001.geekbang.org/infoq/f4/f436cb5e3c47070671c2222bee161084.png)
如上图所示,红色部分是通过 iframe 嵌入的模式集成到工作台里面的。通过 iframe 嵌套的方式,在一站式工作台里面遇到了较多的问题,主要问题如下:
坐席辅助创建工单模块,一线客服的切换频率与操作流程都非常快,不同模块通过 postMessage 消息通信的时候,存在延迟的现象,导致工单数据串位;
工单详情使用的频率非常高,每次打开都需要重新加载静态资源,渲染效率低下,使用体验比较差;
一线客服一般都会同时打开多个工单详情或者订单详情的 iframe,过多的 iframe 占用浏览器内存比较大,导致消息发送卡顿,影响用户首响时间。
基于上面几个问题,目前运用微前端的设计思想正在重构优化的客服域一站式工作台架构如下图所示:
![](https://static001.geekbang.org/infoq/76/76b3e8c5fffebd75064054fa57c057cd.png)
通过上图将每个单独的功能模块拆分成不同的子应用,如工单工作台是一个子应用,热线服务是一个子应用,不同的子应用独立运行,互不影响,子应用共享主应用的资源,不需要每次重新加载静态资源,每个子应用都可以独立发布和部署。
四、高阶阶段--向全栈转变
在 web 技术兴起的很长一段时间里,前端开发工程师想要去开发服务端的代码,就必须去学习 JAVA 或者 PHP 等后端语言,自从 2009 年,Node.js 兴起之后,JavaScript 开始有能力运行在服务端,之前需要后端工程师使用传统后端语言完成的很多工作,理论上前端工程师都可以在 Node.js 创造的运行环境中使用 JavaScript 完成,此时全栈开发工程师也逐渐被行业所认可。在 Node.js 兴起至今,凭借其高性能、易部署等特点在前端领域脱颖而出了很多明星项目,比如 BFF 和在前端工程化上的实践。
1、什么是 BFF
BFF,即 Backend For Frontend(服务于前端的后端),也就是服务器设计 API 时会考虑前端的使用,并在服务端直接进行业务逻辑的处理,又称为用户体验适配器。BFF 只是一种逻辑分层,而非一种技术。BFF 的出现为前端应用提供了一个对业务服务调用的聚合点,它屏蔽了复杂的服务调用链,让前端可以聚焦在所需要的数据上,而不用关注底层提供这些数据的服务。
试想下如下场景:某个页面需要向服务 A、服务 B 以及服务 C 发送请求,不同的服务返回值用于渲染页面中不同的组件模块,即一个页面存在很多请求的场景。此时,每次访问该页面都需要发送 3 个请求。同时为了保障 Android,iOS 以及 Web 端的不同需求,需要为不同的平台写不同的 API 接口,而每当值发生一些变化时,我们需要在每一个客户端(Android,iOS,Web)分别实现一遍,这样的代价显然相当大。而当我们有了 BFF 这一层时,我们就不需要考虑系统后端的迁移,后端发生的变化都可以在 BFF 层做一些对应的修改,具体如下:
![](https://static001.geekbang.org/infoq/12/12b12ad649c6491806cbb9030f27b04f.png)
如上图所示,加入 BFF 层,原本每次访问发送 3 个请求,变成了一个请求,BFF 层会提前将多个服务的数据聚合起来,返回给前端。
备注:上面只是通过一个简单例子来阐述 BFF 分层带来的好处,实际复杂的业务场景对 BFF 的设计会复杂很多。
2、前端工程实践
前端工程化主要基于 Node.js 开发,Node.js 适合用于开发前端方向的各种工具。如包管理工具 npm 上集成了各种工具模块,包括各种前端预编译工具、构建工具、脚手架以及命令行工具等。其主要的应用场景如下图所示:
![](https://static001.geekbang.org/infoq/07/07a168a6864dd31689b53e4a151d4748.png)
五、前后共勉--总结
前端不要局限于 html、css 和 javascript,需要了解服务器和数据库相关的知识,这样和后端评审技术方案的时候,才能提出一些合理的建议;
前端需要了解数据,把控数据之外的业务逻辑,而不仅仅只是聚焦于页面的展示;
后端需要了解前端相关的知识,考虑页面渲染需要什么样的数据结构,这样在设计 REST API 的时候,才能输出合理的数据结构给到前端页面渲染;
后端需要具备一定的前端技能,在前端完成组件化输出到物料库之后,后端能基于物料库的业务组件完成页面的搭建,提升研发效率。
以上只是站在多年前端开发的视角,阐述了后端同学需要了解的相关内容,实际前端内容远比文章描述的多,比如移动端、布局排版、Hybrid、小程序、PWA 以及 Serverless 等等都属于前端技术领域,路漫漫其修远兮,吾将上下而求索,希望本文能给后端开发同学带来一些帮助和启发,也能让前端开发同学对前端知识有更好的认识。
六、参考文档
文/Bill
关注得物技术,做最潮技术人!
版权声明: 本文为 InfoQ 作者【得物技术】的原创文章。
原文链接:【http://xie.infoq.cn/article/00c4a076d3a7b6409db128674】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论