最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 最佳实践React性能优化

    正文概述 掘金(搞毛开发工程师)   2021-02-18   414

    1: React.lazy和React.Suspense封装dynamic函数动态引入组件

    //使用方法
    import React, {Component} from 'react';
    import {dynamic} from './utils';
    
    const LoadingHome = dynamic(() => import('./components/Home'));
    const LoadingUser = dynamic(() => import('./components/User'));
    
    class App extends Component {
        state = {
            showHome: false,
            showUser: false
        }
        toggle = (key) => {
            this.setState({
                [key]: !this.state[key]
            })
        }
        render() {
            let {showHome, showUser} = this.state
            return (
                <div>
                    {showHome && <LoadingHome/>}
                    {showUser && <LoadingUser/>}
                    <button onClick={() => this.toggle('showHome')}>showHome</button>
                    <button onClick={() => this.toggle('showUser')}>showUser</button>
                </div>
            );
        }
    }
    export default App;
    
    //封装dynamic函数
    import React from 'react';
    const Loading = () => <div>Loading</div>;
    
    export function dynamic(loadComponent) {
        const LazyComponent = React.lazy(loadComponent)
        return () => (
            <React.Suspense fallback={<Loading />}>
                <LazyComponent />
            </React.Suspense>
        )
    }
    
    
    function lazy(load) {
        return class extends React.Component {
            state = { Component: null }
            componentDidMount() {
                load().then(result => {
                    this.setState({ Component: result.default});
                });
            }
            render() {
                let { Component } = this.state;
                return Component && <Component />;
            }
        }
    }
    

    最佳实践React性能优化

    2: PureComponent,memo解决无效渲染问题

    import React,{PureComponent,memo,Component} from 'react';
    export default class App extends React.Component{
        constructor(props){
            super(props);
            this.state = {title:'计数器',number:0}
        }
        add = (amount)=>{
            this.setState({number:this.state.number+amount});
        }
        render(){
            console.log('App render');
            return (
                <div>
                    <Counter number={this.state.number}/>
                    <button onClick={()=>this.add(1)}>+1</button>
                    <button onClick={()=>this.add(0)}>+0</button>
                    <ClassTitle title={this.state.title}/>
                    <FunctionTitle title={this.state.title}/>
                </div>
            )
        }
    }
    class Counter extends Component{
        render(){
            console.log('Counter render');
            return (
                <p>{this.props.number}</p>
            )
        }
    }
    class ClassTitle extends Component{
        render(){
            console.log('ClassTitle render');
            return (
                <p>{this.props.title}</p>
            )
        }
    }
    const FunctionTitle = function (props) {
        console.log('FunctionTitle render');
        return  <p>{props.title}</p>;
    }
    

    最佳实践React性能优化 从上面可以看出只要父组件setstate,子组件无论class组件还是函数式组件无论props是否改变都会进行渲染, 很显然这样是不合理的,所以react自带两个东西PureComponent(类组件),memo(函数组件)具体使用如下

    import React,{PureComponent,memo,Component} from 'react';
    export default class App extends React.Component{
        constructor(props){
            super(props);
            this.state = {title:'计数器',number:0}
        }
        add = (amount)=>{
            this.setState({number:this.state.number+amount});
        }
        render(){
            console.log('App render');
            return (
                <div>
                    <Counter number={this.state.number}/>
                    <button onClick={()=>this.add(1)}>+1</button>
                    <button onClick={()=>this.add(0)}>+0</button>
                    <ClassTitle title={this.state.title}/>
                    <FunctionTitle title={this.state.title}/>
                </div>
            )
        }
    }
    
    class Counter extends PureComponent{
        render(){
            console.log('Counter render');
            return (
                <p>{this.props.number}</p>
            )
        }
    }
    class ClassTitle extends PureComponent{
        render(){
            console.log('ClassTitle render');
            return (
                <p>{this.props.title}</p>
            )
        }
    }
    const FunctionTitle = memo(props=>{
        console.log('FunctionTitle render');
        return  <p>{props.title}</p>;
    });
    

    最佳实践React性能优化 效果显著,这样的话无论class组件还是函数式组件 只要props不变化,组件就不会在渲染

    import React from 'react';
    export class PureComponent extends React.Component{
       shouldComponentUpdate(nextProps,nextState){
           return !shallowEqual(this.props,nextProps)||!shallowEqual(this.state,nextState)
       }
    }
    export function memo(OldComponent){
       return class extends PureComponent{
         render(){
           return <OldComponent {...this.props}/>
         }
    }
    }
    export function shallowEqual(obj1,obj2){
       if(obj1 === obj2)
           return true;
       if(typeof obj1 !== 'object' || obj1 ===null || typeof obj2 !== 'object' || obj2 ===null){
           return false;
       }    
       let keys1 = Object.keys(obj1);
       let keys2 = Object.keys(obj2);
       if(keys1.length !== keys2.length){
           return false;
       }
       for(let key of keys1){
           if(!obj2.hasOwnProperty(key) || obj1[key]!== obj2[key]){
               return false;
           }
       }
       return true;
    }
    

    是不是很有趣?


    起源地下载网 » 最佳实践React性能优化

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元