Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums JavaScript Optimizing my JavaScript/jQuery code — listeners

  • This topic is empty.
Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #178151
    Senff
    Participant

    OK so I’ve been doing some custom JS/jQ code (for some plugin, later down the road) and I need some help with how to optimize my code.

    Let’s say there’s something parallax-y. The pen below (at http://codepen.io/senff/pen/BFjHb ) does something to two elements (based on how much you’ve scrolled) on page load, when the user scrolls, or resizes the window.

    http://codepen.io/senff/pen/BFjHb

    So in essence, it does this:

    $(document).ready(function(){ checkPos(); })
    $(window).resize(function() { checkPos(); });
    $(window).scroll(function() { checkPos(); });
    
    function checkPos() {
        // this is where something is done to some element
        // checks scrolled position value and then does something...
        // ...to two elements based on that
    }
    

    So while it works, functionally, I feel this is not the proper use. I recently read some article that it’s not good (for performance) to have the code listen to the changes in the document or window (load, scroll, resize), but that the code should listen to the actual element that needs manipulation. Which makes sense to me but I can’t find it anymore.

    So, with that in mind (and I realize it’s very basic so that it may be a case of “depends what you want to do”), how should I tackle this? Is this a case of checking if the element is on screen, and fire something when it changes or something….?

    Thanks much,

    #178153
    Senff
    Participant

    I found the article and this is the part I was referring to:

    Don’t bind directly to scroll event.
    Use an interval to update element positions. The scroll is called like a bajillion times a second and can cause crazy performance hiccups. Instead, for elements that are parallaxing, just update thier position every 10ms or so.
    scrollIntervalID = setInterval(animateStuff, 10);

    So with that in mind, I did that and now it’s this (see JS tab):

    http://codepen.io/senff/pen/kFehd

    That works fine, but now I’m wondering… when you DON’T scroll (and just look at the page), the function is STILL fired every 10ms. That sounds a little excessive as well.

    Can someone explain why one is better (for performance) than the other?

    #178154
    nixnerd
    Participant

    Hey @Senff,

    I’ve been doing a lot of complex listeners lately and I’ve wondered the same thing myself. However, in each case, I am listening to only the element I’m wanting to manipulate, to at least mitigate the issue of listening to the entire DOM all the time.

    Admittedly, my situation is much different, as I’m listening to an input field when it’s being typed in. Much different.

    However, I’d like to ask why you don’t use a plugin for this? Scroll Magic is great and I’ve NEVER had performance issues with it. That’s partly due to the fact that it uses GSAP and not jQuery for animations. I’m not sure about it’s event listeners but you might want to check it out (if you haven’t already).

    Again, even on mobile (if you follow the recommendations), it works just fine!

    #178155
    Senff
    Participant

    However, in each case, I am listening to only the element I’m wanting to manipulate, to at least mitigate the issue of listening to the entire DOM all the time.

    How would you do that in the case of my Pen above? Meaning, what is the correct line/syntax/use to check if something changes on my red or blue element? Or something…

    However, I’d like to ask why you don’t use a plugin for this?

    Well, it’s because I’m trying to get my hands dirty creating my own plugin. It’s an uber-basic “sticky menu on scroll” kind of thing (and mostly for my own use, not trying to change the world with it), but I want to make it as optimized as possible anyways, just in case others want to use it.

    #178160
    nixnerd
    Participant

    How would you do that in the case of my Pen above?

    I don’t know that you could. Not without making it look horrible. Because the whole point is that you’re going to have multiple elements doing something… different things, when scrolling is happening. Instead of checking the position every single second, what you MIGHT be able to do is have a callback when the position changes. I’m not totally sure but @JacobPeters might know.

    Well, it’s because I’m trying to get my hands dirty creating my own plugin.

    That’s legit. I enjoy building my own things too. I don’t know that I’m good enough at JS to write my own parallax plugin… so Godspeed sir.

    I would maybe recommend taking a look at Scroll Magic’s code base to see how they do it. Even if that’s the only thing you model yours after… I think they’re doing something right because it looks smooth as butter every time I use it.

    #178161
    nixnerd
    Participant

    Also… have you tried the #javascript IRC channel on Freenode?

    #178174
    Senff
    Participant

    @NIX — it’s not that big of a problem that I need to check how a more serious/pro plugin does it. I’m really just trying to get down to the basics and wanted to know if there was a ‘generally accepted’ way of how to start it. :)


    @Soronbe
    — thanks for your code, however there is still a $(window).on('scroll', start_chain); event in there, which I was trying to avoid (or come up with a better alternative). From my understanding, both methods:

    $(window).scroll(function() { checkPos(); }); — doesn’t do anything when you don’t scroll, but when you DO, the “scroll is called like a bajillion times a second and can cause crazy performance hiccups.
    scrollIntervalID = setInterval(checkPos, 10); — much less calls when you actually scroll, but keeps calling the checkPos function even when you don’t scroll.

    So I guess both ways have their pros and cons…. I think?

    #178189
    shaneisme
    Participant

    I attach a debouncer to any scroll function and haven’t had any issues.

    http://davidwalsh.name/javascript-debounce-function

    #178827
    JacobPeters
    Participant

    I really dislike attaching anything to a scroll event. The problem is that it blocks the scrolling of the page while the function runs.

    requestAnimationFrame with a function that checks for the window.pageYoffset is going to be the best bet for this. For parallax, you want the position to be updated every frame, and that is what rAF does. It queues your function to run just before the next frame is rendered.

    I made two forks. One runs the function every frame, and the other gets triggered by the scroll event which is then cleared.

    I used jQuery to set the event callback and clear it. I did it just for speed of writing. If I were using this in production, I would never use jQuery in a scroll function.

    I don’t really see it as a problem when the function runs every frame though. If the page hasn’t scrolled It should take less than 100 microseconds for the function to complete.

    With a constantly running function:
    http://codepen.io/jacobcpeters/pen/ICfor

    With a resetting callback:
    http://codepen.io/jacobcpeters/pen/ctIgl

    In hindsight, I wish I would have made them with closures instead of prototypes. The reason I chose prototypes was for the slight speed advantage. Mostly, because you were worried about the speed impact of a the function constantly running. Prototypes are a pain with callbacks though.

    Chrome looks terrible with this though. It’s because of lack of smooth scrolling. Another ugly thing I don’t like about chrome. I still prefer it to anything other than firefox though. However, I guarantee that chrome disables smooth scrolling by default because too many developers tied large function callbacks to the scroll event, and it made the browser react slowly to user input.

    Edit Even with a haswell i5 overclocked to 4ghz, I’m still getting some hiccups in scrolling with the resetting callback that I don’t get with the constant function.

Viewing 9 posts - 1 through 9 (of 9 total)
  • The forum ‘JavaScript’ is closed to new topics and replies.