performance: Speed up search bar highlighting.

When we're highlighting all the people that show
up in a search from the search bar, we need
to fairly expensively build a regex from the
query:

    query = query.toLowerCase();
    query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
    const regex = new RegExp('(^' + query + ')', 'ig');

Even though the final regex is presumably cached, we
still needed to do that `query.replace` for every person.
Even for relatively small numbers of persons, this would
show up in profiles as expensive.

Now we just build the query once by using a pattern
where you call a function outside the loop to build
an inner function that's used in the loop that closes
on the `query` above.  The diff probably shows this
better than I explained it here.
This commit is contained in:
Steve Howell
2019-12-24 14:31:52 +00:00
committed by Tim Abbott
parent 6a9eaebff2
commit abdd4b54f4
2 changed files with 26 additions and 17 deletions

View File

@@ -2,12 +2,15 @@ function stream_matches_query(stream_name, q) {
return common.phrase_match(q, stream_name);
}
function highlight_person(query, person) {
const hilite = typeahead_helper.highlight_query_in_phrase;
function make_person_highlighter(query) {
const hilite = typeahead_helper.make_query_highlighter(query);
return function (person) {
if (settings_org.show_email()) {
return hilite(query, person.full_name) + " <" + hilite(query, person.email) + ">";
return hilite(person.full_name) + " <" + hilite(person.email) + ">";
}
return hilite(query, person.full_name);
return hilite(person.full_name);
};
}
function match_criteria(operators, criteria) {
@@ -148,13 +151,15 @@ function get_group_suggestions(all_persons, last, operators) {
const prefix = Filter.operator_to_prefix('pm-with', negated);
const highlight_person = make_person_highlighter(last_part);
const suggestions = _.map(persons, function (person) {
const term = {
operator: 'pm-with',
operand: all_but_last_part + ',' + person.email,
negated: negated,
};
const name = highlight_person(last_part, person);
const name = highlight_person(person);
const description = prefix + ' ' + Handlebars.Utils.escapeExpression(all_but_last_part) + ',' + name;
let terms = [term];
if (negated) {
@@ -202,8 +207,10 @@ function get_person_suggestions(all_persons, last, operators, autocomplete_opera
const prefix = Filter.operator_to_prefix(autocomplete_operator, last.negated);
const highlight_person = make_person_highlighter(query);
const objs = _.map(persons, function (person) {
const name = highlight_person(query, person);
const name = highlight_person(person);
const description = prefix + ' ' + name;
const terms = [{
operator: autocomplete_operator,

View File

@@ -51,12 +51,13 @@ exports.highlight_with_escaping_and_regex = function (regex, item) {
return result;
};
exports.highlight_query_in_phrase = function (query, phrase) {
exports.make_query_highlighter = function (query) {
let i;
query = query.toLowerCase();
query = query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&');
const regex = new RegExp('(^' + query + ')', 'ig');
return function (phrase) {
let result = "";
const parts = phrase.split(' ');
for (i = 0; i < parts.length; i += 1) {
@@ -66,6 +67,7 @@ exports.highlight_query_in_phrase = function (query, phrase) {
result += exports.highlight_with_escaping_and_regex(regex, parts[i]);
}
return result;
};
};
exports.render_typeahead_item = function (args) {