I am trying out this new implementation where I am updating some div's bottom/top value to emulate fixed position using javascript with scroll event. The problem is while scrolling the div's are getting a fixed position but moving little bit up/down depending on scroll direction. Had to do it this way as I used transform scale. So CSS position fixed doesn't work. Any optimization advice will be very helpful.
the code is here --> Alternative of position fixed using JavaScript shows weird behavior on window resize
If you check my page on desktop/laptop you can experience that. It depends on a lot of variables like how powerful the device is, browser to browser. I am hoping that if anyone has access to MAC OS on safari and chrome or Windows chrome or any desktop/laptop with a decent browser on it may check the user experience and leave a comment about how laggy jittery is it? Is it like okay or bad?
the webpage link --> https://elomymelo.com/soundcore-motion-boom-plus.html
All you need to do is, scroll down half of my page clicking the link above on desktop/laptop. The right side content should get fixed. But may have jittery behavior on scroll. And please leave a comment about how bad is the experience?
Thanks for your time. This will help me a lot to figure out if I should implement it on the other pages or not. Any optimization advice will be very helpful.
I have been searching for the best part of a day in order to try and find a way around this but cant. So here I am.
Basically I am working on a component which is position: fixed; to the bottom of the mobile browser's viewport window. This is trivial in itself.
The issue is that the company's native iOS app has an Apple association file which presents the Apple smart banner to open the native app at the top of the page.
When this is presented to the end user it seems that the browser redefines what it classes as the bottom of the page and, as a result, anything which is fixed to the bottom of the page is overlapped by the navigation toolbar which appears.
The only solution I can think of is to write out a list of all Apple mobile device viewport sizes and then compare the size of the window.innerHeight value on the onresize event -- which seems like absolute overkill and still has some nuance in itself.
I have added some screen shots to illustrate the problem and what I would like to achieve.
Thank you in advance to anyone who can assist with this. I have searched through the answers to other questions but they all seem to be people either trying to surface a smart banner or people trying to redirect to their app.
I have managed to find a solution by leveraging the resize event in the document window and then setting the top attribute of the element to window.innerHeight - element.clientHeight.
If there is a better, more performant way of achieving this I would love to still hear the answer but I will, for all intents and purposes, mark this as answered.
On a side note this does feel like a bug in the Safari browser itself as it seems that Apple are altering what they consider to be the bottom of the document.
Solution:
window.onresize = () => {
const button = document.querySelector(".add-to-bag--sticky");
if (button) {
button.style.top = `${window.innerHeight - button.clientHeight}px`;
}
};
I am trying to implement a chat application, more precisely a scroll behavior for chat application. I think it's best described with a gif.
https://i.imgur.com/NnpMeOx.gif
As you can see, I want to support a few key features:
Scrolling is reversed so on page load, the messages start on the bottom along with the scrollbar
Chat is scrolled to the bottom when user types in a message. (this is easy, no need to pay attention to this part)
If new messages appears (pushed by websocket in real life) it shouldn't disrupt the existing scroll position, unless it's already at the bottom. Then it should scroll to reveal the message automatically.
So far I've implemented 2 solutions:
a) Display flex and flex-direction column-reverse on the scrollable element. This works beautifully out of a box, but only on chrome :( IE (and Edge) as well as firefox just ignores this totally. NOT A GOOD SOLUTION
b) I flipped the container with transform: scaleY(-1) then I reversed the messages and fliped every one of those with the same transform. The main obvious problem here is the scroll (mouse wheel and arrows) is reversed. I sort of fixed it, didn't manage smooth scroll (sucks) but yet again, Edge (and probably IE) just shows scrollbar as disabled. NOT A GOOD SOLUTION
I am really hoping to find somebody who can point me in the right direction because so far, my efforts while logically ok totally failed browser compatibility.
The code is on https://github.com/PeterKottas/react-bell-chat, it's react but tbh, that doesn't matter much as this seems more like a general web dev exercise.
P.S.: I can't use jQuery, hope that's fair. So either css or plain javascript. Like I've said, this doesn't have much to do with react
Well I got no replies and managed to fix it myself so I'll accept this in case it helps somebody in the future.
3rd and final solution:
I kept the direction of scrolling and didn't do any reversing at all. Instead I hooked into onScroll and wheel event, created a few callbacks and managed to mimic the behavior perfectly. You can find more details in the code on https://github.com/PeterKottas/react-bell-chat.
I've been working on a slideshow script that uses CSS3 transitions, or jQuery's animate when they are unavailable. I've created a custom function to do the slide animations, which does so appropriately. Everything seemed to be working fine, but I've hit a major snag during testing.
For one reason or another, there is an large delay applying the jQuery CSS before and after the transition on large slideshows. For example, the slideshow in the link below is around 9900 pixels wide (container width, most of which is hidden). The container is maneuvered to display the appropriate slide, using CSS3 transition and transform properties. The delay occurs applying the CSS between lines 75 - 82 in the paste below. In particular, applying the 'transition' CSS causes the problem. Add the 'transition' CSS to the stylesheet (rather than applying it with JS), and delay disappears. This isn't really a solution however, because we only want to use CSS3 transitions on specific properties, that can vary (using 'all' in the stylesheet would transition some CSS that we don't want to animate, but change regularly).
Animation function:
http://pastebin.com/9wumQvrP
Slideshow Demo:
http://www.matthewruddy.com/demo/?p=2431
The real problem is with iOS, in which the slideshow (and even the browser sometimes) becomes completely un-usable. I can't pinpoint any errors, and have really exhausted my knowledge of debugging JS. I'm sure it is related to this section of the function after playing around a bit, and disabling CSS3 support within the plugin altogether removes the problem completely.
I'm completely stuck, and really appreciate any help anyone can give.
--- Edit ---
I've tried applying the CSS with native Javascript rather than jQuery's .css function. Same results, no better performance. Also worth noting that this isn't happening at all in Firefox, and seems to only be a problem with Webkit browsers.
Anyone with a solution, would happy to make a donation towards a few beers! I really cannot figure this out!
--- Second Edit ---
Ok, so been debugging and I can see that the slowdown is caused by the browser repaint cycle that is taking a very long time. Is there a better way to handle this that the way it is already doing? Positioning the element absolutely is a known way to reduce repaints, but that isn't really working because the slideshow is responsive. Absolutely positioning the slide images or the slides themselves causes it to collapse.
--- Third Edit ---
A day later, and I've made some progress. Adding 'transition: all 0s ease' to the elements stylesheet CSS has gotten rid of the repaint caused by adding the inline CSS transition property via the custom animation function mentioned in the original post. This causes a significant performance gain, especially when removing the inline CSS transition property when the transition itself has finished.
Good stuff! However, now there is still a slowdown when the inline CSS translate is being removed (that was used to create the hardware accelerated transition effect itself) after the transition, and the left positioning is being applied. When the two happen together, there is a slowdown.
Breaking them up into two separate tasks (the translate removed, then the left position added in a setTimeout with no time specified), again gets rid of the repaints = performance gain, and looks likes problem solved. But sometimes, the CSS transition property isn't get negated fast enough, and the translate removal gets animated. No good, and don't know where to look next to work around it.
I think the problem is you're loading HUGE images :)
They are too big for the container you have them in, so you scale them down, which is even more resource intensive.
Try resizing them.
First of all congrats for your debugging!
I have been working on the exact same stuff lately and found out that ios devices don't support a large number of images positionned in the same page. It causes crashes and the only solution I found was removing elements instead of just hiding them. The downside is that removing and appending elements causes lags so you have to do it cleverly, when your transitions are done. I thought the best way to go was keep 3 or 5 images in the DOM and replacing the rest with thumbnails of the images, resized to fit the original. When transitions are done, I'd just put the large images back into place...
Hope this helps you a bit on the ios problem at least...
After spending some time analysing your code TimeLine with Chrome Dev Tools, I believe there's some optimization you could do.
As far as I can tell, every single one of your 16 images gets fully repainted every time an animation is requested. This seems quite obvious to me, as there are 16 images in your example, and the Chrome Dev Tools reports 16 long "Paint" executions every time in hit "Next".
In my humble opinion, you should figure out a solution that considers only translating two images: the one you want to hide and the one you want to show. So, consider please, not moving the rest of the images and, instead, leaving them all side-by-side to the shown image.
One more thing, using scaled down images is probably making the paint cycles quite longer. Avoid them whenever you can.
Well, think I've managed to figure it out! Just so you know, original post links don't reflect the changes as I've done them on my localhost environment.
Absolutely positioning the slides container has fixed the problem that was occurring with repaint speeds after the transition had taken place (whilst applying CSS properties). Obviously taking them out of the DOM has done the trick, allowing painting to take place much more efficiently.
I originally didn't try this too much because I knew this would add a lot of work to the resizing functionality. I had originally intended to not resize at all in JS, and rely on percentages to do the dirty work. Absolutely positioning the container would cause the slideshow viewport to collapse, rendering the native resizing useless.
However, I was already having problems with sub-pixel rendering in other browsers anyway, so I guess it was time to bite the bullet and rely on fixed pixel values. I then used JS to handle the resizing, using the window resize event. All seems good, however the slideshow was still collapsed due to the positioning. Assigning height values wasn't working correctly, so was at a bit of a loss.
Thankfully, I came across a neat little trick of setting the 'padding-top' of the slideshow viewport to a percentage value, dynamically calculated (desired slideshow height, set in the settings panel for this script, divided by desired width). As padding-top percentages are relative to the width of the element, this did a great job of providing responsive height and correcting the viewport again (no longer looking collapsed).
Here is some info on using padding-top for responsive elements that maintain aspect ratio. Great little trick: http://f6design.com/projects/responsive-aspect-ratio/
All is good now, and things are working well in iOS and webkit browsers. Everything is extremely quick and working as it should. Four days later, and it is finally figured out. Not happy about having to resort to JS for resizing, but I guess it was always going to happen due to percentage inconsistencies between browsers. Lots of decimals = no good!
Thanks to all who tried to point me in the right direction. Definitely got me thinking, and learned a lot of debugging skills that I can use again to make sure transitions are performing well. Thanks again!
not sure if this helps or not but I noticed you use 3d translation - I would think a simple 2d translation would be enough especially since your third parameter is 0 and might accelerate the issue, also go with fewer images as Armel L. suggested, don't have an iphone to test though... alternatively, this is a solution I used before css3 but should still work move the element containing the images using javascript by modifying left (?and top - the demo only moves left and right though? without the transition effects) and this way you can fine-tune the refresh rate which I think might account for the slowdown... you can go as low as 18 fps without anyone noticing, might even be good enough with just 16fps
I had this when I was first designing a magazine carousel-style page device.
If you have a series of images within a long "tray", even if they are not within the viewport, they will still take up ram, and you can effectively have five or so before leaks and nastiness begin to happen.
What I found works is "hiding" them ... But make sure they take up the physical space necessary.
What I also found worked was that one could make the 'previous' current and 'next' image are visible and move the tray, 'unhiding' them as they reach those three positions.
In my own system, I skipped the 'tray' holding e images and only had them at -100% width, 100% width and the current one a 0.
I never had much luck with the typical long-tray carousel with large scale background images... Especially with css3 acceleration.
I have the weirdest of problems.
I have a jQuery function that animates the result bars of a poll.
function displayResults() {
$(".q_answers1 div").each(function(){
var percentage = $(this).next().text();
$(this).css({width: "0%"}).animate({
width: percentage}, 'slow');
});
}
As you can see it is a simple animation that elongates a couple of divs. It works OK until I embed it on my main page. The problem seems to be that there is too much OTHER content that breaks the beauty of the smooth animation. I was thinking of me being lame in implementing the JavaScript, CSS etc. but after a couple of tests and reverse engineering I found out that THE MORE CONTENT (images, text, video) I HAVE ON THE PAGE, THE WORSE THE QUALITY OF THE ANIMATION IS. I can only guess what the reason is... I really like my animation :)! Appreciate the help!
This demo shows how it should look like. I get it to work like this when the page has less content on it. By bad quality I mean not smooth flow of the bars. The worst case is when the bars appear in their final width in an instant.Tested it on Mozilla and Chrome and IE7 - no difference.
Edit: It seems that without the actual examples your hands are tied so here is something to work on. Just look for the red border, pick one answer and click the button. The language is Bulgarian if you are wondering.
A desirable behavior here
I can live with that here
Starting to look weird here
I don't get this here
If all of them look the same to you then my computer is to blame and I don't have to worry about this particular problem anymore, which already took 2 much effort. Use Mozilla if possible.
Edit 2: I found this SO answer that answers some of my questions about the animate() function and how it works, but the problem remains unsolved, at least for my computer.
How much content are we talking here?
If the page is large enough, the browser engine may simply not have enough power to re-render the contents quickly enough to provide a smooth display.
The way jQuery does it's animation is that it periodically updates inline CSS attributes. If the elements you're changing style's of are floated or have other complex interactions with the other elements on the page then the animation wont be smooth.
In short, put less stuff on your page. You might also attempt some sort of iFrame solution or switch to using flash to display the results.
This is just a limitation of the system, unfortunately.