1

I have some JavaScript which replaces smiley symbols with their corresponding images in my blog.
So symbols like :) or :( are replaced by proper <img> tags.

Currently there are around 50 smiley symbols that can be used. But in any page only a few of them will be used obviously. The script has lines of the form element.replace(smileyRegex, <imgTags>) for each smiley. The problem is that, due to a large number of these regex matching lines, the script causes a slight delay after the page is loaded.

I'm thinking of the following method to make this more efficient: To call replace with a large regex which matches all smiley symbols as first argument, and a function which chooses proper image from an array as the second argument.
Will this usage be more efficient than a number of separate replace calls that may or may not match?

1
  • Write your own jsperf.com test and look at it in a few popular browsers. The answer will either be obvious or there will be no single right answer. Commented Aug 17, 2011 at 8:58

4 Answers 4

4

Having one regex match all occurences of smileys would be a lot more efficient. That is because it would only be one iteration through the source, instead of one interation per smiley. Then have an appropriate hashtable / object with smiley -> img src would be an efficient lookup:

var smileyImgMap = {
    ":)" : "happysmiley.png",
    ":(" : "sadsmiley.png"
};

Then use it like this:

var smileyImg = smileyImgMap[":)"];

I think you get the idea.

Sign up to request clarification or add additional context in comments.

1 Comment

You are right! Using a single regex made a big difference. Now the smiley replacement takes place in a breeze. With smileys having words and common characters in their representation, the single regex had a length of around 200. But still worth the effort :)
2

I wrote this jsperf to test the two concepts. It probably needs more representative data put in it for what type of source data you're searching through, how many different things you're looking for and how often you are likely to find a match. You can fill those into the basic framework in the jsperf and then look at it in different browsers.

The regex w/callback option looks basically like this:

var replaceLookup = {aa: "--", bb: "++", cc: "**"};
var result = sourceStr.replace(/aa|bb|cc/g, function(str, p1, p2, offset, s)   
{
    return(replaceLookup[str]);
});

2 Comments

As a note to this is that the more replaces you will run, the bigger the difference would get.
When you do a large number of replaces on a large body of text, there is a noticeable delay, and sometimes the browser freezes even. But the single regex method works with almost zero delay.
0

Almost any "which is more efficient" question is going to get an answer like "it depends". What you're proposing certainly sounds promising but you really should just benchmark on a few different browsers and be sure.

Another solution would be to render the page as is, and then asynchronously go through each of the 50 smileys and run the regexps one at a time. It would certain take more time, but your user wouldn't perceive the delay (since the page is already rendered).

Comments

-1

One way to speed it up is to place all smileys in one image and use it as a css sprite.

.smily1 {background:url('/images/allSmilyImage.png') 0px 0px}
.smily2 {background:url('/images/allSmilyImage.png') 0px 50px}
.smily3 {background:url('/images/allSmilyImage.png') 50px 100px}
...

Specify the smileys image position in a css file then use the hash mapping as @jishi suggested for mapping the css styles for the corresponding smily.

var smileyClassMap = {
  ":)" : "smily1",
  ":(" : "smily2",
  ":P" : "smily3"
};

Replace the text smileys with a <span class="smily1" style="display:block" /> tag or similar

1 Comment

It was never about loading the images, the smiley images are rather too small in size and not all of them are required (even less than the allSmilyImage in most of the cases!)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.