大前端时代,浅谈JavaScript开发重型跨平台应用以及架构

大前端时代以及即将到来的5G时代,3D可视化,音视频直播技术,IM即时通信场景应用我以为都是大有可为的。前段时间爆款换脸应用出现,到近段时间头像加🚩的火爆,这是好事。前端

不知不觉,九月就要过去,因为这个月工做上,被C++折磨得很难受,并且其余时间都在学习,因此没有时间写文章,好在技术提高很大。今天准备好好谈一谈重型应用的架构以及技术选型,为接下来个人正式架构设计作个铺垫。react

为何写重型应用的架构和技术选型

  1. 传统的web前端,只能发个ajax请求,画画页面。了不起写个webApp
  2. 想让后端的同窗们,了解下目前大前端的世界,如今的前端跟之前不同了,特别如今市场很缺高级前端,可是术业有专攻,这点我认可
  3. 大前端的定义,太普遍,在我看来,必须深刻前端某个方向,以及能独立设计不那么复杂场景下的后端架构。
  4. 在极客时间上提问了winter老师,我自我感受已经良好,可是迷茫了。他回怼了我:想想你用你的技术作出了什么nb的东西把。
  5. 是人都想作出点什么事情,我想引发你们的共鸣去使用某些技术,或者朝着这个方向去发展,共同提高 社区的技术总体层次

什么是重型应用

例如微信,QQ,Telegram, 以及一些工具类的应用linux

说到这些你们确定以为,为何不说是游戏? 固然游戏也算,但是我相信作出1000万人天天都在用的产品是你们的梦想,起码能吹一生吧git

工具类的东西实际上是最难作的,好比vsCodeExcelPhotoShop这些。这也是为何这么多年出现成功的工具类产品这么少。这里不得不提到vsCode,它其实就是用ELectron开发,基于TypeScript。固然确定使用了很多C++插件,说到这里,留下伤心的眼泪,最近也是被折磨得很难受程序员

成功开发一个重型应用的好处

  1. 出去面试基本上很容易成功,特别是专业性强的岗位,例如你在QQ开发了十几年,你根本不用出去找工做,固然你应该也不会跑
  2. 技术全面,复杂场景你都能hold
  3. 有能吹的地方,能够跟谁说:我开发的东西,多少万人在用,老了还能吹。 程序员嘛,一半时间都在吹水,还有接近一半时间在划水,只有一丁点时间在写代码
  4. 更容易财务自由,生活自由,例如如今不少有过成功的重型应用开发者已经不单纯靠代码产出维持生活。他们作技术顾问,卖课程,出书,办培训都甚至比单纯写业务代码赚得多不少

正式开始

  • 目前跨平台框架,移动端比较成熟的是React-native,可是你们有所了解的都应该知道,这个框架虽然生态比较成熟,可是在面对众多手机的适配难度,以及性能方面存在的缺陷,若是用它制做重型应用我以为是不合适的,若是要作重型应用,移动端应该使用原生。
  • 库克说过,中国的移动端开发确实很强,美国人要作一个应用,首先考虑的是PC桌面端,而国内首先考虑的是移动端。

国内移动端开发人员,在我看来已经人目前已经够多了,若是说你如今不会React-nativeFlutter,我也不建议你去深刻学习,特别是Flutter.github

为何要这么说?web

React-native刚出来的时候,坑多吧。如今Flutter也是,但是当你从RN最初的版本踩坑踩到如今,以前踩的坑大都没有意义(说这些话想过被喷,可是...此处省略一万字,建议去了解下原理和基本使用,不要耗费太多时间)面试

一个技术你去使用,并非它多流行,只要它足够流行。 ---来自某位国内大佬ajax

技术的学习,应该多往底层钻研,若是你走错了路,钻错了方向,浪费了时间得不偿失,我以前有说过,前端最核心的几个基础知识点,应用层的东西历来不会很难。前提你的基础足够扎实数据库

前端20个真正灵魂拷问,吃透这些你就是中级前端工程师 【上篇】

前端20个灵魂拷问 完全搞明白你就是中级前端工程师 【中篇】

前端20个灵魂拷问 完全搞明白你就是中级前端工程师 【下篇】

这些文章不少同窗应该都看过,争议也很大,在我如今看也写得很烂,可是它里面的知识点是够的。固然你必需要去结合起来,而后深刻学习每一个知识点。

