³õѧÕß¶ÔReact¿ÉÄÜÂú»³ÆÚ´ý£¬¾õµÃReact¿ÉÄÜÍ걬ÆäËüÒ»Çпò¼Ü£¬ÉõÖÁ²»ÇÐʵ¼ÊµØÈÏΪReact¿ÉÄÜÁ¬ÔÉúµÄäÖȾ¶¼ÄÜÍ걬¡ª¡ª¶Ô¿ò¼ÜµÄ¿ñÈÈȷʵ»á³öÏÖÕâÑùµÄ²»ÇÐʵ¼ÊµÄÆÚ´ý¡£ÈÃÎÒÃÇÀ´¿´¿´ReactµÄ¹Ù·½ÊÇÔõô˵µÄ¡£React¹Ù·½ÎĵµÔÚAdvanced
PerformanecÕâÒ»½Ú£¬ÕâÑùдµÀ£º
One of the first questions people ask when considering React for a project is whether their application will be as fast and responsive as an equivalent non-React version |
ÏÔÈ»React×Ô¼ºÒ²ÆäʵֻÊÇÏ뾡Á¿´ïµ½¸ú·ÇReact°æ±¾ÏàÈôµÄÐÔÄÜ£¬
ÄãËù²»ÖªµÀµÄrender
reactµÄ×é¼þäÖȾ·ÖΪ³õʼ»¯äÖȾºÍ¸üÐÂäÖȾ¡£ÔÚ³õʼ»¯äÖȾµÄʱºò»áµ÷Óøù×é¼þϵÄËùÓÐ×é¼þµÄrender·½·¨½øÐÐäÖȾ£¬ÈçÏÂͼ£¨ÂÌÉ«±íʾÒÑäÖȾ£¬ÕâÒ»²ãÊÇûÓÐÎÊÌâµÄ£©£º

µ«Êǵ±ÎÒÃÇÒª¸üÐÂij¸ö×Ó×é¼þµÄʱºò£¬ÈçÏÂͼµÄÂÌÉ«×é¼þ£¨´Ó¸ù×é¼þ´«µÝÏÂÀ´Ó¦ÓÃÔÚÂÌÉ«×é¼þÉϵÄÊý¾Ý·¢Éú¸Ä±ä£©£º

ÎÒÃǵÄÀíÏë״̬ÊÇÖ»µ÷Óùؼü·¾¶ÉÏ×é¼þµÄrender£¬ÈçÏÂͼ£º

µ«ÊÇreactµÄĬÈÏ×ö·¨Êǵ÷ÓÃËùÓÐ×é¼þµÄrender£¬ÔÙ¶ÔÉú³ÉµÄÐéÄâDOM½øÐжԱȣ¬Èç²»±äÔò²»½øÐиüС£ÕâÑùµÄrenderºÍÐéÄâDOMµÄ¶Ô±ÈÃ÷ÏÔÊÇÔÚÀË·Ñ£¬ÈçÏÂͼ£¨»ÆÉ«±íʾÀ˷ѵÄrenderºÍÐéÄâDOM¶Ô±È£©

