我理解中的“大前端”/“大无线”

本文内容较长,大概需要15分钟时间阅读。

内容包含五部分:前言,NodeJS职能变化,ReactNative的大规模应用,专门的架构组职能,总结。主要是介绍我所在团队最近的一些变化和思考。

更多信息可以加入我的小密圈关注团队每日动态:http://t.cn/Ri2cBT0

前言

最近,我所在的团队做了一些结构调整,其实我一直想讲讲这次调整,希望能够带给同行一些思考,但因调整后很多事情还未走上正轨,一直拖延着,现在终于有时间把一些想法写下来记录成文字。

今天早晨,还看到一篇文章,讲“大前端”,文中展望了近年来“前端”影响的领域,从美工时代刀耕火种的时代到现在延伸到 NodeJS ,ReactNative甚至桌面端,以及传统前端的时代,听来的确让人非常兴奋和自豪,但是作为一名理性的工程师,对于这种自High的论调一定要抱有谨慎的态度。

其实在技术选型上我是一个激进却又保守的人,所以,我同大家伙一样,对于JS语言冒出来的给人无限想象的能力非常的敏锐和兴奋,但是在落地到真正的业务中的时候却要仔细权衡好它的真正的“价值”。此处的价值更多针对的是“对公司整体业务的价值”,而不是对团队或者个人的价值或是其他,所以,引入一个技术栈,绝非看起来那样简单,“新技术”可能会给你的团队或者业务带来加持,但是更多时候,外界的人云亦云却往往会夸大某个技术的价值,然后同时刻意避免谈及这些技术带来的问题,就是我们通常所说的“脱离场景讨论技术”,而且通常带来的问题比解决的问题还要多得多,这时候如果抱着“扩大前端团队的话语权”或者“做一步看一步毕竟业界都在这样玩”的态度,那就和“技术创造价值”的本意相违背了。

其实,大家会发现我所在的团队并不是一个保守的团队,从外面看,我们始终走在最前沿,但是从内部看,其实我们一直在关注“技术创造价值”这件事情的本质,所以我们给前端团队强化了很多职能,但是却走了一些不同的道路,之所以会这样,其实就是基于我们针对每个技术栈所做的思考,接下来我会举几个例子来讲。

其实我今天本来想讲的事情,并不只是“前端”,而是这次团队组织架构调整后的“大无线”,为什么要从“大前端”到“大无线”,也是基于最大化价值输出的考虑,这是后话。

这次调整,最大的三个动作就是, NodeJS 的职能变化/ReactNative的引入/专门的架构组职能,然后包含其他一些小动作。

NodeJS 职能变化

对于 NodeJS ,我其实有挺多的话题想分享,关于前后端分离,关于服务端渲染,关于纯服务端开发。很长一段时间内,在我们团队, NodeJS 都是在做纯服务端开发,然后我们的核心关注点一直是致力于将 NodeJS 在服务端开发的整个工程能力提升到和Java生态相当甚至是超越,包括开发/部署/运维/服务化/线上保障 等。值得注意的一点是,当我们的 NodeJS 运用非常成熟的时候,我们却一直没有做业界大家在玩的服务端渲染,或者前后端分离中间层,其实不是我们不了解或者没有能力,而是我们一直在思考“为什么”,然后会”带来什么问题?“。我觉得很多公司在做服务端渲染或者前后端分离的时候,可能都没有非常全面的去思考过这个问题,是必须要做了而且带来的价值远远超越了风险?还是只是为了让团队占领更大的势力版图?我们前几天在讨论这个问题的时候还提到,包括在某些大公司内,做某些事情可能只是政治正确或者为了业绩好看,如果你去问一个服务端开发,他对这些事情的看法是什么?难有好评?那这件事情可能就已经走偏了,它可能关注了前端团队的自身价值,却偏离了整个技术团队的价值体现。

当然我不是表达不应该去做某些事情,而只是讲所有技术栈的落地都要基于场景去考量权衡。其实我们团队后来也做了业界意义上基于”服务端渲染"的”前后端分离“项目,在某个特殊业务中,我们衡量必须要做,与多方共同讨论,最终实施落地的一个和谐方案。做这个项目的目的足够单纯,但是我们并没有打算推广这个方案,因为在我看来,他只是解决某个特定场景的一个解决方案,而不是一种必须推开来的“开发方式”。而且对于服务端渲染引入的风险一定要做好风险评估,包含但不限于:运维/线上保障能力(前端的弱项);前后端开发的复杂度;性能问题(真正做过服务端的同学对内存和cpu占用都会很敏感,但是目前一些方案看来在这方面的损耗还是太夸张); NodeJS 本身的开发能力熟悉程度。其实有些问题是很严重的问题,只是在业界大家讨论的时候,大家会刻意去弱化某些话题,而是强调其革新之处,或者是未来的趋势,而这些理由,在真实场景落地的时候的作用微乎其微,别人一个质疑就足以让你的方案变成一个”糟糕的方案“。

不过,我所在的团队的 NodeJS ,最近其实在做”去服务端逻辑“化,也就是慢慢退出纯服务端开发的领域,倒不是被倒逼,我觉得一个团队应该做什么事情从来不是因为技术之间的斗争导致的,而是前面提到的整体价值,在公司飞速发展的业务背景下, NodeJS 的开发生态和团队扩张速度,都是瓶颈。 NodeJS 开发者的开发能力其实都很强,但是却缺乏传统软件工程大规模开发的经验,这些经验可能大部分都不是和技术相关的,所以越在技术上走的深入,与大规模工程化关注的方向越发背离。所以,我基本上是主动要求团队退出服务端开发,将整个公司的服务端统一到 Java 技术栈上,统一由 Java 架构组规划技术发展,由 Java 业务组统一发展业务的工程化,这样对公司的爆炸式增长会更有益处,随后Java开发在一个月内扩招20人,而 NodeJS 一年时间里基本一直维持在5个人的水平(人数也是影响工程化的重要一环),想想这五位同学曾经在一年之内建设的诸多系统,虽然真的很牛逼,但是却略显小气,没有一个统一的规划和价值体现。

那我们现在在做什么?

之前提到,我们现在整个团队成为“大无线”,其中包含两个大团队,架构和业务,而 NodeJS 正是架构中的一员,对于 NodeJS 来说,它擅长的正是对社区和标准的追逐/开发效率/异步性能,而我们则发挥这些长处,在整个“大无线”的范围内解决相关的问题。例如正在做的一件事情,一个无线网关系统,具体网关系统是做什么事情的可能无法一句话描述清楚,核心两点,1. 公司内所有api请求的入口和规则分发,2. 在网关层做服务分级。具体实现其实并不是完全的 NodeJS 技术栈,其中多个子系统,包括Nginx开发网络层/lua开发的独立的心跳检查/ NodeJS 开发的规则管理等,对于 NodeJS 来说是个不小的挑战,对于整个无线端,甚至服务端,都有深远的意义,这种事情才是真正“有意义”的,后续我们也还有其他规划,不过一切都需要一步一步调整,而对于我们 NodeJS 开发来说的调整,就是转变思路,发挥长处,而不是一心想要去改变服务端开发的格局。

ReactNative的大规模应用

我所在团队对于RN的技术积累其实从很早就开始了,大概接近1年前,但是一直处于调研的状态,甚至组件库都写好了,基础的集成SDK也写好了,但是从来没被应用到业务中。为什么?不是因为不成熟,也不是因为hold不住,而是没想明白,为什么一定要用RN?而不是H5或者Native?这其实是个很严肃的问题,你想不清楚一个技术的价值的时候,不要说是说服别人,连说服自己都很难,这样的事情注定无法落地,所以我们就一直在调研,在准备。就跟微信小程序一样,我们调研了很久,自己做了个小程序上线,但是后来还是没有做一个真正的业务相关的小程序,因为实在想不明白要做什么,为什么必须要用小程序?

后来,算是跟上了“大无线”整合的契机,也是公司业务飞速发展的契机。当我们统一规划一下公司内所有的前端和无线端之后,发现数量竟然和所有服务端(包含架构和数据等)的数量基本相当,这很不正常,当公司开始快速扩张之后,这种比例是非常吓人的,而核心问题就是我们公司无线端所有的开发工作量基本都是Native承担的,这主要受制于公司业务类型限制,公司基本所有业务都是偏商家服务类型,重交互重操作重数据,在客户端上开发,对H5来说的确难以满足需求,不管是性能还是体验还是开发成熟度上来说。所以除了公司的to C业务和PC端业务之外,大量投入客户端开发,而因为之前客户端分散在各个业务之间,每个业务的每个端都各自为政,在底层方案和组件SDK等问题上都缺乏一个统一的规划。