既然说了移动端没有合适的重型跨平台应用开发框架,那么只有PC端了。还有多少小伙伴在PC端开发呢?

Electron开发,来了

我不止一次提到过这个框架,我以为它真是一个很是棒的框架,为何这么说呢?

  1. 我跟不少朋友说过,若是想开发APP,不会写原生,那么你确定达不到某种境界。由于你始终有不少不少的黑盒过程,但是Electron就会大大下降这个几率。
  2. 基本上没有适配和差别性,linuxMac以及Windows三者均可以运行,除了Mac上某些特殊场景须要本身设计下菜单快捷键之类,以及一些文件IOMAC默认行为
  3. 最新的Node版本、运行的V8环境以及最新的谷歌浏览器一块儿被打包,最新的技术和API均可以用,无需适配担忧兼容性,真正放飞自我,能够随时随刻用Node.js实现功能,甚至调用大量C++插件,著名的VSCode就是这样而来

你甚至能够当作Electronweb网页套上一层壳,你能够在主进程写你的Node.js去实现功能,渲染进程你怎么写怎么写,还能够呼叫封装好的原生接口。遇到特别复杂的需求,用C++插件去实现吧

最终打包出来的安装包跟正常的桌面应用是同样的,正常安装卸载等,都已经封装好。

目前GitHub上已经有77.2Kstar

应用层面的东西,大都不会太难,Electron的文档已经很是全面,基于它出现了不少复杂,并且成功的工具类重型应用。我相信它

whatsApp也是基于它,国外还有一些很NB的应用也是。这里不作过多阐述,能够肯定它是一个成熟并且成功的框架

可能不少人看到这里又要说标题党了,别急,下面来干货。

重型应用架构注重的核心问题

  1. 项目自己的最重要功能是什么
  2. 项目自己出发点是为客户提供什么方便
  3. 项目的核心竞争力是什么

一个好的开发,它必定能懂一些产品,甚至测试,固然他也应该会炒河粉,35岁之后好维持生活

咱们今天举一个例子,IM,即时通信,Telegram,20万人超级群端到端加密的核心卖点产品

电报Telegram

如今回答上面三个问题:

项目自己的最重要功能是什么

答案:即时通信,信息的收发

项目自己出发点是为客户提供什么方便

使用产品进行消息传递

项目的核心竞争力是什么

20万人的超级群,端到端加密,隐私足够安全

核心竞争力,每每表明了这个应用产物的技术最难点,由于谁都能作,那么就不是核心竞争力了

因此咱们其余的都忽略,关注第三点,开始进行技术选型,架构。

单线程的Node.jsJavaScript重型应用架构设计

要想写好这个架构,我以为你首先在自身的擅长领域不能有太多的黑盒过程。例如框架源码,库原理实现,浏览器和Node.js的事件EventLopp以及他们的缺陷,你要熟知在心。由于像这种应用,一个小方向可能就会掏空你的技术栈,耗尽你的精力,例如音视频、图片处理等。

单线程的Node.js以及js主解析引擎,让咱们又爱又恨。

这款应用的核心竞争力,是20万人超级群,那么数据量很大,大批量渲染压力和频繁加解密计算耗时、频繁数据库写入压力都是不可避免的,那么咱们的Node.js擅长异步非阻塞,以及前端渲染进程的异步就显得尤其重要

前端架构总体的核心除了技术选型以及大致框架外,就是任务调度。

这里的任务调度分两种:

1.渲染任务调度

2.非渲染任务调度

单个渲染任务调度

1.React框架中,屡次传入对象,setState会自动合并到一次执行,其实就是一种节流思想

2.ReactFiber架构思想,把若干个任务分割成多个小任务执行,中间根据你的任务优先级安排去选择时机执行

3.淘宝的分片渲染方案,跟上面第二条有一些相似

我以前说过,应用层的东西都不难,只要你基础足够扎实,能手写出简单的框架,以及库。你绝对能很是轻松应对前端百分80以上的性能问题和需求,技术最终都是类似的

上面只是说了别人的一些比较简单的优化方案,下面才是开始咱们本身的渲染任务调度:

回到咱们的Telegram架构设计方案:

渲染任务架构过程须要着重考虑的几个问题:

1.渲染数据量特别大

2.更新特别频繁

