Skip to content
This repository was archived by the owner on Oct 8, 2021. It is now read-only.

Jumpy and blinky page transitions #455

Closed
woutervanwijk opened this issue Nov 13, 2010 · 114 comments
Closed

Jumpy and blinky page transitions #455

woutervanwijk opened this issue Nov 13, 2010 · 114 comments
Assignees

Comments

@woutervanwijk
Copy link

As of A3, page transitions are still not smooth on many platforms so this issue is being used to track our progress on improving the situation. This is a multi-faceted issue because we need a smooth transition system that works across all our target platforms and maintains all the normal "web" behavior such as returning a user back to their original scroll position when re-visiting page.

This issue originally started out regarding the address bar on iOS and flashes on Android but has expanded to discuss our progress on the larger re-write that Jesse, Kin and Scott have been working on so I've added this intro and revised the title accordingly. All transition-related issues will be closed and push back into this issue so we can track them together. A solution to the symptoms seen will require a deep re-factor and re-approach so it makes sense to look at this issue holistically and any fix for one platform needs to be evaluated against it's impact on another.

In iOS, there is a noticeable blink of the un-rendered page (checkboards) while the page scrolls down to a previous anchor position, among other situations. On newer builds of Android, there is flash of the previous page when executing a transition.

Also, when using long pages Safari on an iPhone 3GS, the address bar jumps up and down after page transitions. Not always, but it sometimes does (especially when selecting the items at the bottom of the listview).

Safari probably figures that because of the hash-change, the address bar needs to be visible. It will hide it again. Because of that, the user experience is not great. In jQtouch, the hash doesn't change, and Safari doesn't show this behaviour.

Maybe it would be considered an Apple-bug, but for me it's quite an issue, and for others too:

http://forum.jquery.com/topic/iphone-safari-address-bar-jumps-down-after-page-transition

I really like jq mobile, so it would be great if it could be fixed in some way.

@fabriziogiordano
Copy link

might be considerd to implement the trick used in
http://www.20thingsilearned.com/js/twentythings.history.js

They used:
history.pushState
[ https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history ]

I do not know if webkit for iphone safari support that.

BTW at least is it possible to edit the hash tag from # to #! to be google search compliant?

Thanks
Fabrizio

@speedmax
Copy link

+1

This is very annoying

@schorsch
Copy link

+1

really annoying

@Vincentgr
Copy link

+1 Again. Ridiculously annoying when transitioning between pages.

@bradya
Copy link

bradya commented Nov 29, 2010

+1 from me also

@brandonaaskov
Copy link

+1

@brandonaaskov
Copy link

Not sure if this falls in line with this issue, or issue 568 (https://github.com/jquery/jquery-mobile/issues#issue/568), but from what I can tell, it's a matter of going from a page that isn't longer than the viewport's height to a page that is. In the first page, you'll see the address bar, and after changing the page, you'll see the page jump to hide the address bar.

To workaround this for now, you can dynamically set the min-height of .ui-page to whatever the device size is, but I'm still trying to find out how to determine what that device size is (I tested it just by hard-coding a value for the iPhone Simulator). Ideally (at least for my case), when the page is rendered, if the page is less than the device's height, this would happen automatically.

Scott/Todd, if the community agrees on this approach of setting the min-height to the height of the device (or the height of the viewport plus any status/nav bars), we can tackle that here at Brightcove.

@scottjehl
Copy link

Believe me, big +1 from the team on this one too :)

I did some testing and found it's not related to updating the hash, setting focus to the first focusable element, or calling silentScroll... so hopefully Brandon is on to something!

Brandon, can you send a pull request with that workaround? I'll be very happy to take a look!

@brandonaaskov
Copy link

Hi Scott,

Is there some way to get the device's height? I've looked around and haven't turned up anything yet.

@scottjehl
Copy link

hmm.. screen.availHeight ?

@brandonaaskov
Copy link

So, there seem to be two good ways to go about doing this.

If you're loading in jQuery Mobile stuff the way I am since I'm in dev (by pointing the js directory), then you can just call this at any point in your code:
$('.ui-page').css('minHeight', screen.availHeight);
Here I'm just applying a min-height to all of the .ui-page elements and setting it to the device's screen height.