注意!这里提到两个核心问题:

  1. 开发人员输出价值的人均效率,对于Native来说都需要至少乘以2,如果算上两端之间的协调,将远远大于2这个最好预期。
  2. 难以统一规划整个客户端的统一发展,总是会受限于两个完全不同的端各自不同的技术栈。

这时候,ReactNative站出来了,一个真正性能折中但是可以完美解决这两个核心问题的技术方向,而且我们还是有技术积累的,至于我们如何在RN和Weex之间做选型,其实不想多说,Weex的场景并不适合我们的业务类型,而且作为创业公司,我们只会选择整个业界非常成熟的方案而不是一个还在发展期只是看起来很美好的方案。
对于ReactNative,核心价值点,其实就是上面说的这两点,听起来只是两个问题总结,但是对于整个技术团队,甚至对于整个公司的业务发展,这都是非常核心的点,所以,我们毫不犹豫的执行,短时间内快速推进了整个RN的解决方案以及落地。

针对RN,我们做了几个事情:

  1. 完全改变RN的开发流程,自己定制的脚手架以及开发流程/调试流程/发布流程/版本更新规则。(我司最擅长的点)
  2. 自己实现的集成流程/热更新方案,这里有一个核心点,我们制定了某个App依赖某个版本bundle的机制,RN代码不是每次热更新,然后RN代码是直接内置到工程里走发版,而不是线上访问,因为我们的业务场景很特殊,业务耦合很强,所以制定了严格的版本依赖规则和维护方式,热更新的能力只限于bugfix,不能用于发布新功能。
  3. 封装过客户端SDK,主要提供几个能力:Bundle依赖管理/Native组件以及提供更多组件SDK无缝接入的能力/RN和Native和H5之间通过协议互相调用的能力/性能和错误崩溃监测/其他底层优化(例如秒开,bundle分拆复用等)。
  4. 最终面向具体业务开发的一部分:开发框架/开发规范/基于设计规范的组件库/Native组件封装/工具库/文档/模板项目/example项目列表 等,通过这些,我们给具体的业务开发暴露极少的概念,可以在短时间内完成一个RN项目,并且将可能平台差异的部分都做了深度封装。

所以,可以看到,其实我们的RN开发有自己的一些特色:

  1. 大部分RN业务开发是客户端开发,而前端仍然专注于前端的领域,所以我们的方案做了大量概念封装,具体开发过程中大量使用的是自己封装的概念而不是原生的概念,也把React生态,RN本身的生态的概念做了最大化的封装,让不熟悉React的同学也可以做基础的开发。
  2. 强版本依赖,RN业务发布走发版而不是在线热更新,RN和Native和H5之间深度耦合,一个流程中可以无缝在不同的容器间切换。然后RN和H5调用Native的能力其实也是一个统一的底层封装。

这块,不想在这里展开来讲,毕竟这篇文章只是讲方向,而不是具体实现。

专门的架构组职能

到这里,才讲到,为什么要整合“大无线”?基于前文的分析,无非是让大家更关注大团队的价值输出,而不是某个业务或者某个技术工种的价值输出,前文多有体现其中的各种弊端。

如此的组织架构,对于集中输出价值的表意更为清楚:

  1. 各小组的价值,就体现在各自的职责定义上,其实这样的组织架构各自的职责定义非常清楚,业务方负责将业务实现和落地,其价值体现在更高效的落地业务,而架构组则负责统一规划技术方向,提供基础设施,推进技术演化,来解决业务落地过程中的技术问题。
  2. 二者协作,价值最终还是集中于一个点上:业务价值。对于无线来说是无线端对业务的价值,而后端则是后端对业务的价值。二者其实略有不同,无线端更关注表现和体验,后端则更关注逻辑和服务。
  3. 最终大家的价值其实都集中在公司层面,当然能不能考虑到这一层,能不能推动这一层,就是各大Leader的能力问题了。

在抽取出统一的无线端架构组之后,至少以下几件事情可以体现出深刻的价值来:

  1. 专门的跨端体验组,提供RN的整套解决方案和各种优化以及推进等,统一规划RN的发展方向,效率提升,流程规范等,而业务方则致力于快速实施推进业务开发的效率。
  2. 专门的客户端和前端架构组,统一规范“开发方式”,所谓的工程化体系,提供各种效率工具(例如我们内部的mock系统,已经和服务端自动化集成在一起,非常高效),提供基础组件,基础服务(例如前端的静态资源管理等服务)基础脚手架,提供一些底层manger的统一实现等。
  3. 专门的 NodeJS 中间件团队,提供一切与无线端的后端服务能力,例如网关服务,服务端渲染服务,RN模块管理服务,静态托管服务,消息服务等,其中有些服务挑战非常大(网关/消息等),后续,还准备做另外一个中间件的尝试,不过还是要按照上面讲的方法论进行评估。

