清丰县论坛

首页 » 问答 » 灌水 » 如何全方位优化你的超大型React应
TUhjnbcbe - 2020/6/1 12:25:00
北京中科医院骗人

(给前端大全加星标,提升前端技能)

作者:前端巅峰公号/Ptr谭金杰(本文来自作者投稿)

Ract为了大型应用而生,Elctron和Ract-nativ赋予了它构建移动端跨平台App和桌面应用的能力,Taro则赋予了它一次编写,生成多种平台小程序和Ract-nativ应用的能力,这里特意说下Taro,它是国产,文档写得比较不错,而且它的升级速度比较快,有issu我看也会及时解决,他们的维护人员还是非常敬业的!

Tips:本文某些知识点如果介绍不对或者不全的地方欢迎指出,本文可能内容比较多,阅读时间花费比较长,但是希望你可以认真看下去,可以的话最好手把手去实现一些cod,本文所有代码均手写。

本文会从原生浏览器环境,到跨平台开发逐渐去深入介绍,先给一些资料

手写Ract优化脚手架带项目

ract-ssr的源码

手写Nod.js原生静态资源服务器

跨平台Elctron的dmo

原生浏览器环境:

原生浏览器环境其实是最考验前端工程师能力的编程环境,因为我们前端大部分一开始面向浏览器编程,现在很多很多工作5-10年的前端,性能面板API都不知道用,怎么看调用函数分析耗时都不知道,这也是最近面试的情况,觉得有人说35岁失业的情况,是普遍存在,但是很大部分是你在混啊兄弟。

原生浏览器环境中使用Ract框架,比较常见的是制作单页面SPA应用:原生的SPA应用,分以下几种:

纯CSR渲染(客户端渲染)

纯SSR渲染(服务端渲染)

混合渲染(预渲染,wbpack的插件预渲染,Nxt.js的约定式路由SSR,或者使用Nod.js做中间件,做部分SSR,加快首屏渲染,或者指定路由SSR.)

下面会分别仔细介绍这几种渲染形式的精细化渲染,以及优缺点:纯CSR渲染

客户端请求RstFul接口,接口吐回静态资源文件

Nod.js实现代码

客户端收到一个HTML文件,和若干个CSS文件,以及多个javaScript文件

用户输入了url地址栏然后客户端返回静态文件,客户端开始解析

客户端解析文件,js代码动态生成页面。(这也是为什么说单页面应用的SEO不友好的原因,初始它只是一个空的div标签的HTML文件)

判断一个页面是不是CSR,很大程度上可以根据右键点开查看页面元素,如果只有一个空的div标签,那么大概率可以说是单页面,CSR,客户端渲染的网页。

纯CSR的应用,如何精细化渲染呢?

单页面采取CSR形式,大都依赖框架,Vu和Ract之类。一旦使用这类型技术架构,状态数据集中管理,单向数据流,不可变数据,路由懒加载,按需加载组件,适当的缓存机制(PWA技术),细致拆分组件,单一数据来源刷新组件,这些都是我们可以精细化的方向。往往纯CSR的单页面应用一般不会太复杂,所以这里不引入PWA和wbwork等等,在后面复杂的跨平台应用中我会将那些技术一拥而上。

单一数据来源决定组件是否刷新是精细化最重要的方向。

一旦业务逻辑非常复杂的情况下,假设我们使用的是dva集中状态管理,同时连接这么多的状态树模块,那么可能会造成状态树模块中任意的数据刷新导致这个组件被刷新,但是其实这个组件此时是不需要刷新的。

这里可以将需要的状态通过根组件用props传入,精确刷新的来源,单一可变数据来源追溯性强,也更方便dbug

单向数据流不可变数据,通过immutabl.js这个库实现

不可变数据,数据共享,持久化存储,通过is比较,每次map生成的都是唯一的,它们比较的是codhash的值,性能比通过递归或者直接比较强很多。在PurComponnt浅比较不好用的时候

一般的组件,使用PurComponnt减少重复渲染即可

PurComponnt,平时我们创建Ract组件一般是继承于Componnt,而PurComponnt相当于是一个更纯净的Componnt,对更新前后的数据进行了一次浅比较。只有在数据真正发生改变时,才会对组件重新进行rndr。因此可以大大提高组件的性能。

PurComponnt部分源码,其实就是浅比较,只不过对一些特殊值进行了判断

这里特别注意,为什么使用immutabl.js和purComponnt,因为Ract一旦根组件被刷新,会自上而下逐渐刷新整个子孙组件,这样性能损耗重复渲染就会多出很多所以我们不仅要单一数据来源控制组件刷新,偶尔还需要在shouldComponntUpdat中对比nxtProps和this.props以及this.stat以及nxtStat

路由懒加载+cod-spliting,加快首屏渲染,也可以减轻服务器压力,因为很多人可能访问你的网页并不会看某些路由的内容

使用ract-loadabl,支持SSR,非常推荐,官方的lazy不支持SSR,这是一个遗憾,这里需要配合wpback4的optimization配置,进行代码分割

Tips:这里需要下载支持动态import的babl预设包

babl/plugin-syntax-dynamic-import,它支持动态倒入组件

好了,现在路由懒加载组件以及代码分割已经做好了,而且它支持SSR。非常棒

由于纯CSR的网页一般不是很复杂,这里再介绍一个方面,那就是,能不用rdux,dva等集中状态管理的状态就不上状态树,实践证明,频繁更新状态树对用户体验来说是影响非常大的。这个异步的过程,更耗时。远不如支持通过props等方式进行组件间通信,原则上除了很多组件共享的数据才上状态树,否则都采用其他方式进行通信。

SSR,服务端渲染:服务端渲染可以分为:纯服务端渲染,如jad,tmpalt,js等模板引擎进行渲染,然后返回给前端对应的HTML文件

这里也使用Nod.js+xprss框架

混合渲染,使用wbpack4插件,预渲染指定路由,被指定的路由为SSR渲染,后台0代码实现混合渲染,使用Nod.js作为中间件,SSR指定的路由加快首屏渲染,当然CSS也可以服务端渲染,动态Titl和mta标签,更好的SEO优化,这里Nod.js还可以同时处理数据,减轻前端的计算负担。

我觉得掘金上的神三元那篇文章就写得很好,后面我自己去逐步实现了一次,感觉对SSR对理解更为透彻,加上本来就每天在写Nod.js,还会一点Nxt,Nuxt,服务端渲染,觉得大同小异。

服务端渲染本质,在服务端把代码运行一次,将数据提前请求回来,返回运行后的html文件,客户端接到文件后,拉取js代码,代码注水,然后显示,脱水,js接管页面。

同构直出代码,可以大大降低首屏渲染时间,经过实践,根据不同的内容和配置可以缩短40%-65%时间,但是服务端渲染会给服务器带来压力,所以折中根据情况使用。

以下是一个最简单的服务端渲染,服务端直接吐拼接后的html结构字符串:

只要客户端访问localhost:就可以拿到数据页面访问

服务端渲染核心,保证代码在服务端运行一次,将rdux的stor状态树中的数据一起返回给客户端,客户端脱水,渲染。保证它们的状态数据和路由一致,就可以说是成功了。必须要客户端和服务端代码和数据一致性,否则SSR就算失败。

rndr函数:

数据注水,脱水,保持客户端和服务端stor的一致性。

上面返回的script标签,里面已经注水,将在服务端获取到的数据给到了全局window下的contxt属性,在初始化客户端stor时候我们给它脱水。初始化渲染使用服务端获取的数据~

这里注意,在组件的

1
查看完整版本: 如何全方位优化你的超大型React应