However, the better way (I say better since it's documented already to work this way) is to modify the jQuery Mobile defaults, like so:
$(document).bind("mobileinit", function(){
$.extend($.mobile, {
metaViewportContent: "width=device-width, height=device-height, minimum-scale=1, maximum-scale=1"
});
});

Here I'm just adding the height value, which is not there by default.

This is working for me in keeping my page transitions from "jumping", but I'm curious to see if this works for others as well.

Since that has to happen after jQuery gets loaded, but before jQuery Mobile gets loaded, I had to change my setup a bit to get it to work. Based on that setup, users would be required to have jQuery separate from jQuery Mobile, which is not currently how the ant build process is setup, but perhaps that is the plan for the first release (similar to jQuery UI).

Alternatively, if we find that a lot of people are looking to use this option, maybe we can just make it one of the defaults? Time will tell, I suppose.

@woutervanwijk
Copy link
Author

I tried the second option and it works well. Thanks! Are there any drwabacks in making it one of the defaults? If not, I suppose it should be a default, otherwise it would confuse new developers imho.

@scottjehl
Copy link

Nice work!
If this fixes the issue and doesn't interfere with taller pages ( as in, it acts as a min height), then let's roll it into the defaults.

@scottjehl
Copy link

We'll do some testing on all the devices here but my initial testing shows this fixes the address bar issue. Look for the commit soon! Thanks again.

@patussay
Copy link

patussay commented Dec 8, 2010

The metaViewportContent solution is perfect but another problem arises when you decide to change the orientation of your device on the fly (at least for me), it doesn't dynamically change the size of the viewport, which apparently remains stuck on the old orientation value. You need to refresh the page to get the right view and so on.

Otherwise it's a big step forward since this visual problem does not seem so easy to resolve. By the way many thanks to the team for the great work they have already done.

tested with the latest rev.jqm + ipod 4g ios421

@scottjehl
Copy link

ahh rats!
Yeah, that's a pretty big problem actually. There are so many finicky issues with orientation change in iOS. I reported the issue to Apple where the layout zooms in on change when user-scaling is enabled, but so far they haven't released a fix for that one either.
We may need to look into setting a min-height on certain elements through CSS. Maybe the body element will work...?

@patussay
Copy link

patussay commented Dec 8, 2010

CSS would be good but i think it's really a job for Mr javascript.

A quick 'console.log' test reveal that the event.orientation in jqm (circa line 389 w/o jq144) is never updated (iOS_421) and keeps the value "portrait" (if you start browsing in portrait) even if you flip your device to landscape.

On the other hand if you start browsing in landscape mode, the value is correct the 1st time but lost afterwards and cannot be recovered (until you reload your page), the fact is that the className is never correct unless you keep your device in one orientation from the start.

update: if you keep the original metaViewportContent from JQM (w/o "height=device-height" as mentionned above), the event.orientation is correct in mobile safari. Strange isn't it !

@patussay
Copy link

As a starting point, here is a solution for the address bar, it's not perfect and beware not to mix this solution with the jumping page issue that still must be adressed (and going to be a hard case).
Test it first without scrolling, it acts as the silentScroll should work, if you change orientation of your device everything is fine.

Of course, pages are intended to be scrolled and many unpleasant display issue appear if you act upon a link and you are somewhere in your page (perhaps some kind of default browser behaviour mixed with the lastScroll data sent to silentScroll() + loading of the page + ...? = it's a lot to take care in a short time). The problem also appears when the page is in cache but the effect is less visible.

But 'back to our sheeps'.

Here's what i did, i worked from the solution 1 of brandon (as it seems impossible to mix device-width and device-height with iOS, as said above, the orientation is not updated) :

if(event.orientation) {
* in line 390 of jqm (standalone version without jq.144)
    [change] 
        $html.removeClass( "portrait landscape" ).addClass( event.orientation );
    [for]
        $html.removeClass( "portrait landscape" ).addClass( event.orientation ).css({'min-height': screen.availHeight});

* i also added beneath it a setTimeout, sometime the address bar show up especially when you change your orientation
        setTimeout(function() { window.scrollTo(0, 1); }, 20);//could be connected with silentScroll ?
}//end event.orientation

* need to add few lines at the beginning of your css file, otherwise the page is truncated during animation
        html {
            position:relative;
        }

UPDATE
Forget about the above block of code as the css rule creates problem on Safari:desktop (doesn't like position:relative in this situation),
but for testing purpose, put this in your jqm.js file

if(event.orientation) {
    //use class for every browser
    $html.removeClass( "portrait landscape" ).addClass( event.orientation );

    //only mobile
    if($.support.touch) {
        $html.css({minHeight: screen.availHeight, position: 'relative'});
        setTimeout(function() { window.scrollTo(0, 1); }, 20);
    }
}

Tested only on iOS4.

@brandonaaskov
Copy link

In jquery.mobile.event.js in the special_event.orientation function elem.clientWidth and elem.clientHeight only report correctly the first time the screen renders. Once it rotates, they report the device's height and width.

Then, I tried taking out width=device-width, height=device-height from the metaViewportContent default (jquery.mobile.core.js) altogether and everything seems to be working wonderfully, including rotation. patussay, can you give that a shot and see if it works for you?

@patussay
Copy link

The bare minimum for iOS (and maybe other mob-systems) seems to be the following rule

metaViewportContent: "initial-scale=1, maximum-scale=1",

and it acts just like the default one in JQM

metaViewportContent: "width=device-width, minimum-scale=1, maximum-scale=1",

But what about the url bar ? my attempt was to hide it from the view and the following metaviewport rule fails to do so, (I must admit that it's a pity that your 2nd solution fails because of the orientation, it would have been perfect and would have spared a lot of time and energy for such a thing that's normally done with a setTimeout).

This does not work because the address bar is always visible, or did i miss something with your explanation ?

@mesca
Copy link

mesca commented Dec 13, 2010

To get the real visible height/weight, I use something like:

window.onorientationchange = function() {
    h = window.innerHeight ? window.innerHeight : $(window).height();
    w = window.innerWidth ? window.innerWidth : $(window).width();
    // Call your resize function
    // update_orientation();
}
$(window).trigger('onorientationchange');

It will report the correct width and height for the visible part of the viewport. Works well in any orientation and also in full screen mode. Then, in update_orientation(), you can detect the height of the page and adjust it if less than the reported height.

@urlsangel
Copy link

This is a big issue for the team here too.

Will there be a fix for this in the next release? If not, any idea when this will be looked at?

@speedmax
Copy link

Same here, Any update on this issue?

It will have huge impact on user experience

@fabriziogiordano
Copy link

do you think we can get some clues or inspirations from the way this webapp is managing the URL. They change the hash without triggering the navbar appear.

http://m.untappd.com

[ i'm not affiliated or related to untappd ]

@avibha
Copy link

avibha commented Jan 17, 2011

+1

@jstreb
Copy link

jstreb commented Jan 23, 2011

I just took a look at http://m.untapped.com and for me the address bar always appears when the hash changes. Are you seeing something different? For example if I am on the pub tab, scroll down the page and then click on one of the pubs the page jumps back and shows the address bar. Is this different behavior then what you are seeing?

@scottjehl
Copy link

So Todd and I were just chatting about this and here's what we're thinking:

The address bar showing and hiding doesn't often cause much of a problem in regards to transition smoothness. For example, if you go to the homepage of jQuery Mobile docs, and click the first link, the transition is quite good on iOS. Yeah, the address bar shows, but it's smooth overall and the transition works as you'd expect.

The real problem occurs when you scroll down the page and then click a link. Ideally, the transition would occur from the existing scrollTop to the correct scrollTop of the page you're transitioning to (which is saved in data when a page has already been visited). Unfortunately, this is the part that doesn't work quite right, but I think it's the fault of our own sequence of events (and not a browser issue).

Maybe we should first direct our efforts there, since it's clearly a problem that we can solve. You can test this in Chrome as well; just scroll far down a page and click any link. The transition will blink rather than working properly.

@jstreb
Copy link

jstreb commented Jan 25, 2011

Yes, I think there are a handful of issues here.

  1. if a page's height does not take up more then a 100% of the window then after the transition the page shifts down because the silent scroll will not hide the address bar on the shorter page. ( I just pushed a pull request to address this. )
  2. If a user scrolls down the page, clicks on a link to navigate to a new page, then the transition does not look right. This seems to be a new issue, specific to HEAD. The alpha 2 branch seems to do this correctly.
  3. As Scott and Todd mentioned returning to page that you had previously scrolled down on jumps to the bottom of the page after the transition. Ideally there would be no jump but rather you would just slide over to the previous scrollTop.
  4. You will always see the address bar appear because an a href was clicked. As Scott and Todd mentioned this seems like the right thing.

Anyway, I will start looking into the suggestion that Todd and Scott have made about transitioning to the existing scrollTop.

@scottjehl
Copy link

Awesome - sounds like we're on track now. Thanks Jesse

@jstreb
Copy link

jstreb commented Jan 27, 2011

Hi all,

I pushed up a fix to make the pages not jump around during the transitions. We looked into scrolling from where we were in the page to the new page, but there are too many performance problems for this to work well. What we see now is similar to alpha2 where we scroll up to the top of the page and then scroll over.

New to this update is that the page does not go down and then back up during the transitions, which is what the original bug was. If the user hits back we will take them back to the page and then scroll them to where they were in the page. (known issues is that on iOS the scroll down to where they previously were can result in seeing some flicker.)

Please let us know if this improves the jumpiness of the transitions.

  • Jesse

@rmahnovetsky
Copy link

HUGE +1 for me. Im using motorola Xoom

This only occurs when I use hardware acceleration mode. Otherwise it is fine. But without hardware acceleration scrolling is too slow.

@rmahnovetsky
Copy link

No more flashing for me, except for the footer nav bar which still flashes but I guess that it another issue. In my case the problem was overflow. I had li elements and text areas that grew beyond 100% width of the screen and this cased the flashing or maybe redrawing. It also made the app run really slow.

The other issue I had was the async calls to the web db. This also cased flashing because the screen would render then some small time after the data will return and I add the data to the screen casing a little flash. To fix this I created a transition handler to render once the async call came back.

@MonsieurDart
Copy link

It seems like I have the same issue. To simplify the explanation, I have done a simple test case: https://gist.github.com/1165071

The test case links 0 and 2 are working fine (transition with no blink), but the test case link 1 blinks. The difference between 1 and 2 is that the page change is done by the HREF for test case 1 and programmatically in test case 2. Do you think this could be a lead? Or have I overlooked something?

@jblas
Copy link
Contributor

jblas commented Aug 23, 2011

@MrDart

What device/platform are you running your test on? I see no differences on some of the Android devices I'm testing on.

@rmahnovetsky

How are you turning off Hardware acceleration? I thought config switches were for apps you packaged yourself, or are you using Phone Gap? The browser on the Xoom is already hardware accelerated, but I wasn't aware of any switches that allow you to turn it off for the built-in browser.

  • Kin

@rmahnovetsky
Copy link

I was testing it in the brower and in phone gap. Phone gap and the browser
worked the same.

I dived deeper into the issue and it seems to be a browser issue. To test,
just create a div where its content overflows, and set overflow:scroll. If
you have overflow: hidden there is no flashing.

Sent from my android
On 24/08/2011 1:32 AM, "jblas" <
reply@reply.github.com>
wrote:

@MrDart

What device/platform are you running your test on? I see no differences on
some of the Android devices I'm testing on.

@rmahnovetsky

How are you turning off Hardware acceleration? I thought config switches
were for apps you packaged yourself, or are you using Phone Gap? The browser
on the Xoom is already hardware accelerated, but I wasn't aware of any
switches that allow you to turn it off for the built-in browser.

  • Kin

Reply to this email directly or view it on GitHub:
#455 (comment)

@MonsieurDart
Copy link

@jblas

I'm testing this code with Safari Version 5.1 (7534.48.3) on Mac OS X. But it seems to work fine on the iPhone.

@netline
Copy link

netline commented Aug 26, 2011

Hi,

I have a problem of "blinking" transition, but for me it's link to the iPad keyboard.

My forum post : http://forum.jquery.com/topic/transition-goes-wrong-when-ipad-keyboard-shows-up
Someone with quite the same issue here in bug tracker : #1983
A video a the problem : http://www.youtube.com/watch?v=iT8-YPETkAk
And a page to test on iPad : http://demo.netline.lu/jqueryMobile/

I don't know if it's the same "blinking" as here, but it's very annoying...

@jblas
Copy link
Contributor

jblas commented Aug 26, 2011

@netline

I opened a separate bug regarding your problem:

#2343

  • Kin

@kenjiru
Copy link

kenjiru commented Sep 16, 2011

This is very annoying on Android.

Android 2.2 on Samsung Galaxy S.

@toddparker
Copy link
Contributor

Hi all - At this stage, we've really tried pretty much every technique or approach that might improve the smoothness of transitions and reduce blinkiness and it's a fine balancing act between compatibility and accessibility. The gist is this: because all the pages actually share the same viewport, we need to scroll the document to jump up to the top of the page before a transition (or restore a scroll position) so the only way to make transitions smoother is to have the page your on and the one you're transitioning to be in their own containers with overflow. Now that iOS5 supports this, we are going to encourage browsers makers to follow suit and we've proactively added features to leverage iOS for way better transitions and true fixed toolbars.

We were also hoping that migrating from keyframe-based page animations to CSS transitions would improve animations, especially in Android but we were disappointed to see that some devices were a bit better, others a bit worse but most were a wash. We've decided to hol doff on rolling this out because FF and Opera's mobile support for transitons isn't quite ready.

We know that Android's transitions aren't great and that Honeycomb is especially blinky but we just can't find a solution for this right now because Android is frankly pretty darn bad with hardware acceleration and buffering. In any case, we will continue to work on this and hope that native support for scrolling will have quick uptake because that is going to be the true way forward is we want to support cross-browser.

This is still incredibly important for the project so this will be a priority even after 1.0 goes out. There's lot of smart people here, so please do weigh in with ideas!

@quangmv
Copy link

quangmv commented Oct 10, 2011

This is very annoying

@toddparker
Copy link
Contributor

@quangmv - I agree :)

Like I said above, we're exhausted every option to smooth this out so we're actively lobbying browser makers to improve their support and performance for native overflow: CSS support. iOS5 already has this and I know RIM and others are making strides here too. We already have a great system in place for making transitions and fixed toolbars pretty much perfect as platforms support this -- just turn on the touchOverflowEnabled feature and test the pages on iOS5 and you'll see where we're heading and how much better this is.

http://jquerymobile.com/demos/1.0rc1/docs/api/globalconfig.html

@offsky
Copy link

offsky commented Oct 18, 2011

As an interim concession, would it make sense to temporarily turn off the visibility of the page that is about to flicker/jump? I think that it would be preferable for the page transition to have a flash of white instead of having the scroll position visibly jump around.

@toddparker
Copy link
Contributor

Whenever there was a flash of white, it was very distracting and this could last for almost a second so it might freak people out that it blanks out. We add classes when transitioning if you want to make this customization on your end to test.

@karol-f
Copy link

karol-f commented Oct 24, 2011

Ok, what abut this idea - transitions are jumpy because next page have to be scrolled to top. What about we do like this:
#1. Instead of loading page BEFORE we change the page with nice transition, without the jump to the page only showing "loading...". So we change the page before it is loaded. We just have one small page which is always scrolled to top
#2 After the page loads we change "loading..." with page content with page content or information that we couldn't load page + BACK button.

I'm thinking in a good way or is it rubbish idea?

@pythonflying
Copy link

Hi, I just tested with 1.0rc2 for Droid X / Gingerbread and am very happy that the links jumping to secondary/different pages (original jumpy issue) are forever gone. Thanks!! I haven't tested with animations turned on yet (blinky), but i guess that is still an issue(?). The former was much more important to me. Kudos to whoever fixed that bug!

@karol-f
Copy link

karol-f commented Oct 26, 2011

@pythonflying: Checked with iPad - still the same jump to top before ajax page.

@toddparker
Copy link
Contributor

We haven't changed the basic mechanics (we can't if we want to keep compatibility) so if transitions are on, we do need to scroll the viewport.

On Oct 26, 2011, at 5:35 AM, "blnight" reply@reply.github.com wrote:

@pythonflying: Checked with iPad - still the same jump to top before ajax page.

Reply to this email directly or view it on GitHub:
#455 (comment)

@karol-f
Copy link

karol-f commented Oct 26, 2011

@toddparker - the viewport scrolling (to top) is done always, even when transitions are off.

This jump before transitions is the only thing that keeps me from using jQuery Mobile as it's the easiest and most compatible mobile framework out there. I think that I'm not the only person who would sacrifice compability to fix that.

Maybe you can give me some hint how to turn it off so I can experiment with some solutions? I commented out almost all code which I thought was responsible for this jump but it still occurs - is there some tricky way how the jump/scrol top is done?

Regards.

@toddparker
Copy link
Contributor

@blknight - can you create a new issue for this? If transitions are off, I think we shouldn't scroll to top. If you ca provide a test page, that would be helpful

@toddparker
Copy link
Contributor

Sorry, I was thinking that you were saying that the scroll happened with Ajax off, but this is still Ajax-based nav with multiple pages in the DOM but no transitions. In that scenario, we still need to scroll to the top otherwise, if you were scrolled halfway down the page and clicked a link, the next page would have a ton of whitespace above it. You can turn off Ajax nav if you don't want transitions -- the whole point of the Ajax nav system is primarily to have both pages in the DOM so as can animate between them.

@karol-f
Copy link

karol-f commented Oct 26, 2011

@toddparker - yes, you are right about Ajax scroll to top - that's what I meant.

The problem is that I want both Ajax request + animations without scroll to top. I can see from comments that it's hard to achieve so I would chill out. I still think that this can be achieved if we first switch the page to our "loading page" (maybe with no content so we can scroll to top without visible jump) and then show loaded content.

Unfortunately I can't find way to remove scroll to top behaviour so I can't check above scenario myself. As I said I will chill out, thanks anyway. Regards.

@jblas
Copy link
Contributor

jblas commented Oct 26, 2011

@blnight

Your not the first to ask for this option, and perhaps we should consider a way to turn it off via a config option. The problem that @toddparker was referring to above was that without doing the "scroll to the top", transitions to new pages will result in a change in the document height ... the problem is different browsers do different things when this happens. Some stay at the current scroll offset even when the document height is less than that offset, resulting in what looks like a blank page, while others will adjust accordingly showing you the bottom of the new page content. Aside from this problem, it just looks wierd to see a transition that doesn't involve the top of a document.

Believe me when I say we have tried several times to figure out how to make this smoother, for example offsetting the rendering of the new page by the current scroll position during the transition, etc ... but we always get bitten by blinky/flashing rendering when we fix the scroll position for the new page because the browser thinks it hasn't rendered that part of the document.

I just wanted to give you a feeling of the types of issues you may come up against if we give an option to turn this behavior off.

@karol-f
Copy link

karol-f commented Oct 26, 2011

@jblas - thank you for the response. I don't want to take your time so I will just say that I'm really impressed by your work. Thanks and take care.

@toddparker
Copy link
Contributor

Be very careful if you add -webkit-backface-visibility: hidden; to your styles. We've seen this cause all sorts of odd behavior in Android with form inputs.

@guy-wb
Copy link

guy-wb commented Nov 20, 2011

Don't know if this will help iron this out, but I noticed that when my <body> element contained a direction:rtl the reverse slide transition flickered badly.
Setting the direction on the page element (.ui-page) seemed to fix this.

@toddparker
Copy link
Contributor

We have a new centralized ticket #3217 for the page transition re-factor we're doing for 1.1 here so I'm closing these older issues to keep things focused:
#3217

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests