render渲染

触发render条件

1.组件mount

React组件构建并将DOM元素插入页面的过程称为挂载。当组件首次渲染的时候会调用render,这个过程不可避免。

2.setState方法被调用(组件或父组件中

通常情况下执行setState会触发 render。

执行setState的时候一定会重新渲染吗?不一定,当setState传入null的时候,不会触发render;如果setState的参数不变,即判断state并未发生改变,也不会重新渲染。

3.父组件重新渲染

原则:只要一个节点变了,那么从它开始回溯的父节点全都是变的

react父节点数据变了,但传给子节点的没变,子节点变不变?只要父组件重新渲染了,即使传入子组件的props未发生变化,子组件也会重新渲染进而触发render。

如何在数据不变的情况下阻止子节点render?shouldComponentUpdate/pure component/memo

4.调用forceUpdate


渲染详细过程:

1.调用React.createElement()编译成虚拟v-DOM节点

2.diff

3.调用ReactDOMComponent(vdom).mountComponent()将虚拟DOM变成真实的DOM

4.调用appendChild(domNode)插入DOM树,显示出来

diff & patch

更新视图的过程(diff、patch)


Rendering

Batching

Whenever you call setState on a component, React will mark it as dirty. At the end of the event loop, React looks at all the dirty components and re-renders them.

This batching means that during an event loop, there is exactly one time when the DOM is being updated. This property is key to building a performant app and yet is extremely difficult to obtain using commonly written JavaScript. In a React application, you get it by default.

 setState mark component as dirty

Sub-tree Rendering

When setState is called, the component rebuilds the virtual DOM for its children. If you call setState on the root element, then the entire React app is re-rendered. All the components, even if they didn’t change, will have their render method called. This may sound scary and inefficient but in practice, this works fine because we’re not touching the actual DOM.

First of all, we are talking about displaying the user interface. Because screen space is limited, you’re usually displaying on the orders of hundreds to thousands of elements at a time. JavaScript has gotten fast enough business logic for the whole interface is manageable.

Another important point is that when writing React code, you usually don’t call setState on the root node every time something changes. You call it on the component that received the change event or couple of components above. You very rarely go all the way to the top. This means that changes are localized to where the user interacts.

re-render whole subtree

性能和渲染(Render)正相关

React的处理render的基本思维模式是每次一有变动就会去重新渲染整个应用。在Virtual DOM没有出现之前,最简单的方法就是直接调用innerHTML。

当DOM树很大时,遍历两棵树进行各种比对还是相当耗性能的,特别是在顶层setState一个微小的修改,默认会去遍历整棵树,这个过程会损耗性能。

VirtualDOM厉害的地方并不是说它比直接操作DOM快,而是说不管数据怎么变,都会尽量以最小的代价去更新DOM。React将render函数返回的虚拟DOM树与老的进行比较,从而确定DOM要不要更新、怎么更新。

基于虚拟DOM和高效Diff算法的完美配合,实现了对DOM最小粒度的更新。在个别复杂业务场景下,性能问题依然会困扰,此时需要采取一些措施来提升运行性能,很重要的一个方向就是避免不必要的渲染

优化Render

当子组件过多或者组件的层级嵌套过深时,反复重新渲染状态没有改变的组件,可能会增加渲染时间又会影响用户体验,此时就需要对render进行优化。不必要的render会带来性能问题,因此主要优化思路就是减少不必要的render。


Selective Sub-tree Rendering

Finally, you have the possibility to prevent some sub-trees to re-render. If you implement the following method on a component:

boolean shouldComponentUpdate(object nextProps, object nextState)

based on the previous and next props/state of the component, you can tell React that this component did not change and it is not necessary to re-render it. When properly implemented, this can give you huge performance improvements.

In order to be able to use it, you have to have to be able to compare JavaScript objects. There are many issues that raises such as should the comparison be shallow or deep; if it’s deep should we use immutable data structures or do deep copies.

And you want to keep in mind that this function is going to be called all the time, so you want to make sure that it takes less time to compute than heuristic than the time it would have taken to render the component, even if re-rendering was not strictly needed.

Selective Sub-tree Rendering: shouldComponentUpdate  

第一次进入到页面的时候,会在没数据的情况下有一次渲染;等fetch成功后会再一次进行渲染。怎么解决第一次进入页面没数据的情况下,页面渲染时不报错?

1.给定同fetch回来的数据格式一样的默认数据,数组使用空数组,对象则属性都需要存在,值为默认值或者空值。

2.思路是条件渲染,设置一个判断条件,条件值不同,渲染的组件不同。

constructor(){

    this.state = {

        isLoading = true,

        data: []

    }

}

render(){

    return (

        {

            this.state.isLoading

            ? <Loading />

            : <Content />

        }

    )

}

3. 使用? operator


一个模块中props,data中存在同名的变量,会渲染哪一个,为什么?

react结合immutable.js为什么能提高渲染效率

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354