1

I have a chat functionality within my site, where users can chat to each other realtime via chat. We use Layer.com and the chat is built in react. One the I have noticed is that typing in the chat app often has a lag, and I have isolated it down to the "onchange" event that fires when a user is typing in the text area. If I change this to an "onblur" event, then the delay is not present however it kills the typing indicator (other pesrson can see you are typing) which is not great.

Our code is as follows:

import React from "react"

import i18next from "i18next"

import Textarea from 'react-textarea-autosize'


const ENTER = 13;

export default class MessageComposer extends React.Component {


handleChange(event) {
    this.props.onChange(event.target.value)
}

handleKeyDown(event) {
    if (event.keyCode === ENTER && !event.shiftKey) {
        event.preventDefault()
        if (this.props.value.trim().length) {
            this.props.onSubmit()
        }
    }
}

handleImageChange(event) {
    this.props.imageChange()
}

handleVideoChange(event) {
    this.props.videoChange()
}

handleImageFileChange(event) {
    this.props.imageFileChange()
}

handleClick(event) {
    if (this.props.value.trim().length) {
        this.props.onSubmit()
    }
}

render() {

    const { value } = this.props


    return (
        <div className="col-xs-12 col-sm-12 col-md-12 col-lg-12 message-outer-wrapper no-padding" style={ {position: 'absolute', bottom: '0'} }>
<div className="col-xs-12 col-sm-12 col-md-12 col-lg-12 block-composer">

    <div className="col-xs-11 col-sm-11 col-md-11 col-lg-11 input-container no-padding">
    <div className="col-xs-8 col-sm-8" id="messaging-input-wrapper">
        <Textarea
    spellCheck="false"
    autoComplete="off"
    className="messaging-input-div"
    style={ {backgroundColor: '#FFF'} }
    minRows={1}
    maxRows={5}
    placeholder={ i18next.t("messages.composer.placeholder") }
    value={ this.props.value }
    onChange={ this.handleChange.bind(this) } />
</div>
    <div className="col-xs-4 col-sm-4 cam-btn-div" style={ {padding: '0'} }>

    <div id="btn-video-mobile" className="btn btn-file col-xs-4 col-sm-4 no-padding">
        <i className="fa fa-camera"></i>
        <input
    type="file"
    className="image-input"
    accept="image/*"
    style={ {
        position: "absolute",
            top:"0",
            left:"0",
            opacity:"0",
            width:"100%",
            zIndex:"1"
    } }
    capture="camera"
    onChange={ this.handleImageChange.bind(this) } />
    </div>
    <div id="btn-camera-mobile" className="btn btn-file col-xs-4 col-sm-4 no-padding">
        <i className="fa fa-video-camera"></i>
        <input
    type="file"
    className="video-input"
    accept="video/*"
    style={ {
        position: "absolute",
            top:"0",
            left:"0",
            opacity:"0",
            width:"100%",
            zIndex:"1"
    } }
    capture="camcorder"
    onChange={ this.handleVideoChange.bind(this) } />
    </div>
    <div id="btn-file-mobile" className="btn btn-file col-xs-4 col-sm-4 no-padding">
        <i className="fa fa-paperclip"></i>
        <input
    type="file"
    className="image-input-file"
    accept="image/*,video/*"
    style={ {
        position: "absolute",
            top:"0",
            left:"0",
            opacity:"0",
            width:"100%",
            zIndex:"1"
    } }
    capture="filesystem"
    onChange={ this.handleImageFileChange.bind(this) } />
    </div>
    </div>
    </div>
    <div className="col-xs-1 col-sm-1 col-md-1 col-lg-1 send-btn-div"style={ { padding: '0'} }>
<button type="button"  id="btn-send" className="btn" onClick={ this.handleClick.bind(this) }>
<i className="fa fa-paper-plane"></i>
        </button>
        </div>
        </div>
        </div>
)

}
}

Many thanks for your tips in advance!

DrupalNewbie
  • 29
  • 1
  • 4
  • the impact of the bind is not likely to have a very noticeable effect on performance - looking at your code, you bind to `this.props.value` and have a `onChange` handler upstream - far more likely to be responsible for the problem. – Dimitar Christoff Feb 26 '18 at 13:31
  • thanks @DimitarChristoff. Sorry for my ignorance but when you say have an `onChange` handler upstream, are you referring to `handleChange(event) { this.props.onChange(event.target.value) }` ? thanks again! – DrupalNewbie Feb 26 '18 at 15:46
  • yes, you are triggering a set of changes upstream in the component that handles that which presumably alters its own state and exports it as a `value={}` to the component you posted. you should still have the bound methods in the constructor and also, inline styles that are not mutable should be pulled OUT of the render method and saved into a variable so not recreated all the time. see https://marmelab.com/blog/2017/02/06/react-is-slow-react-is-fast.html#beware-of-object-literals-in-jsx – Dimitar Christoff Feb 26 '18 at 16:07

0 Answers0