Santosh Nimbalkar
Santosh Nimbalkar

Reputation: 13

setInterval is lagging my page

I am learning Chrome Extension and trying to replace things on a live chat page. I am able to do most of the things, the only thing that is not working for me or rather lagging my page is the option setInterval which I am using to shoot the function after every 3 seconds.

The reason I am using setInterval is because everytime a new chat message is added to the chat console it creates a <td class=".profile-image">New Message</td> in the table. I wanted to add a class to it, so I can change it's appearance using CSS, now for the CSS to work.

When the page loads with all the past messages, it takes 2 secs for all the messages to load, until then there is no class=".profile-image" thing. I have a setTimeout so that the function waits for 3 secs and then shoot. Now the problem is, this will load only once and when there is a new message I will have to run the same function again. Now to get this working, noob me did a setInterval to run this function gain, but the problem is that the entire page lags. What I want to achive is to make the function know that there is a new message and it should add the class automatically.

Thank you for helping!

var dostuff = function() {
  setTimeout(function() {
    jQuery(".profile-image img").each(function() {
      this.src = this.src.replace('small.jpg', 'large.jpg');
      this.src = this.src.replace('small.png', 'large.png');
      $(".profile-image img").attr("height", "64");
      $(".profile-image img").attr("width", "64");
      $(".profile-image img").attr("class", "pro_img");
    });
  }, 2000);
};

setInterval(dostuff, 3000);

Upvotes: 0

Views: 980

Answers (1)

Daniel Beck
Daniel Beck

Reputation: 21485

Observing the page for changes, or hooking into whatever script is inserting these images into the page, would be better. But if you need to stick with polling the page, some improvements you could make that should make this work reasonably well are are:

  1. If you're going to go ahead and poll the page on a setInterval, there's no need to do a setTimeout inside it. All it does is offset the interval.
  2. The DOM search is the expensive part. You're doing a lot of repeated searches for the same items. jQuery(".profile-image img").each will step you through every one of those images. Inside that loop, you again search for every one of those images, three more times. All you need to do is loop through the images once and modify them.
  3. This is minor, but you could do fewer operations by putting those css rules in a class instead of setting them individually.
  4. If there's a classname you can safely remove from the DOM elements as you modify them, you could keep the search from catching the already-modified elements on every iteration.
  5. The more you can specifically target the search, the better. Instead of searching the whole DOM body for .profile-image img maybe there's a closer parent element with an ID you could use to limit the amount of the DOM you have to dig through (#foo .profile-image img). (ID selectors are quick, because they're unique and can just be looked up. Class selectors actually have to search the DOM.)

Result:

var dostuff = function() {
    $(".profile-image img").each(function() {
      this.src = this.src.replace('small.png', 'large.png');
      $(this).addClass('pro_img') // put the height and width rules inside the class CSS
             .removeClass('profile-image'); // if you're not depending on this CSS (or move what you need to preserve into .pro_img)
    });
};

setInterval(dostuff, 3000);

Upvotes: 1

Related Questions