Jump to content


animations lag when chrome has multiple tabs open

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

There is a problem with tweens in these conditions(edited):

  • Browser has multiple opened tabs and has worked for about 10-15 min
  • Browser was idle and then used again
  • When I open up more then 3 tabs


var tweens = { main_area: { layer_buttons:{ getTween: function (_this, _properties) { return TweenMax.to(_this,0.5, { css: _properties, paused: true, delay: 0.2 }); } } }}var g = tweens.main_area.layer_buttons.getTween;var start = g($(".info", "#information-start"),{opacity: 1});$("#layers").on("mouseenter", "#information-start", function () { start.play(); }).on("mouseleave", "#information-start", function () { start.reverse(); });
Problem:When I do a quick mouseenter from outside of browser or from another
or mouseleave, animation doesn't render correctly and I just see end result (without seeing actual animation)Note:
  • I've noticed this behavior only in Chrome so far. I don't know what will be users situation with browser, that's why I want to know is there some kind of workaround for this problem.
  • After completely closing all tabs and restarting chrome browser, all tweens work how they supposed to work.
  • It's not just in this situation, it's with every tween I have on my site.
Edited by masq
Link to comment
Share on other sites

Hi and welcome to the forums,


Jack addressed a similar behavior previously, it has to do more with erratic behavior but also in chrome. Check this post.


Also it would be great if you could set up a live example (fiddle or codepen) in order to take a look at it.


Hope this helps a little,



Link to comment
Share on other sites

Hi Rodrigo!


Thank you for greeting :)


So I tried, useRAF(false) and it didn't help.


I'm not able to replicate this problem in jsfiddle, but I will deploy newest version tonight and post address and give you instructions how to replicate issue.


I think it is problem with chrome distributing some kind of resources, and opening up more and more tabs ( as users are got use to it ) those tweens in timlines are working slower and slower until I can see only results on onComplete and on onReverseComplete without actually seeing animation in between.




Edited by masq
Link to comment
Share on other sites

Hi Masq,


You're welcome.


You could test the fps meter included in chrome's developer tools. Open developer tools and in the bottom right corner you'll find a gear for the settings, click on it and in general settings - rendering select "show FPS meter". With that you'll see if the lag is related with that or some other thing creating problems.


Also you could select "show painting rectangles" to see what else maybe painting besides the elements controlled by GSAP, sometimes an event bubbling in the code can cause some problems in the long term.


Anyway I'll be waiting for the url to check.




Link to comment
Share on other sites

Hi again.

FPS Counter doesn't change, it's same in both situations.
Not that I understand much of painting rectangles, but nothing else than what should isn't painting in background.

After discovering the correct way to replicate problem I'm starting to think it's something maybe linked to garbage collection or RAM allocation.

Correct way to replicate problem:

  • Open up 4+ browser tabs
  • Content should be heavy like facebook, twitter
  • Then open up this link
    • To start web page animations click on keyhole
    • When clicking on buttons your url will change, before you refresh page just make sure you don't have clean url like "/" you must have "/dev/" atleast - "/dev/" will bring you at start.
    • Don't click on facebook and twitter buttons, those will throw error.
  • You can monitor problems at first keyhole animation and all other animations that are present because all animations are executed by Tweens
  • Browser support: IE9+ all other browser seem to have full support

To solve problem:

  • I just need to close all other tabs, and after page refresh it immediately works fine

Sorry for messy site, but it's still in heavy development, and until I don't find a way to have it animate smooth I can't even think about shipping, and to be honest this plugin improved sites performance by 80% and this problem with Chrome is the last one animation wise.


P.S. Your plug-in is a miracle because I was struggling to have cross browser and ie9 support, not only your plugin can do that, but with extra effort it's possible to even support ie7,8. This javascript framework is a real gamechanger. Thank you again for introducing us developers with this tool. :)

Link to comment
Share on other sites

I too have noticed this "irregularity" and can confirm it, even with latest chrome still the same issue, whilst on firefox everything animates beautifully.

Link to comment
Share on other sites



I've looked at your site and looks very slick, nice work!!. The only js I found were just some set tweens, so there's not much it can be done with that. I noticed that you're working with version 1.9.0, try updating it to 1.9.3. Also you're loading TweenMax and the css plugin, there's no need for that since TweenMax includes the css plugin.


Regarding the chrome issue, it has been reported previously in the forum the fact that chrome puts render quality over render performance which could be a factor here. My recommendation would be to isolate as much as you can in order to make specific trials of your code and then start putting it all together piece by piece until you find what piece of the code could be causing this problem.


It also would be great to take a look at the tweens code (if is not a problem for you) in order to figure what the problem could be.




  • Like 1
Link to comment
Share on other sites


Sadly I haven't got time to (for the 4th time) put everything back together piece by piece :D That's sort of thing I cannot afford because my deadline is 5 days from now, and I still have lot of work not related to this problem.

Thanks, the idea of the site was developed 50/50 with my client, very creative woman, I told her that in order to have a good site I give her opportunity to request anything she want's and I will get that working whatever the cost.

Well, I'm new to Tweens so I didn't know that TweenMax had CSSPlugin already included. I use MVC 4 script bundle, so the js and css loads only the first time they enter the site, after that it's stored on their computer with unique hash to know it's the same version the server has. What I want to say, size of load isn't issue for me, because the site doesn't support any mobile device, so I really have no reason to optimize site load :)

For you to understand my tweens I would need to give you whole file, because everything is connected.

I will get the latest version in 2-3h, and put it up, maybe you will see something I couldn't :)

But tbh, I followed all the rules of increasing performance like:

  • Use over
  • Put predefined width,height values on
  • Try to avoid resizing (as much as I can), so I wouldn't use transform because Mozilla has problems with performance rendering transforms. At start the first keyhole animation was animating to scale[40,40] now its animating width,height.
  • Have low amount of DOM elements present (thats why I use lot of ajax, because at starting point I hade over 3k elements present and it was disaster :D ). Now I narrowed down to 220-280 elements per page, still too much thou.
  • Use GreenSock JS Tweens :D

