vlambda博客
学习文章列表

阿水说前后端分离(篇一)

阿水说前后端分离(篇一)

java web开发的演变

旧石器时代 - Servlet

在旧石器时代,连jsp都还没有,为了实现动态html,是在servlet中把html当字符串来拼接,如下面代码所示:

import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HTML>"); out.println("<HEAD><TITLE>Hello World</TITLE></HEAD>"); out.println("<BODY>"); out.println("<H1>Hello World</H1>"); out.println("Today is: " + (new java.util.Date().toString()) ); out.println("</BODY></HTML>"); } // doGet} // HelloWorld

笔者有幸,很多年前有在真实项目中见过上述写法,通过servlet拼接出一个页面,脑补当时前辈敲代码的场景,敬仰之心,有如滔滔江水,连绵不绝。但是这种写法实在是太啰嗦,生产效率太低。

新石器时代 - JSP

于是有识之士就提出:“It's time to separate the view from the logic”。我为啥要用字符串的方式拼一个html出来,html本来就是标签化,我无非是要扩充html的标签,html是静态的,我可以增加一些动态标签,动态的将数据与html元素绑定,在服务端将动态页面解析为静态html。这是一个多么好的方案啊,我们就叫它JavaServer Pages吧。如果用jsp的方案来重写上面的hello world,写法为:

<HTML> <HEAD> <TITLE>Hello World</TITLE> </HEAD> <BODY> <H1>Hello World</H1> Today is: <%= new java.util.Date().toString() %> </BODY></HTML>

上述写法的生产率比当年servlet拼接字符串的方式不知提高了多少,而且IDE也能支持jsp的编写,代码补全,编译警告等。

随着时间推移,jsp的弊端也逐步体现,有两个问题是该技术方案最突出的。

jsp里同时有html、java/jsp语法。前端开发同学不了解java,后端开发同学对前端html/css掌握的也一般。所以开发模式是前端同学写好静态html,后端开发同学将html改为jsp,当中的静态模拟数据改为动态标签。后期维护更麻烦,改着改着样式啥的就有些乱了,前端人员又调试不动jsp,只能在浏览器调试后,再和后端开发人员找对应的jsp里可能是哪的问题。数据的动态变化。采用jsp的方案,都是服务端渲染(SSR),比如有个列表页面,点击下一页的话,没办法,全页面刷新。后来ajax流行起来了,明明可以只获取下一页的数据即可,前端页面元素都可以用之前的,这样既减少网络请求的大小,也可以减少页面元素的重新生成。

青铜时代 - Ext.js

基于此,Ext.js就开始流行起来了,十几年前实习时,第一次见Ext.js,当时觉得这种技术方案太先进了,前端常用的控件都封装成一个个模块化的组件,像Ext.grid.GridPanel,Ext.FormPanel,组件可以继承后进行扩展。像Ext的列表控件,可以绑定dataStore,调用reload方法时通过ajax去后台取数据,Ext调用render方法将加载回来的数据渲染到页面。

当年就是靠着这本书在实习期做了一个浙江移动的项目。

当年Ext.js在前端框架的地位就如现在react、vue差不多,在这种情况下,Ext.js在2010年成立了一家叫Sencha的公司,想搞商业化,其开源社区逐渐没落。

2011年4月,Sencha发布了Ext JS 4.0,结果这个版本刚发布时有严重的性能问题,花了好几个月时间才逐步完善解决。同时JQuery也越来越流行起来了。ExtJS与Jquery相比,有几个明显的弊端

封装过多,一提起ExtJS大家的第一反应是比较重,灵活性和自定义没那么方便。一般用ExtJS做的系统,如果不是把样式重写,长的都差不多,跟当年vista

JQuery提供了非常强大的选择器,便于去修改页面,这对于交互性系统非常灵活简便ExtJS商业化后开源社区逐渐没落,而JQuery有非常丰富的第三方插件可供选择Ext对于跨浏览器的支持没有JQuery完善


按照最新的情况,使用ExtJS的网站数是14634,而用JQuery的是10272406,相差将近1000倍。

白银时代 - JQuery

JQuery创立的理念就是:Writing Javascript code should be fun。它有两个主要的价值主张

提供简洁易用的操作页面的API浏览器兼容

