From ec3ff529e7ce4985f1b553c48d7175c7d1097b5a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 8 Sep 2017 23:05:27 +0100 Subject: [PATCH 1/2] 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). --- src/HtmlUtils.js | 15 +++++++++++++++ src/components/views/elements/EmojiText.js | 13 ++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 87e714083b..a046a94363 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -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(); diff --git a/src/components/views/elements/EmojiText.js b/src/components/views/elements/EmojiText.js index cb6cd2ef5e..a48e51f44f 100644 --- a/src/components/views/elements/EmojiText.js +++ b/src/components/views/elements/EmojiText.js @@ -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 = { From ea5726aa4e101afa65d2e8a87813d1ef80fd418d Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 8 Sep 2017 23:14:06 +0100 Subject: [PATCH 2/2] Copyright --- src/HtmlUtils.js | 1 + src/components/views/elements/EmojiText.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index a046a94363..05be98f5fd 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/components/views/elements/EmojiText.js b/src/components/views/elements/EmojiText.js index a48e51f44f..faab0241ae 100644 --- a/src/components/views/elements/EmojiText.js +++ b/src/components/views/elements/EmojiText.js @@ -1,5 +1,6 @@ /* Copyright 2016 Aviral Dasgupta + Copyright 2017 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.