虽然,整个无线端包含了这么多角色,但是我深感欣慰的是,我们在各自领域都有了一定的基础积累,所以在这样大整合的趋势下,能够良好运转,并快速发挥各自优势为整个团队的发展出一份力。如果我们是从开始按照这样的职责孵化,其实我觉得很难走到今天这一步,所以,这是一个趋势,但是不是一种与生俱来的合理结构。

另外,在架构组职责上,还有一点很重要就是,架构这个角色绝对不止是“研究新技术/熟悉底层/产出复杂技术方案”的角色,更多时候,架构师需要深入到业务中去发现问题,然后分析问题总结问题,思考解决方案,与其他成员脑暴,制定最终解决方案,并将其最终落地的过程。所以我们有一套自己的架构流程,大抵是这个过程:

提出问题 -> 调研 -> 初步方案 -> 讨论 -> 完整方案 -> 架构组分析图 -> 业务方评审 -> 制定计划然后实现 -> 推进落地。

你会发现其中写代码的时间可能不到20%,如果你每天不是在思考或者沟通而是一直在写代码,那你肯定是个假架构师。

##其他

说了这么说,总结下我的核心观点:

  1. 不要一味追随潮流,基于场景讨论问题。
  2. 关注技术的核心价值,不要为了用而用。
  3. 不要因为自己是前端而妄自菲薄,每个领域都要深扎下去。

最终,无线和前端领域这么多概念,个人其实很难完全掌控,但是团队一定要有能力掌控,不同的人,对不同的技术栈,做好技术积累和预研,厚积薄发,这样的团队在合适的机会才能更好的发挥整体价值。

更多信息欢迎关注团队博客: http://f2e.souche.com/blog

也可以加入我的小密圈关注团队每日动态《全栈团队成长记录》:http://t.cn/Ri2cBT0

转载请不要删减并注明出处:https://zhuanlan.zhihu.com/p/25567060


本文对你有帮助?欢迎扫码加入前端学习小组微信群:


更多专业前端知识,请上 【猿2048】www.mk2048.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32之Systick(系统时钟滴答定时器)

systick定时器有两个可选的时钟源,一个是外部时钟源(STCLK,等于HCLK/8),另一个是内核时钟(FCLK,等于HCLK)。假若你选择内核时钟,并将HCLK频率设置为72MHz的话&#xff0c…

Dirichlet分布

1.预备知识 Beta分布函数是一种定义在实数区间[0,1]的特殊函数,它是二项式分布的共轭分布;与Beta分布相同,Dirichlet分布也是定义在实数区间[0,1]的概率度量函数,Dirichlet分布是多项式分布的共轭分布,Dirichlet分布的…

python编程制作接金币游戏_pygame学习笔记(6):完成一个简单的游戏

学了这么长时间的Pygame,一直想写个游戏实战一下。看起来很简单的游戏,写其来怎么这么难。最初想写个俄罗斯方块,想了很长时间如何实现,想来想去,也没写出来,于是干脆下载别人的代码来读。后来,…

Spring:使基于Java的配置更加优雅

大家好,我很久没有写新文章了。 积累了很多资料,需要在不久的将来在我的博客中发布。 但是现在我想谈谈Spring MVC应用程序配置。 确切地说,我想谈谈基于Java的Spring配置。 尽管在3.0版本中引入了基于Spring Java的配置,但是许多…

用观察者模式编写一个可被其他对象拓展复用自定义事件系统

观察者模式 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知 什么是观察者模式? 发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态…

布局定位

布局与定位 摆放元素 1,使用流 流实际上就是浏览器在页面上摆放HTML元素所用的方法。浏览器从HTML文件最上面开始,从上到下沿着元素流逐个显示所遇到的各个元素。 每个块元素会按它在HTML标记中出现的顺序放置在页面上。每个新的块元素会带来一个换行。并…

T - Memory and Trident CodeForces - 712B( 注意:* ++ = 的优先级

题意:有四种命令:U代表上移一个单位,D代表下移一个单位,R代表右移一个单位,L代表左移一个单位。 现在给出一串命令,问怎样修改命令中的任意一条命令,使得命令结束后重新返回原点,并且…

python语言精通_Python语言基础从入门到精通

1、python关键字False await else import passNone break except in raiseTrue class finally is returnand continue for lambda tryas def from nonlocal whileassert del global not withasync elif if or yield2、命令行参数williamdeMBP-2:~ william$ python -c "imp…

休眠事实:了解刷新操作顺序很重要

Hibernate将开发人员的思维方式从思考SQL转变为思考对象状态转换。 根据Hibernate Docs,实体可能处于以下状态之一: new / transient:实体不与持久性上下文关联,因为它是数据库不知道的新创建的对象。 持久性:实体与…

[HNOI2012]排队

题目描述 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的&a…

声速的测量的实验原理和应用_声速的测定实验报告心得体会

测量声速的实验报告1。提出问题如何测出声音的速度?2。猜想与假设如果在一定距离内听到声音要多少时间?3。实验步骤步骤应该就是实施实验,第三是实验器材的话,就是要秒表。4。实施实验在一个山谷中,站在距离峭壁680M的地方大叫一声&#xf…

FreeNAS:创建 CIFS 共享(权限)

第一部分:新建账户与指定数据集权限 简单起见,本教程主要介绍带基本身份验证的 CIFS 共享,即只有输入正确的用户名和密码才可以访问共享目录。关于创建匿名共享、多用户权限管理以及域控制器相关内容,我们会另外发布教程专门介绍。…

使用序列化查找对象中的脏字段

假设您正在开发一个将对象自动保存到数据库中的框架。 您需要检测两次保存之间所做的更改,以便仅保存修改过的字段。 如何检测脏场。 最简单的方法是遍历原始数据和当前数据,并分别比较每个字段。 代码如下: public static void getDirtyFie…

js操作table中tr的顺序,实现上移下移一行的效果

总体思路是在table外部加个div,修改div的innerHtml实现改变tr顺序的效果 具体思路是 获取当前要移动tr行的rowIndex,在table中删除掉,然后循环table的rows,到了目标行再直接加进去,最后把整体的html赋值给div完成效果…

oracle日记账单据编号未生成_商管财务数据平台Oracle与共享未付池差异如何核对、解决?...

‍‍近期,总部新上线财务数据平台啦!各个系统间的差异异常数据清晰可见,随时可查,今天就和小伙伴们一起分享一下Oracle与共享未付池差异如何核对、解决。首先,将Oracle与共享未付池差异数据导出。由于导出的数据包括本…

python (六)函数

一、函数的形成 需求1:来测试一下‘hello word’ 的长度 # 在没有函数的时候,我们可以用for循环实现 s1 "hello world" length 0 for i in s1:length length1 print(length) 再增加一个需求2:再来测试一下另外一个字符串的长度&…

Java方法中的参数太多,第4部分:重载

期望将过多的参数传递给Java方法的问题之一是,该方法的客户端很难确定它们是否以适当的顺序传递了适当的值。 在以前的文章中,我描述了如何使用自定义类型 , 参数对象和构建器来解决此问题。 解决此问题的另一种方法(也是本文的主…

android paint 圆角 绘制_[BOT] 一种android中实现“圆角矩形”的方法

内容简介文章介绍ImageView(方法也可以应用到其它View)圆角矩形(包括圆形)的一种实现方式,四个角可以分别指定为圆角。思路是利用“Xfermode Path”来进行Bitmap的裁剪。背景圆角矩形实现的方法应该很多,网上一大堆。很怀疑为啥安卓的控件不内置这样的属…

解决高度塌陷问题

所谓高度塌陷就是在文档流中,父元素的高度默认是被子元素撑开的,也就是子元素多高,父元素就多高。但是当为子元素设置浮动以后,子元素会完全脱离文档流,此时将会导致子元素无法撑起父元素的高度,导致父元素…

HDU2035 - 人见人爱A^B

求A^B的最后三位数表示的整数。 说明&#xff1a;A^B的含义是“A的B次方” Input 输入数据包含多个测试实例&#xff0c;每个实例占一行&#xff0c;由两个正整数A和B组成&#xff08;1<A,B<10000&#xff09;&#xff0c;如果A0, B0&#xff0c;则表示输入数据的结束&…