My audience:

  • My audience is people with not very good computers, and lot of them are without hdw accelerated graphics option, so I need to develop everything for a normal computer.
  • And my target audience browsers are:
  • Chrome
  • Mozilla
  • Opera
  • Internet explorer 8+ (I will support only 9+)
  • Safari (We don't have that many mcbook users) - (funny thing is that these are the most important users I need to target)




  • Thanks, I'm happy that someone from side likes my work.
  • I will put JS file for you to check Tween's I'm using, maybe there is optimization possible 
  • Sadly I don't have time to go in such a detail to analyze each piece of my site and put it one by one together (as I did 4 times before, thou not using TweenMax plug-in)




Link to comment
Share on other sites

I couldn't upload attachment so I posted on pastebin my code.


The lagging was before and after useRAF(false).




Link to comment
Share on other sites

Hi Masq,


By looking at your code and watching the site a little closer I can tell you that this is a pure chrome bug issue, why is this happening? I have no idea at all.


If you google for chrome and animation issues you're going to find that chrome has problems with CSS3 transitions, jquery animate(), other js libraries, canvas and svg animations, besides the fact that the site runs quite smooth on safari indicates the fact that is just a chrome issue and not webkit in general.


In other aspect the cpu and memory consumption are quite normal, there are no jumps in either when you do a mouse over & out in the menu elements, and when you click the animations runs a little bit jittery but it doesn't chew up the resources in a relative new laptop. Therefore I presume that there's nothing wrong with the engine itself, considering that with 7 tabs opened in firefox the animation runs very well and also there's no abnormal resource consumption. That also indicates that there's nothing structurally wrong with your code, as far as I can see.


Also you haven't updated the engine version maybe that could help..


To sum it up unfortunately I can't help you further than I've already done without some serious debugging of your code which implies testing each part of it and find what's causing chrome to behave like this. One alternative to that grueling process could be to comment out some parts of the code in order to see if there's any improvement, for example leave the functions empty, so when they're called you won't get an error, that would help to isolate without any major disassemble of the site.


Anyway keep posting if you can in order to see if there's anything else we can do, or if other user can chip in.


Well I hope this helps a little,



  • Like 3
Link to comment
Share on other sites



I posted issue to chromium website, so I hope to get some answers.


Upgraded to latest TweenMax 1.9.3 and no change at all in performance.


I will do some talking with my client about this problem, how to handle this.... to be honest, this problem is so ridiculous, I just can't believe it exists...


I'll be posting up if there is some kind of workaround or solution, until then


Stay classy GreenSock!




  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

Hello there again.


So I have good and bad news.


Good news is I managed to fix the major problem with animations. It seems that chrome isn't able to run JS properly. What I did I wrote more direct code rather than writing nested code, and did everything step by step watching if there isn't anything that puts a weight on animations.


So that's good, now everything works slick.... BUT


Now there is problem which, what I think, comes from the first problem.


When I change tabs in middle of animations, I create a problem with TweenMax animations, it seems that on fast mouseenter/mouseover and/or after waiting for 2-3 secs on icon and then moving mouse outside the animation goes straight to end point or starting point, without animating anything, but when mouse is moved slowly in/out not staying in one place too long everything works like charm.


I switched of RAF, and that didn't help.


Maybe it's somehow related to how I write my Tweens, because when I tried to replicate problem in jsfiddle  everything works fine.


So here some samples how I attach Tweens:


Light contur:


Here I define it:

light: function () {
                return TweenMax.to(map.light_contur, 1, {
                    opacity: 1,
                    paused: true

Here I attach it:

keyhole: function () {
            // Set light tween
            var lightTw = tl.start.light();

            map.light_contur.on("click tap", function () {
                // Remove event listeners

                // Start intro
            }).on("mouseenter mouseover", function () {
            }).on("mouseleave mouseout", function () {

Menu buttons:


Here I define them:

itemHover: function (_thisTitle, _thisIcon) {
                var _self = new TimelineMax({
                    paused: true,
                    onStart: function () {
                        globals.menu_item_hover_complete = false;
                        console.log("animation started");
                    onReverseComplete: function () {
                        globals.menu_item_hover_complete = true;
                        $(document.elementFromPoint(window.mouseXPos, window.mouseYPos)).trigger("mouseenter.action").trigger("mouseover.action");

                    TweenMax.to(_thisTitle, 0.5, {
                        opacity: 1,
                        scale: [1, 1]
                    TweenMax.to(_thisIcon, 0.5, {
                        opacity: 0,
                        scaleX: 2,
                        scaleY: 0

                return _self;

Here I attach them:

menu: function () {

            // Find all menu items
            map.menu.find(".menu-item").each(function () {

                // Set animation
                var item_hover = new tl.menu.itemHover($(this).find(".title"), $(this).find(".icon"));

                $(this).find("a.handler").on("mouseenter.action mouseover.action", function () {
                    if (globals.menu_item_hover_complete)
                        // Animate current element


                }).on("mouseleave.action mouseout.action", function () {
                    // Reverse animation

                // Set click event
                $(this).find("a.handler").on("click.action tap.action", function () {

                    if (!$(this).hasClass("facebook") && !$(this).hasClass("twitter")) {
                        //Get routeName
                        var routeName = $(this).attr("data-menu-item");

                        // Remove all handlers
                        map.menu.find("a.handler").each(function () {

                        // Reverse hover
                        item_hover.reverse().eventCallback("onReverseComplete", function () {

                            // Show middle text
                            TweenMax.set(map.middleT, { display: "block" });

                            // Go to route
                    else {



And here are another button set I use in regions:


Here I define and attach them:

 // Global settings
            var global_settings = new TimelineMax({
                paused: true,
                onComplete: function () {

                    // Set show content
                    var showContent = new TimelineMax({
                        paused: true,
                        onComplete: function () {

                            // Reset middle text 

                    // Middle text fadeOut
                    showContent.add(TweenMax.to(routes[_route].middle_text, 1, {
                        opacity: 0

                    // Content fadeIn
                    showContent.add(TweenMax.to(map.layer, 1.5, {
                        opacity: 1

                    // Launch


            // Settings foreach button
            $.each(routes[_route].button_opt, function (index, item) {

                // Settings for route button
                global_settings.set($(item.id), {
                    css: item.settings

                // Declare info,text tweens
                var routeBtn_hover = new TimelineMax({
                    paused: true,
                    onStart: function () {
                        globals.route_btn_hover_complete = false;
                        console.log("Route btn animation started");
                    onReverseComplete: function () {
                        globals.route_btn_hover_complete = true;

                        $(document.elementFromPoint(window.mouseXPos, window.mouseYPos)).trigger("mouseenter.route").trigger("mouseover.route");

                // Add animations
                    TweenMax.to($(item.id).find(".text"), 0.5, {
                        css: item.text
                    TweenMax.to($(item.id).find(".info"), 0.5, {
                        css: item.info

                // Set mouseeneter/mouseleave handlers
                $(item.id).on("mouseenter.route mouseover.route", function () {
                    if (globals.route_btn_hover_complete)
                    console.log("Route btn hover started");
                }).on("mouseleave.route mouseout.route", function () {
                }).on("click.route tap.route", function () {

                    // Disable animations
                    map.layer.find(".route-btn").each(function () {


            // Set info's settings
            global_settings.set($(".info"), {
                opacity: 0

            // Launch settings


If someone could give me a tour how TweenMax.to() function reacts with the browser, and why does $(element).on("mouseenter mousover") jerks with that function it would be great!


If anyone has any questions please ask, and if you need live version, ask for that two, I will try to put that on, because right now, I rewrited everything and I dont have underconstruction page and then I need to create it!




Link to comment
Share on other sites

I think I might just create a video, with experiments showing how tweens act... I know that it's the way I use them and create them.

Because I don't know how actually TwennMax.to() and TimelineMax() work, I don't know where to find the problem?

Why would there be a situation where Tween doesn't animate and just show end result?

Is it .play() function and .reverse(), or is it the way I pass my element?

By default I pass elements like this: $("#element") or $(".elements-class")

When I did this in jsfiddle everything works fine..

Could it be that those buttons are in nested containers?

My site structure is like this:

  • View port
    • View area
    • simulated_background
    • main_area
    • layer
    • layer-item (buttons are here)
  • menu (buttons are here)
  • middle_text
  • key-hole
  • key hole light (this tween sometimes lag too)

And always the place where buttons are active is on the top and all unnecessary are display: none.

If site is opened normally and everything is done correctly, without leaving page, it might just bee all ok, no problems, always one of these things 100% trigger problems:

  • From developer tools taking select element, it messes with DOM and then tweens start to jerk
  • Switching tabs when something is animating (allmost anytime)
  • (this is 50%) Losing focus from browser and going with mouse in very fast.



And yes it's still related to multitabing, without multiple tabs everything works just fine. And none of the above things trigger the problems.

Link to comment
Share on other sites



Well it is a recommended practice to pass elements just once and through variables and when you define those variables limit the amount of elements to go through, something like this:

var element1 = $("div#element1");

Like that everytime you call for element1 it is already stored in a variable, and populating that variable is easier because you're giving detailed information of where to look for.


Also there's a lot of images being animated in the site, mainly transparent PNGs, and maybe considering the fact that chrome puts quality over quantity in terms of rendering, could be causing some trouble. Also, and please don't take this as a personal thing because is just an observation, your code seems a little over complicated, is very well structured but one thing I would try i would be to simplify it as much as I can, maybe less arrays and more straightforward variables and functions.


Finally, unfortunately you're dealing with a very singular issue here (it just happens on chrome and under very specific circumstances), it's like you sat right on the needle of the haystack and chromium hasnt come up with an answer and I'd love to give you a straight one that could solve this, because you're site is quite amazing. Like I told you I checked on chromium a couple of days ago and looked at the site again and one thing i can tell you is that is quite amazing.


As soon as you have the new live site let us know in order to take a look, because the fiddle is just one element and doesn't involve the complexity of the real site.




Link to comment
Share on other sites

Hi there,


Before I continue, you can look at this post about problems with Tween transition I posted





I really appriciate any kind of criticism on my programming skills and code writing.

And you might be 100% right that complexity of code is just what the problem might be, I will try to rewrite overnight the site again, even more simpler.


The main problem is, the simpler the code the larger file, pluss I need leave room for future content. Another problem is going from one place to another is so damn complicated, that I just need to make it modular as the rest of the site :D


You just gave me a good idea, I will replace all nontransperent PNG's with JPEG files, less rendering, smaller filesize.


As soon as I rewrite working example, I will put on the live server, with the same address, but until then take look at the problem in video -> http://youtu.be/iZ_ee0lh-7Q


Regards and thanks for the very appreciated posts you been giving me,


Link to comment
Share on other sites

It's not immediately apparent what might be causing the problem, but would you mind adding this to your code and see if it helps anything?: 

window.onfocus = window.onblur = function() {

I kinda doubt it'll solve anything - just curious. 


Also, I noticed in your code at one spot you have this in a tween:


but that's not valid. You can't pass an array as the value. I think you meant:


I'm curious if this line in your code is causing a problem too: 

$(document.elementFromPoint(window.mouseXPos, window.mouseYPos)).trigger("mouseenter.route").trigger("mouseover.route");

Which is inside an onReverseComplete. Can you remove that and see if it helps? I'm not saying it's wrong - just looking to isolate things that could be causing issues. 


To give you a better idea of how things work under the hood, there's one central ticker that drives ALL of the updates which is why everything is perfectly synchronized in GSAP. Normally, that ticker is driven by requestAnimationFrame events, but of course those become much less frequent when the browser tab switches away (blurs). If you switch away mid-tween, then most likely as soon as you return to that tab, it will suddenly cause the engine to "wake up" (because requestAnimationFrame started up again) and that pulse will update all the tweens/timeilnes. Therefore, you'll likely see things jump to the correct time/position. That's all normal behavior. However, it isn't normal for things to simply not animate thereafter, like when you rollover/out on things, your tweens should work perfectly. The jump only happens when the tab first "wakes up". 


The only other thing I can think of is overwriting. If you are creating a tween that conflicts with another one (they're both tweening the same property of the same object), the default behavior is for the second one to overwrite the first (to avoid conflicts). So if your tween gets killed, it obviously won't work thereafter (just the particular properties that were conflicting, and only in that one tween instance). 


I'm hoping something here helps you :)

Link to comment
Share on other sites

Hi there again,

Answers to your questions and suggestions:

  • window.onfocus didn't solve anything sadly,
  • Thanks for the tip about scale, but that didn't change a thing neither,
  • I added that code only for this problem with purpose to minimize horrible effects I had, basically it manages normal hover when going from element to element, wish this was the problem and I wish I could work around somehow when I'm leaving the element,
  • Correct me here if I'm wrong while describing the actual process for tweening when hovering
  • Broswer is tracking my mouse movement,
  • Event listener fires function when hovered,
  • Then tween is rendered tick by tick
  • And what happens at the end I have no clue, because it's interesting that it shows the last tick if it didn't all the middle ones

So from here, my guess:

  • On multiple tabs, there is some kind of problem AND only in specific situations I have no clue on which ones precisely, with rendering actual ticks when mouse movement was idle for more then 1,5 second, it seems as if browser is sleeping when mouse stops... I added dispatchEvent to the mousemove and it didn't help either.

My questions:

  • Could it be somehow related to how I create new Tween instances, as I always create them dynamically?
  • How .play() and .reverse() of the same Timeline() instance could mess up elements starting properties, one of the elements flickered and stuck at left: 70px?
  • Would it help if I created new team foundation project and gave anyone of you access to see the real thing?

Said that, I will try to replicate problem in jsfiddle and/or codepen, I am 90% sure I won't succeed but I have no other choice, because these buttons only show me that actual image sliders won't work properly too.

I noticed VERY interesting thing, when I'm doing this sequence:

  • wait 1 second
  • move on element
  • wait 1 sec
  • move from element
  • move mouse around for more then 1 second
  • move to element

the same thing happened, SO I think, it might be something with my Tween instances, browser and tweens loose communication if no Tween is animated for over a second.

And my another guess is, there is something that messes up the whole TweenMax plguin, and don't know what, but basically it seems that browser or something in my code does something to Tweens.


I've overboiled water the 3rd now :D

So, I launched these lines 2 seconds separated:

and the same thing happened, so now I'm 100% sure it's nothing to do with eventListeners and mouse tracking, it's 100% with the way I manage my Tween instances, create them, use them, while chrome has multiple tabs open, might it be that chrome has issues not rendering but execute javascript, like if nothing happens - let's save memory? And when something happens - Ops need to wake up, aaaand it's too late...

Will do some profiling and rewriting, I will simplify the code as much as I can.

Another interesting thing, that previously, what I think, the same problem occurred site wide, but now when I rewrote I removed some code that messed up and left some peaces that are still messing up small things.


Sorry for my what it might seem illogical sentences, I'm just very stressed because need to ship this asap, but can't until this isn't sorted out.

Link to comment
Share on other sites


I have success making everyone to view the real thing here:

See the Pen xbCJd by skmasq (@skmasq) on CodePen


Routes are not working yet.

But the interesting thing is, I can't seem to replicate this problem, as if somekind of magical thing is happening here.


Maybe create site in codepen and ship it ? :D

I will put up on live server in an hour, and will start to check the differences.


I found a temporary fix, that will always keep my tweens without lag but with very,very low FPS.

I created transparent element which is animating all the time:

TweenMax.to($("#tween-fix"), 1, { css: { height: 55 }, repeat: -1, yoyo: true });

Here we go a video in codepen:




Link to comment
Share on other sites

This is tricky because you've got over 1,000 lines of code in your example and it would take quite a while to wrap our heads around what every line does, how they all interact, what potential conflicts there are, what your intent was, how the other tools factor in (like jQuery), etc. In these forums, we really need to stay focused on questions directly related to GreenSock-tools in isolated examples whereas what you're asking for here is more of a full-fledged consulting project for troubleshooting a specific application. We do offer consulting services for a fee, so let us know if that's what you need (we can address that over a PM or e-mail). 


That being said, I did look around at your example and noticed some intermittent HUGE repaint costs in Chrome. The core problem here (from what I discerned) wasn't that the engine itself was slowing down or misfiring - it was that there were intermittent huge gaps in the ticker updates. Normally, the browser hits the ticker 60 times per second, resulting in smooth updates. However, in your example, sometimes the browser was so overwhelmed with some other task (like a repaint and/or image decode) that a gap was introduced, thus the ticker didn't get a requestAnimationFrame or setTimeout callback for literally 0.5 or 1 second (or more, depending on the CPU power). So when GSAP was told to update, it correctly rendered things at that (new) time and things looked like they "jumped". 


Remember, GSAP is time-based, not frame-based. That's a GOOD thing. It honors the duration of tweens in terms of time, so that if there are gaps in the ticker updates due to CPU load, it won't just slow everything down and make them look like they're going in slow-motion like a frames-based system would. 


I've attached a screen capture showing a huge repaint time when I rolled over one of the dots/icons. It looks like Chrome is spending a massive amount of time decoding a png. See the large green bar? That's repaint. The orange bars are JavaScript execution (that's what GSAP does). Notice performance for JS is rock solid and very fast. 


I'd recommend looking into why your repaint costs are so high and optimize that. Tip: Don't make the browser resize your images if at all possible because Chrome prioritizes image quality over performance, thus repaint times can be very large in Chrome for image resizes. 


Link to comment
Share on other sites



A big thank you for helping me understand the root of my problem. This is the first time I come head to head with such a problem, if I knew never would opened up a post :) (Being ignorant just thought there is something with the way plug-in works)


Sorry everyone for your troubles and again big thank you everyone who helped, I will post full site in several days for you to enjoy!


Best regards,


Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.