Jquery在开发中用起来的确很顺手,开发效率比之前用原生js或者ExtJS框架有大幅提高。在Jquery的顶峰时时期,约有74%的网站在使用JQuery,妥妥的NO.1。不过近些年,Jquery的流行度开始下降,GitHub去掉了Jquery,Bootstrap v5也计划去除对Jquery的依赖。这个情况主要有以下几个原因:

浏览器的差异性开始变小,主流的浏览器厂商 (Apple, Google, Microsoft, and Mozilla) 通过 Web Hypertext Application Technology Working Group这个组织在web标准上开展合作。微软从edge开始已经放弃了自己的内核,改用Chromium内核。而且各浏览器也借鉴了一些JQuery的API,很多JQuery的API现在浏览器都可以原生提供,如果感兴趣的可以上http://youmightnotneedjquery.com/进行了解ReactAngularVue为代表的新的MVVM框架的诞生。这些框架较Jquery比有两个显著的改进更方便的将UI拆分为components不仅仅可方便的用于更新页面,也能用于初始渲染。而之前用Jquery的时候,通常是在后台用thymeleaf、jsp或者其它方案在后台进行初始渲染双向数据绑定,将数据和UI分离,研发人员只需要考虑更新数据,至于怎么渲染出来,你不用管,交给框架就行。

想当年,前端为了动态增加元素,常常要用jquery选择器获取dom后进行delete,再append新的元素,给大家看一段当年的代码

 var dsrDom = $("<table>").addClass("fd_table_form_01 fd_table_form_06 dsrItem").attr("usertype","2").attr("id",domId); var strLines = []; strLines.push( "<tr>" + " <th class='th_header' colspan='4'>" + " <div class='th_cell th_cell_title'>" + " <span class='sp_title sp_zrr'>"+SSWY.htmlEncode(dsrData.CName)+"</span>" + " <span class='sp_operate' " + displayStyle(display) + ">" + " <a href='javascript:handleEditDsr(\""+domId+"\")' title='编辑' class=' btn_edit'>编辑</a>" + " <a href='javascript:handleDeleteDsr(\""+domId+"\")' title='删除' class=' btn_delete'>删除</a>" + " <input name='dsrItemInfo' class='dsrItemInfo' type='hidden' />" + " </span>" + " </div>" +  " </th>" + "</tr>" + "<tr>" + " <td class='td_label_title fd_width_fix_130'><label for='' class='td_label_title'>当事人类型:</label></td>" + " <td class='fd_width_fix_250'><div class='fd_cell'>法人</div></td>" + " <td class='td_label_title fd_width_fix_130'><label for='' class='td_label_title'>单位性质:</label></td>" + " <td class=''><div class='fd_cell'>"+HtmlUtil.displayCodeName(dwxzCodeList,dsrData.NDwxz)+"</div></td>" + "</tr>");

当时我接手这个项目时,其实内心是拒绝的,改吧,真难受,重构吧,工作量太大,这种面向字符串编程的方式实在是效率太低了,跟当年servlet拼页面如出一辙。为了让自己后续维护不那么难受,我选了handlebars来做语义化模板,拒绝做字符串拼接,同时开始了解一些MVVM框架。好久没用到handlebars了,不知道它现在还好不。

黄金时代 - Angular/React/Vue

MVVM三巨头应运而生,16年的时候,我从一些技术博客上了解到这几个框架热度逐渐上来了。当时公司内部已经有项目开始用MVVM框架了,一个用的是Angular,另一个用的是司徒正美大牛开源的avalon.js。17年的时候我们就考虑在这四个框架中选一个做为公司统一的前端框架。

当时公司有两个架构师倾向于Angular和avalon。公司的前端架构师选Angular的原因是google开源,大厂有保障,理念“先进”。另一位同事选avalon的原因只有一个,兼容IE6。我对比之后,站在一个后端工程师的角度,倾向于vue。理由有二:

angular涉及的概念太多,学习曲线陡峭(其实就是我学的有些懵逼),如果后续是做组织上的前后端分离,前端工程师只做前端,后端工程师只做后端的话,还好。如果全栈的话,想让后端工程师了解这么复杂的概念比较难。avalon一定不能选,这个属于司徒正美的个人英雄主义作品,而且它的核心优势就是支持IE6这个远古时期的浏览器。国内的开源,能不选尽量不选,社区不成熟,而且除非最后贡献给apaceh基金会,否则不可能能存活下去,只会成为闭关锁国的畸形产物。