Tips:
²ð·Ö×é¼þÊÇÓÐÀûÓÚ¸´ÓúÍ×é¼þÓÅ»¯µÄ¡£
Éú³ÉÐéÄâDOM²¢½øÐбȶԷ¢ÉúÔÚrender()ºó£¬¶ø²»ÊÇrender()ǰ¡£
¸üн׶εÄÉúÃüÖÜÆÚ
componentWillReceiveProps(object nextProps)£ºµ±¹ÒÔØµÄ×é¼þ½ÓÊÕµ½ÐµÄpropsʱ±»µ÷Óᣴ˷½·¨Ó¦¸Ã±»ÓÃÓڱȽÏthis.props
ºÍ nextPropsÒÔÓÃÓÚʹÓÃthis.setState()Ö´ÐÐ״̬ת»»¡££¨×é¼þÄÚ²¿Êý¾ÝÓб仯£¬Ê¹ÓÃstate£¬µ«ÊÇÔÚ¸üн׶ÎÓÖÒªÔÚprops¸Ä±äµÄʱºò¸Ä±ästate£¬ÔòÔÚÕâ¸öÉúÃüÖÜÆÚÀïÃæ£©
shouldComponentUpdate(object nextProps,
object nextState)£º -boolean µ±×é¼þ¾ö¶¨ÈκθıäÊÇ·ñÒª¸üе½DOMʱ±»µ÷Óá£×÷Ϊһ¸öÓÅ»¯ÊµÏֱȽÏthis.props
ºÍ nextProps ¡¢this.state ºÍ nextState £¬Èç¹ûReactÓ¦¸ÃÌø¹ý¸üУ¬·µ»Øfalse¡£
componentWillUpdate(object nextProps,
object nextState)£ºÔÚ¸üз¢Éúǰ±»Á¢¼´µ÷Óá£Äã²»ÄÜÔڴ˵÷ÓÃthis.setState()¡£
componentDidUpdate(object prevProps,
object prevState)£º ÔÚ¸üз¢Éúºó±»Á¢¼´µ÷Óᣣ¨¿ÉÒÔÔÚDOM¸üÐÂÍêÖ®ºó£¬×öһЩÊÕβµÄ¹¤×÷£©
Tips:
ReactµÄÓÅ»¯ÊÇ»ùÓÚshouldComponentUpdateµÄ£¬¸ÃÉúÃüÖÜÆÚĬÈÏ·µ»Øtrue£¬ËùÒÔÒ»µ©prop»òstateÓÐÈκα仯£¬¶¼»áÒýÆðÖØÐÂrender¡£
shouldComponentUpdate
reactÔÚÿ¸ö×é¼þÉúÃüÖÜÆÚ¸üеÄʱºò¶¼»áµ÷ÓÃÒ»¸öshouldComponentUpdate(nextProps,
nextState)º¯Êý¡£ËüµÄÖ°Ôð¾ÍÊÇ·µ»Øtrue»òfalse£¬true±íʾÐèÒª¸üУ¬false±íʾ²»ÐèÒª£¬Ä¬ÈÏ·µ»ØÎªtrue£¬¼´±ãÄãûÓÐÏÔʾµØ¶¨Òå
shouldComponentUpdate º¯Êý¡£Õâ¾Í²»ÄѽâÊÍÉÏÃæ·¢ÉúµÄ×ÊÔ´ÀË·ÑÁË¡£
ΪÁ˽øÒ»²½ËµÃ÷ÎÊÌ⣬ÎÒÃÇÔÙÒýÓÃÒ»ÕŹÙÍøµÄͼÀ´½âÊÍ£¬ÈçÏÂͼ£¨ SCU±íʾshouldComponentUpdate£¬ÂÌÉ«±íʾ·µ»Øtrue(ÐèÒª¸üÐÂ)£¬ºìÉ«±íʾ·µ»Øfalse(²»ÐèÒª¸üÐÂ)£»vDOMEq±íʾÐéÄâDOM±È¶Ô£¬ÂÌÉ«±íʾһÖÂ(²»ÐèÒª¸üÐÂ)£¬ºìÉ«±íʾ·¢Éú¸Ä±ä(ÐèÒª¸üÐÂ)£©£º

¸ù¾ÝäÖȾÁ÷³Ì£¬Ê×ÏÈ»áÅжÏshouldComponentUpdate(SCU)ÊÇ·ñÐèÒª¸üС£Èç¹ûÐèÒª¸üУ¬Ôòµ÷ÓÃ×é¼þµÄrenderÉú³ÉеÄÐéÄâDOM£¬È»ºóÔÙÓë¾ÉµÄÐéÄâDOM¶Ô±È(vDOMEq)£¬Èç¹û¶Ô±ÈÒ»Ö¾Ͳ»¸üУ¬Èç¹û¶Ô±È²»Í¬£¬Ôò¸ù¾Ý×îСÁ£¶È¸Ä±äÈ¥¸üÐÂDOM£»Èç¹ûSCU²»ÐèÒª¸üУ¬ÔòÖ±½Ó±£³Ö²»±ä£¬Í¬Ê±Æä×ÓÔªËØÒ²±£³Ö²»±ä¡£
C1¸ù½Úµã£¬ÂÌÉ«SCU (true)£¬±íʾÐèÒª¸üУ¬È»ºóvDOMEqºìÉ«£¬±íʾÐéÄâDOM²»Ò»Ö£¬ÐèÒª¸üС£
C2½Úµã£¬ºìÉ«SCU (false)£¬±íʾ²»ÐèÒª¸üУ¬ËùÒÔC4,C5¾ù²»ÔÙ½øÐмì²é
C3½ÚµãͬC1£¬ÐèÒª¸üÐÂ
C6½Úµã£¬ÂÌÉ«SCU (true)£¬±íʾÐèÒª¸üУ¬È»ºóvDOMEqºìÉ«£¬±íʾÐéÄâDOM²»Ò»Ö£¬¸üÐÂDOM¡£
C7½ÚµãͬC2
C8½Úµã£¬ÂÌÉ«SCU (true)£¬±íʾÐèÒª¸üУ¬È»ºóvDOMEqÂÌÉ«£¬±íʾÐéÄâDOMÒ»Ö£¬²»¸üÐÂDOM¡£
´ø¿ÓµÄд·¨£º
{¡this.props} (²»ÒªÀÄÓã¬ÇëÖ»´«µÝcomponentÐèÒªµÄprops£¬´«µÃÌ«¶à£¬»òÕß²ã´Î´«µÃÌ«É¶¼»á¼ÓÖØshouldComponentUpdateÀïÃæµÄÊý¾Ý±È½Ï¸ºµ££¬Òò´Ë£¬Ò²ÇëÉ÷ÓÃspread
attributes£¨<Component {¡props} />£©)¡£
::this.handleChange()¡£(Ç뽫·½·¨µÄbindÒ»ÂÉÖÃÓÚconstructor)
this.handleChange.bind(this,id)
¸´ÔÓµÄÒ³Ãæ²»ÒªÔÚÒ»¸ö×é¼þÀïÃæÐ´Íê¡£
Ç뾡Á¿Ê¹ÓÃconst element¡£
mapÀïÃæÌí¼Ókey£¬²¢ÇÒkey²»ÒªÊ¹ÓÃindex£¨¿É±äµÄ£©¡£¾ßÌå¿É²Î¿¼Ê¹ÓÃPerf¹¤¾ßÑо¿React
Key¶ÔäÖȾµÄÓ°Ïì
¾¡Á¿ÉÙÓÃsetTimeOut»ò²»¿É¿ØµÄrefs¡¢DOM²Ù×÷¡£
Êý¾Ý¾¡¿ÉÄܼòµ¥Ã÷ÁË£¬±âƽ»¯¡£
ÐÔÄܼì²â¹¤¾ß
React¹Ù·½ÌṩµÄ£ºReact.addons.Perf
react¹Ù·½Ìṩһ¸ö²å¼þReact.addons.Perf¿ÉÒÔ°ïÖúÎÒÃÇ·ÖÎö×é¼þµÄÐÔÄÜ£¬ÒÔÈ·¶¨ÊÇ·ñÐèÒªÓÅ»¯¡£
´ò¿ªconsoleÃæ°å£¬ÏÈÊäÈëPerf.start()Ö´ÐÐһЩ×é¼þ²Ù×÷£¬ÒýÆðÊý¾Ý±ä¶¯£¬×é¼þ¸üУ¬È»ºóÊäÈëPerf.stop()¡££¨½¨ÒéÒ»´ÎÖ»Ö´ÐÐÒ»¸ö²Ù×÷£¬ºÃ½øÐзÖÎö£©
ÔÙÊäÈëPerf.printInclusive²é¿´ËùÓÐÉæ¼°µ½µÄ×é¼þrender£¬ÈçÏÂͼ£¨¹Ù·½Í¼Æ¬£©£º

»òÕßÊäÈëPerf.printWasted()²é¿´Ï²»ÐèÒªµÄµÄÀË·Ñ×é¼þrender£¬ÈçÏÂͼ£¨¹Ù·½Í¼Æ¬£©£º

ÓÅ»¯Ç°£º

ÓÅ»¯ºó£º

ÆäËûµÄ¼ì²â¹¤¾ß
react-perf-toolΪReactÓ¦ÓÃÌṩÁËÒ»ÖÖ¿ÉÊÓ»¯µÄÐÔÄܼì²â·½°¸£¬¸Ã¹¤³ÌͬÑùÊÇ»ùÓÚReact.addons£¬µ«ÊÇʹÓÃͼ±íÀ´ÏÔʾ½á¹û£¬¸ü¼Ó·½±ã¡£

React¹Ù·½µÄ½â¾ö·½°¸
PureRenderMixin(es5)
var PureRenderMixin = require('react-addons-pure-render-mixin'); React.createClass({ mixins: [PureRenderMixin], render: function() { return <div className={this.props.className}>foo</div>; } }); |
Shallow Compare (es6)
var shallowCompare = require('react-addons-shallow-compare'); export class SampleComponent extends React.Component { shouldComponentUpdate(nextProps, nextState) { return shallowCompare(this, nextProps, nextState); } render() { return <div className={this.props.className}>foo</div>; } } |
es7×°ÊÎÆ÷µÄд·¨£º
import pureRender from "pure-render-decorator" ... @ pureRender class Person extends Component { render() { console.log("ÎÒre-renderÁË"); const {name,age} = this.props; return ( <div> <span>ÐÕÃû: </span> <span>{name}</span> <span> age:</span> <span>{age}</span> </div> ) } } |
pureRenderºÜ¼òµ¥£¬¾ÍÊǰѴ«½øÀ´µÄcomponentµÄshouldComponentUpdate¸øÖØÐ´µôÁË£¬ÔÀ´µÄshouldComponentUpdate£¬ÎÞÂÛÔõÑù¶¼ÊÇreturn
ture£¬ÏÖÔÚ²»ÁË£¬ÎÒÒªÓÃshallowCompare±ÈÒ»±È£¬shallowCompare´úÂë¼°Æä¼òµ¥£¬ÈçÏ£º
function shallowCompare(instance, nextProps, nextState) { return !shallowEqual(instance.props, nextProps) || !shallowEqual(instance.state, nextState); } |
ȱµã
shallowEqualÆäʵֻ±È½ÏpropsµÄµÚÒ»²ã×ÓÊôÐÔÊDz»ÊÇÏàͬ£¬¾ÍÏñÉÏÊö´úÂ룬props
ÊÇÈçÏÂ
{ detail: { name: "123", age: "123" } } |
ËûÖ»»á±È½Ïprops.detail ===nextProps.detail£¬µ¼ÖÂÔÚ´«È븴ÔÓµÄÊý¾ÝµÄÇé¿öÏ£¬ÓÅ»¯Ê§Ð§¡£
immutable.js
ÎÒÃÇÒ²¿ÉÒÔÔÚ shouldComponentUpdate() ÖÐʹÓÃʹÓÃ
deepCopy ºÍ deepCompare À´±ÜÃâÎÞ±ØÒªµÄ render()£¬µ« deepCopy ºÍ
deepCompare Ò»°ã¶¼ÊǷdz£ºÄÐÔÄܵġ£
Immutable Data ¾ÍÊÇÒ»µ©´´½¨£¬¾Í²»ÄÜÔÙ±»¸ü¸ÄµÄÊý¾Ý¡£¶Ô
Immutable ¶ÔÏóµÄÈκÎÐ޸ĻòÌí¼Óɾ³ý²Ù×÷¶¼»á·µ»ØÒ»¸öÐ嵀 Immutable ¶ÔÏó¡£
Immutable ʵÏÖµÄÔÀíÊÇ Persistent Data Structure£¨³Ö¾Ã»¯Êý¾Ý½á¹¹£©£¬Ò²¾ÍÊÇʹÓþÉÊý¾Ý´´½¨ÐÂÊý¾Ýʱ£¬Òª±£Ö¤¾ÉÊý¾Ýͬʱ¿ÉÓÃÇÒ²»±ä¡£Í¬Ê±ÎªÁ˱ÜÃâ
deepCopy °ÑËùÓнڵ㶼¸´ÖÆÒ»±é´øÀ´µÄÐÔÄÜËðºÄ£¬Immutable ʹÓÃÁË Structural
Sharing£¨½á¹¹¹²Ïí£©£¬¼´Èç¹û¶ÔÏóÊ÷ÖÐÒ»¸ö½Úµã·¢Éú±ä»¯£¬Ö»ÐÞ¸ÄÕâ¸ö½ÚµãºÍÊÜËüÓ°ÏìµÄ¸¸½Úµã£¬ÆäËü½ÚµãÔò½øÐй²Ïí¡£Çë¿´ÏÂÃæ¶¯»£º

