Fast path for emojifying strings

Emojione's regex for detecting emoji is *enourmous* and we were
running it on every display name, room name, message etc every time
those components mounted. Add a much simpler regex to rule out the
majority of strings that contain no emoji and fast-path them.

Makes room switching about 10% faster (in my tests with all the
profiling turned on).
This commit is contained in:
David Baker 2017-09-08 23:05:27 +01:00
parent 1f84c68180
commit ec3ff529e7
2 changed files with 25 additions and 3 deletions

View file

@ -31,13 +31,28 @@ emojione.imagePathPNG = 'emojione/png/';
// Use SVGs for emojis
emojione.imageType = 'svg';
const SIMPLE_EMOJI_PATTERN = /([\ud800-\udbff])([\udc00-\udfff])/;
const EMOJI_REGEX = new RegExp(emojione.unicodeRegexp+"+", "gi");
const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
/*
* Return true if the given string contains emoji
* Uses a much, much simpler regex than emojione's so will give false
* positives, but useful for fast-path testing strings to see if they
* need emojification.
* unicodeToImage uses this function.
*/
export function containsEmoji(str) {
return SIMPLE_EMOJI_PATTERN.test(str);
}
/* modified from https://github.com/Ranks/emojione/blob/master/lib/js/emojione.js
* because we want to include emoji shortnames in title text
*/
export function unicodeToImage(str) {
// fast path
if (!containsEmoji(str)) return str;
let replaceWith, unicode, alt, short, fname;
const mappedUnicode = emojione.mapUnicodeToShort();

View file

@ -15,12 +15,19 @@
*/
import React from 'react';
import {emojifyText} from '../../../HtmlUtils';
import {emojifyText, containsEmoji} from '../../../HtmlUtils';
export default function EmojiText(props) {
const {element, children, ...restProps} = props;
restProps.dangerouslySetInnerHTML = emojifyText(children);
return React.createElement(element, restProps);
// fast path: simple regex to detect strings that don't contain
// emoji and just return them
if (containsEmoji(children)) {
restProps.dangerouslySetInnerHTML = emojifyText(children);
return React.createElement(element, restProps);
} else {
return React.createElement(element, restProps, children);
}
}
EmojiText.propTypes = {