综合比较,vue的社区成熟,虽然创始人尤雨溪是中国人,但是是在美国期间开发的vue,本身就是一个国际化的产品,而且其API极为简单,我学了一天就能上手开发,比jsp还简单。

为什么尤雨溪开发的框架反而能比google一堆大神开发的框架更简单易用,我猜测是,google那帮大神对简单的定义和普通程序员对简单的定义会有区别,他们会认为,Angular都这么简单了,你还说学习曲线陡峭。

前后端分离

通常说前后端分离的话,有两种模式

纯前后端分离,从人员分工上就做到前后端分离,后端开发人员只负责编写接口,所有的前端开发工作由专门的前端开发人员负责技术上采用前后端分离,通常是前端MVVM框架+后端RESTFul接口,开发人员同时负责前端和后端接口的开发

这两种模式没有说哪种一定比另一种好,跟业务规模和团队配置有关。

如果是几百人就维护一个互联网产品,像电商系统这种,业务功能并不多,每个业务功能不断的进行完善,一个后端对应多种不同的前端,比如android/IOS/web等, 使用纯前后端分离的话会更聚焦,更有利于把功能做到极致。如果是2B或者2G这种,客户需求旺盛,变更频繁,和一些互联网产品比,更关注的是功能的广度而不是深度。以法院为例,上线民法典,案由的修改,可能是加一个字段或者需要修改一下业务逻辑控制,如果这个小功能还需要两个人配合才能开发,这个开发效率直接下降一倍。

对效率和质量的影响

我拿了一些研发项目的缺陷情况,想通过分析出选用不同前端框架的缺陷情况来判断对质量和效率的影响,但是木有成功。一是基础数据不够完善,二是无法评估不同项目特点、不同团队带来的差异性的影响。基于我从jsp、Ext、Jquery、vue项目的真实项目开发体验来看,vue+RESTFul接口的开发效率是最高的。我再也不想去操作DOM了,我就操作数据,渲染的事你别找我,既减少了我操作DOM的开发时间,也降低了我因为操作DOM,各种拼接处理可能引起的bug。后端RESTFul接口便于我做接口自动化测试、接口复用等。而且有搞不定的前端问题,也能更方便的请教前端开发人员,不像之前,我还得给他搭建一个后端程序去调试。

需要改进的地方

这几年前端技术发展日新月异,前端工程化、组件化已成为主流,整个前端技术栈越来越复杂。17年我用vue的时候,前端同学提供静态html,我在静态html中加上vue的指令和控件,写的js代码也没有完全做到模块化,webpack打包啥的也没用上,整体特别简单。现在我再去看一些项目,前端各种组件,复杂度比以前提升不少,当时用vue学了一天,现在的话学习成本有点高,简单使用的话,估计要学个两三天。

如果只是技术上使用前后端分离,人员分工作不前后端分离的话,最要改进的地方就是,在前端技术架构选型和工作推进上,需要前端架构师和后端架构师共同讨论决策,避免前端架构师对前端技术复杂度存在误判,造成整体学习成本较高,能力培养、工作组织推进上缺少整体把控,毕竟前端技术选型会影响到所有开发人员,而不只是前端开发人员。

总结

每引入一个新技术,都不单纯是一个简单的技术引进的工作,可能涉及到组织结构的调整,职责变更,能力培养等。而且一旦出现点啥问题,甭管和新技术是否有关,都可能会引起其他人的质疑,要有强大的内心和对技术痛点的准确判断。

以前系统慢,说因为Ext太重了,创建的对象多,所以慢。现在用spring cloud+vue,慢了说还是Ext好,贼快,vue让系统变慢了。其实我想说Ext也是前端渲染,Ext的Grid、form啥的也是通过ajax请求去后台取数据,然后render。vue用到了一些浏览器新特性的API,在IE下可能用需要通过polyfill来解决,会有些影响性能,但在chrome下,是不存在因为用vue导致性能问题,需要回到jsp时代才能解决的情况。而且IE本来就慢,人家vue3.X就没打算继续支持IE11了,再加上国家对信创的支持,IE这两年必定退市。

参考资料

the-rise-and-fall-of-ext-jsthe-history-and-legacy-of-jquery