3.尽量手动回收垃圾,避免消息量过大,v8垃圾回收的时间不肯定性致使内存被白白占用,引发卡顿

4.考虑大批量数据到达渲染进程的用户应用体验,肯定用户交互属于高优先级任务,其余的哪些是低优先级-但必须执行的任务,哪些是中优先级任务,这里说的任务,都是渲染任务。

今天在学习一篇小册,里面有一句话引发了个人共鸣,在计算机的世界,若是有解决不了的问题,那就加一个中间层,若是还不行,那就加两个。 -后面这句是我加的

这个是我本身编写的Reactmini-react源码地址

PReact源码中,是将须要更新的组件放入队列中,而后一次清空,伪代码:

if (setStateQueue.length === 0) {
    //清空队列的办法是异步执行 
    defer(flush);
  }
     setStateQueue.push({
    stateChange,
    component
  });

    function defer(fn) {
      //requestIdleCallback的兼容性很差,对于用户交互频繁屡次合并更新来讲,requestAnimation更有及时性高优先级,requestIdleCallback则适合处理能够延迟渲染的任务~
      //   if (window.requestIdleCallback) {
      //     console.log('requestIdleCallback');
      //     return requestIdleCallback(fn);
      //   }
      //高优先级任务
      return requestAnimationFrame(fn);
    }


  while ((component = renderQueue.shift())) {
    renderComponent(component);
  }



复制代码

上面这段代码其实很重要,核心思想就是:

每当进入这个函数,若是发现队列队列里没有任务就去执行defer函数

defer函数执行是异步,此时defer下面的setStateQueue已经被push了进去数据,这样达到一帧完成一次渲染任务调度

固然上面仅仅一个小的任务调度,这个必需要了解,才能往下看


requestAnimationFramerequestIdleCallback使用:

你须要深刻了解React框架的Fiber架构,这块尤为重要,是性能优化,任务调度的基础,上面有提到,React在每次diff对比阶段,将任务分割成若干个小任务,此时若是有RAFRID的任务,就要考虑去执行了

RAF的任务会每次在下一次小任务前执行

RID的任务只有在下一次小人物前,有空余时间才会执行,因此它不必定会执行。(特别高频必须执行的任务)

Fiber架构配合单个任务分割已经介绍完毕,下面出思惟导图出总体的任务调度


总体渲染任务调度

核心的两点:

1.释放主线程的占用,让用户的操做最快获得响应

2.合理调度任务,分高、中、低三种优先级别任务

理清思路:

1.数据经过IPC通讯到达渲染进程

2.所有交给子线程去进行计算,组装数据,经过异步的postMessage事件通讯,拿到渲染数据

3.调度渲染任务,用户操做交互

4.释放主线程

这里特别提示,为何我一直强调不要使用定时器,一旦应用变得很复杂,若是任务调度不合理,定时器里的代码是要好久好久才能执行的。固然,只有重型应用会这样

渲染任务调度这块,主要是微任务,RAF,RID分片渲染以及同步代码,队列调度等手段。

主进程,接入层任务调度

核心思想跟渲染进程大概一致:

1.尽可能释放主进程,保持空闲,让用户的操做即时获得反馈,由于不少操做会调用主进程的接口

2.异步调度任务,写入数据库异步,解密计算可使用nextTick等方式去调度添加队列

这里提到,任务调度的核心一点就是,频繁触发的任务必须加入队列,异步清空,不然像解密这种同步计算耗时,一旦被频繁触发就会引发阻塞。即便交给了其余进程,也要作队列

总体架构以及技术选型注意点

1.技术选型时,尽可能选择本身熟悉它原理的库,以及能用Demo测试模拟场景的技术,测试经过再选用,不一样技术之间解决问题出发点不同,可能会有冲突

2.队列和多进程、多线程的开启,并非必定须要的,你能够本身设定一套规则,当一段时间的任务到达多少次被触发时候选择开启多线程,多进程。不然就是浪费

3.重型应用架构远不止这些,因此标题是浅谈,等下个月技术做者再度飞速提高一波,再来谈这些。

这里推荐关注做者的微信公众号:前端巅峰

发送加群,我会将你拉进 前端交流群,不少小姐姐哦~

技术氛围杠杠滴~ 关键漂亮的小姐姐也在里面哦~

若是以为写的不错,必定要点个赞再走,必定哦~

相关文章
相关标签/搜索