Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 5 of 5
  1. #1
    New to the CF scene
    Join Date
    Jan 2017
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    setInterval performance issue

    I'm making this fun little web page that emulates a retro computer terminal ala WarGames. My emulation uses setInterval to display one character at a time in rapid succession. I need to be able to control the speed that it displays. The problem is that this only really works well on Internet Explorer or Edge. On any other browser, it is painfully slow. On Chrome it eventually grinds to a halt. I assume it's the DOM manipulation and reflow that is slowing it down but, if that is the case, I cannot figure out a workaround. Any ideas?

    See it live on mavenom.com. Just hit any keys at the prompts.

    Code:
    	var index = 0,
    	strlen = str.length,
    	text = $console.text(),
    	interval = setInterval(function(){
    	if (index < strlen){
    		$console.text(text+=str[index++]);
    		cursor.scrollIntoView(false);
    	} else {
    		clearInterval(interval);
    	}
    }, delay);

  2. #2
    Master Coder sunfighter's Avatar
    Join Date
    Jan 2011
    Location
    Washington
    Posts
    8,083
    Thanks
    37
    Thanked 1,081 Times in 1,077 Posts
    You may be slowed down with the if() statement. This might help:
    Code:
    <script>
    
    function printSentence(id, sentence){
      for(var i = 0; i < sentence.length; i++){
        (function(index) {
          setTimeout(function() {
            document.getElementById(id).innerHTML+=sentence[index]; 
          }, 100 * i);
        })(i);
      }
    }
    
    printSentence("good", "Let's Play War Games");
    </script>
    Evolution - The non-random survival of random variants.
    Physics is actually atoms trying to understand themselves.

  3. #3
    Regular Coder nomanic's Avatar
    Join Date
    Feb 2009
    Location
    United Kingdom
    Posts
    293
    Thanks
    10
    Thanked 33 Times in 33 Posts
    Hi

    Few things
    store getElementById
    innerHTML+= can get slow when innerHTML is HUGE, might be better to just replace it
    Also, setInterval not as reliable as requestInterval (go here - RAF replacements for setTimeout and setInterval - bl.ocks.org)

    Maybe this -

    Code:
    <script>
    
    function printSentence(obj,sentence){
      for(var i = 0; i < sentence.length; i++){
        (function(index) {
          setTimeout(function() {
            obj.innerHTML=sentence.substring(0,index+1);
          }, 100 * i);
        })(i);
      }
    }
    
    printSentence(document.getElementById("good"),"Let's Play War Games");
    </script>
    <DmncAtrny> I will write on a huge cement block "BY ACCEPTING THIS BRICK THROUGH YOUR WINDOW, YOU ACCEPT IT AS IS AND AGREE TO MY DISCLAIMER OF ALL WARRANTIES, EXPRESS OR IMPLIED, AS WELL AS DISCLAIMERS OF ALL LIABILITY, DIRECT, INDIRECT, CONSEQUENTIAL OR INCIDENTAL, THAT MAY ARISE FROM THE INSTALLATION OF THIS BRICK INTO YOUR BUILDING."
    <DmncAtrny> And then hurl it through the window of a Sony officer
    <DmncAtrny> and run like hell

    Portfolio, Tutorials - http://www.nomanic.biz/

  4. #4
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,625
    Thanks
    43
    Thanked 317 Times in 311 Posts
    Quote Originally Posted by swaldner View Post
    I assume it's the DOM manipulation and reflow that is slowing it down but, if that is the case, I cannot figure out a workaround. Any ideas?
    This needs a basic rewrite before any further troubleshooting can be done:

    • Use an HTML id attribute and the Document.getElementById method for the .console element. Accessing it by class requires an unnecessary array-like look-up.
    • Use CharacterData.data instead of Element.innerHTML. The innerHTML setter reserializes the DOM.
    • Use CSS instead of the jQuery html() method, which should also eliminate use of some loops and avoid reserializing the DOM.
    • Append a newline character instead of a br element node to add line-breaks. You're already using CSS white-space: pre and it's wasteful to reserialize the DOM to build an element object when you can add a one-byte character to an existing node.
    • Don't wastefully use regular expression constructors where a regex literal will suffice.
    • Parse the entire text document up front instead of as-you-go. Every time you call the continue and getText function, you're building and invoking regular expressions, which are slow.
    • Regular expressions should be used as a last resort and when you do use them, the expression should be cached in a property or variable if it's reused. You have three static regular expressions in the two aforementioned functions that are being rebuilt on every execution of two of your most frequently used functions.
    • Remove any unnecessary use of timers (such as setTimeout invocations with a timer duration of 0).
    For every complex problem, there is an answer that is clear, simple, and wrong.

    CSS Specifications

  5. #5
    Senior Coder deathshadow's Avatar
    Join Date
    Feb 2016
    Location
    Keene, NH
    Posts
    3,427
    Thanks
    4
    Thanked 488 Times in 476 Posts
    What's with the $, is that jQuery BS or some other bizzaroland library? Say hello to slow.

    Make the function static, anonymous functions have to be reparsed every time they are created.

    String addition for nothing is pretty trashy... not sure why you're wasting time doing that instead of using the DOM with document.createTextNode like a good little doobie.

    If it's actually content why do you need that "scrollIntoView" nonsense?!?

    Really though you've not shown enough of the codebase to actually say how it should be done, it's just what you've shown is throwing up a lot of warning flags.

    @Nomanic has a very interesting approach there, but I'd be worried about the timeouts hitting out of order if some other scripting is hogging the CPU. I've had that happen and it's like "how the hell is setTimeout(dummyFunc, 100) going off AFTER setTimeout(dummyFunc, 200)?!?

    Though that's more of a spiderMonkey issue (firefox/gecko based browser) than it is other scripting engines. I swear these days I spend more time hacking around FF and Safari than I do IE.
    Last edited by deathshadow; Jan 18th, 2017 at 02:05 AM.
    “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies.” – C.A.R. Hoare, The 1980 ACM Turing Award Lecture
    http://www.cutcodedown.com


 

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •