react native 已经快没了 还有人在问为什么react native会比H5性能好... 本文将从线程模型
,渲染方式
,刷新机制
, 加载方式
等多个角度给大家讲清楚 为什么react native性能更好,以及哪些方面不如web..
前置文章:
浏览器:进程与线程
浏览器:帧原理&渲染优化的基石
js三座大山之异步五基于异步的js性能优化
线程模型
H5多线程模型:
-
主线程: 解释执行js代码,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等,当界面需要重绘或由于某种操作引发回流时,该线程都会执行。
-
合成线程: 将多个层合并为一帧交给gpu渲染,css中的动画属性和transform属性都是作用在这个线程中的。
-
栅格化线程: 由合成线程派生的一个或多个线程,用于处理栅格化任务。即将页面内容一般按照屏幕大小分块生成位图。
还有其他的线程 这里只讨论和渲染性能相关的...
web最大的性能瓶颈
在于 主线程 做的事情太多了 虽然有合成线程 和栅格化线程 可以分担部分工作量 但是执行js和渲染流程
绝大部分依然需要主线程来完成。
react native线程模型
- js线程: 在rn中 js端是在独立线程中运行的 仅用于执行业务逻辑。
- native线程: 这是原生应用的UI线程,这个线程负责绘制UI元素并响应用户的交互。
- Shadow Thread or Layout Thread(布局线程) : 主要用于解析flex布局等,会将结果应用于native线程。
多个线程通过bridge机制 将数据序列化和异步地交换信息 实现通过通信。
所以react native 比 web快的一点已经出来了 因为rn的多线程模式 js执行和UI渲染是分开执行 这就可以打破web的性能极限了。
但是缺点也同样明显 频繁的在多线程间进行异步序列化的数据通信也是它的性能卡点
,例如频繁的手势操作和UI更新场景是不适合rn的,
渲染方式
H5渲染
渲染一次经过的流程 上图!
浏览器需要从html解析出dom 然后按照上述流程 才能描绘出对应的标签。链路较长.
rn原生渲染
rn原生渲染具体是什么意思?
HTML元素定义(比如div p等)已经预置在浏览器代码中,浏览器知道如何理解以及展示这些元素。但实际的HTML文档(也就是你写的HTML代码,包含具体的div p等标签)并不是预存储在浏览器中的,需要浏览器读取HTML代码,然后解析、构建成DOM树,最后再渲染到屏幕上。所以这些HTML元素(不是在浏览器中预存储的,而是需要计算生成的。
对于原生组件,比如React Native中的 View,它们会被编译成具体平台的代码(比如在iOS上,一个View 可能会被编译成一个UIView的实例;在Android上,可能会被编译成一个ViewGroup的实例)。原生组件的运行方式和HTML有所不同,它们并不需要像HTML那样需要被解析和渲染成DOM,而是由操作系统直接管理和渲染,所以可以说,它们在一种意义上是"存储在操作系统中的"。
所以rn的原生渲染是比H5的解析渲染要更快的。
刷新机制
H5同步刷新
操作dom后立即更新 多次调用多次刷新... 现代浏览器也会有合并操作的case 但是整体依然是立即更新。
rn异步批量更新
js创建和维护虚拟dom, 虚拟dom的状态通过js bridge在线程间传递 实现UI更新,整个过程因为是异步的所以可以做到 合并刷新减少无意义的绘制。但是缺点也比较明显 bridge的瓶颈可能会使页面出现白屏。
加载方式
H5远端下载
我们打包的H5静态资源文件等,会被上传到cdn中 当用户进入页面的时候 浏览器才会实际的去加载对应的文档内容和资源 然后在执行, 渲染...
rn本地运行
rn生成的bundle文件 大部分是直接下发到用户的app里面 当用户进入页面的时候 已经下载好对应的bundle文件了 可以直接执行,渲染。
当然这个H5也是可以通过离线包来优化的,同样可以做到进入页面前下载好对应的资源。