Immutable ÔòÌṩÁ˼ò½à¸ßЧµÄÅжÏÊý¾ÝÊÇ·ñ±ä»¯µÄ·½·¨£¬Ö»Ðè ===
ºÍ is ±È½Ï¾ÍÄÜÖªµÀÊÇ·ñÐèÒªÖ´ÐÐ render()£¬¶øÕâ¸ö²Ù×÷¼¸ºõ 0 ³É±¾£¬ËùÒÔ¿ÉÒÔ¼«´óÌá¸ßÐÔÄÜ¡£Ð޸ĺóµÄ
shouldComponentUpdate ÊÇÕâÑùµÄ£º
import { is } from 'immutable'; shouldComponentUpdate: (nextProps = {}, nextState = {}) => { const thisProps = this.props || {}, thisState = this.state || {}; if (Object.keys(thisProps).length !== Object.keys(nextProps).length || Object.keys(thisState).length !== Object.keys(nextState).length) { return true; } for (const key in nextProps) { if (!is(thisProps[key], nextProps[key])) { return true; } } for (const key in nextState) { if (thisState[key] !== nextState[key] || !is(thisState[key], nextState[key])) { return true; } } return false; } react-immutable-render-mixin |
ÕâÊÇÒ»¸öfacebook/immutable-jsµÄreact pure
render mixin µÄ¿â£¬¿ÉÒÔ¼ò»¯ºÜ¶àд·¨¡£
ʹÓÃreact-immutable-render-mixin¿ÉÒÔʵÏÖ×°ÊÎÆ÷µÄд·¨¡£
import React from 'react'; import { immutableRenderDecorator } from 'react-immutable-render-mixin'; @immutableRenderDecorator class Test extends React.Component { render() { return <div></div>; } } |
Immutable Ïê½â¼° React ÖÐʵ¼ù
ÎÞ״̬×é¼þ
ΪÁ˱ÜÃâÒ»¶¨³Ì¶ÈµÄÀË·Ñ£¬react¹Ù·½»¹ÔÚ0.14°æ±¾ÖмÓÈëÁËÎÞ״̬×é¼þ£¬ÈçÏ£º
// es6 const HelloMessage = (props) => <div>Hello {props.name}</div>; |
¸ß½××é¼þ£¨½ÓÏÂÀ´µÄ·½Ïò£©
´ó²¿·ÖʹÓÃmixinºÍclass extendsµÄµØ·½£¬¸ß½××é¼þ¶¼ÊǸüºÃµÄ·½°¸¡ª¡ª±Ï¾¹×éºÏÓÅÓڼ̳С£
|