Experiencing fade lag when element animates for the first time - performance

I have some custom buttons that control when to fade in an element (done in Jquery). For the most part, the functionality is how I'd expect it. The only problem is that when I press any of the buttons for the first time there is a delay in the animation (sometimes seeming to skip it entirely). I suspect this has to do with the initial loading of the content and the subsequent caching after the initial load.
Here's a snippet of the code:
$('.content').hide();
$('.button').click(function() {
if ($(this).hasClass('active')){
if (!state.isExpanded){
$('.button').animate({height: '5vw', width: '5%'}, 500);
$('#button-container').animate({height: '100%', width: '100%'}, 500);
showSection($(this), 1000);
...
...
showSection:
function showSection(elem, duration) {
var elemID = $(elem).attr('id');
console.log(elemID);
switch(elemID){
case 'person-icon':
$(aboutMeSection.ID).find('.content').fadeIn(duration);
break;
...
...
Worth noting that I'm trying to load in multiple custom SVG images created in illustrator the largest single object being 2.2 mB. This is my first time creating a website so it's not apparent to me what reasonable sizes are media elements. Might this be too large?

Turned out the SVG image I was using was too large. Just so this question isn't a complete waste to anyone that has a similar problem.
Consider whether the image you're using needs to be an SVG. Being a noobie I got caught up in its recent popularity and saved every image I created as an SVG when a PNG would do just fine.
A good article on SVG optimization I was reading before figured out what to do:
Optimizing SVGs for Web Use

Related

I inserted image deferring on my webpages, but Google SpeedTest tells me to consider lazy-loading offscreen and hidden images

I inserted, to show images on my webpsges, the solution offered by this site
https://varvy.com/pagespeed/defer-images.html
I modified the IMG calls
<img src="data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=" data-src="image1.jpg" alt="image 1">
and inserted, at the bottom of the page, the JS code
<script>function init() { var imgDefer = document.getElementsByTagName('img'); for (var i = 0; i < imgDefer.length; i++) {if (imgDefer[i].getAttribute('data-src')) { imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));}}} window.onload = init; </script>
It works ok. However, when using the Google 'PageSpeed Insights' tool, I'm still obtaining the following message:
Consider lazy-loading offscreen and hidden images after all critical resources have finished loading to lower time to interactive
Is the fix I considered a valid "lazy-loading offscreen" solution? I thought it would fix the problem. Are other fixes better solutions? Thank you.
I'd recommend using lozad.js + polyfill for deferring offscreen images (aka lazy loading). I haven't read the varvy article but someone who had, wrote that the method only defers the load of images til after the onload event and so the initial load weight of the page remains the same.
Lozad will not load an image until it's about to get scrolled into viewport.
For <img>s use an empty <svg> as the initial src value where 6 9 in the viewBox below defines the relation between width (6) and height (9) => change those values to fit your context. This will make sure there is no reflow in the page layout once the image(s) load.
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 9'%3E%3C/svg%3E"
Note that lozad.js uses Intersection Observer API that still lacks in browser support so be sure to add a polyfill.
Good luck!

Can I stop stationary SVG images from using excesssive CPU resources in QML?

I have a QML GridView, with a huge number of simple icons in it. The number can be in the millions, but only around a thousand will be visible at the same time, and there are only a few dozen types of images, so I guess they should be cached well.
If I use PNG images, everything is fine. The startup time is relatively long, but after everything is rendered, the application runs fine even on low-spec machines, and scrolling / resizing / zooming in the GridView is also fast and smooth.
However, if I use SVG instead, it slows my system down significantly. Even after everything is rendered, the responsiveness of the application is horrible, even GUI elements unrelated to the GridView are showing significant lag, the mouse cursor can barely be moved, etc. I thought after they are rendered, SVGs are presented just as any other image. Why must the CPU be busy if I don't even interact with them? And, most importantly, is there anything I can do about it? The same thing happens if I have SVG images containing nothing but a single rectangle, and use the same image in every cell. So it must mean the objects themselves are doing something.
"The number can be in the millions" and *"The startup time is relatively long"- those statement warrant a discussion about the design of your data model and bitmap caching strategy. But you didn't provide any code. So the following is a guess.
I'm not sure if you are loading the SVG images in C++ code or through QML, but I suspect you aren't setting the sourceSize (width and height) properties when you import your SVG. Hence, it's getting mapped into memory at a much larger size than it's getting rendered at. That is, it's eating up a lot more memory than it was with pre-sized PNG files. Or perhaps it's getting mapped in at a smaller size and Qt is is spending a lot of time having to resize these images at runtime as it scrolls in/out of view.
Open up one of your SVG files with notepad and look at at the attribute to see what the import size is.
In any case, try making sure your sourceSize.width and sourceSize.height match your render width/height.
Image {
id: icon
anchors.centerIn: parent
source: "cloud.svg"
sourceSize.width: 50
sourceSize.height: 50
width: 50
height: 50
}
Loading SVG's is an expensive operation...
Gridview manage dynamic objects.. creating visible items and destroying invisible items each time ....so, must render SVG each time you move the grid
One very bad idea is use that:
GridVIew{
cacheBuffer : 6000
//create 6000 items ...long startup time and memory expensive
...
}
This is a much better option:
Image {
id: icon
asynchronous : true //load image in asyncronus thread
sourceSize.width: width //scale as item size
sourceSize.height: height //scale as item size
...
}
If the load is too slow, you can add something like "LOADING..." text in the item background...

Flexslider Responsiveness

Just wondered if anyone using the Flexslider has found that when switching back and forth from different size browser windows the slide images do not automatically adjust to new height and widths.
Let me clarify - they do shrink correctly but when scaling back up the first image in the slideshow gets stuck at the previous aspect ratio until the next slide comes in, at which point the whole thing adjusts.
To stop my content from being affected I have created a fixed height container for the flexslider and have used media queries to change its height as it is scaled down. This works perfectly scaling down.
It seems to be on the way back up that it has trouble sorting the image heights out.
I would provide links but it is a new client project in confidence.
All coding is exactly as is from the demo files, with exception to the fixed height and media queries on the container div.
I had the SAME problem - I found that not all my widths were of the same value.
e.g.
.clone { display: block; float: left; width: 994px!important; }
<img src="http://www.website.com/images/panel1.jpg" alt="" width="980px">
There were about 4 instances in my css that had different widths [shame shame] so I went in there and raked the css file.
I hope this helps
Good Luck

Pan/Zoom painfully slow in IE8 RaphaelJS

I have been working on getting this seat mapping chart for a while and have created a few iterations, and the problem I keep finding is when I get to IE8 the panning for this is way to slow and delayed.
What I have at this point to cut down on load time is created a png to replace my "strokes" since I assume ie8 wanted to re-render each time I dragged the map.
I also added controls hoping to force IE8 users this option, but still there is a delay in the pan, and if I can have users with IE8 (and ie7 if possible) still drag/pan without the controls and the respond time a little faster that would be great.
Here is my current JSFiddle
I am still a little green with JS so if you have any suggestions it would be much appreciated. (PS Chrome frame is awesome but is not a option for me)
Update
I have removed the original dragging function and replaced the code using jqueryui's draggable function. Martin had suggested to just drag the div, and not the Raphael elements. Doing so lets this thing fly in ie6-8 which is great, but then came my concern about scaling. What I was seeing before on zoom my paper element WxH would stay the same ratio, cutting off my drawing when it zoomed in. After digging through the Raphael documentation I came across paper.setSize. setSize was exactly what I needed to allow this project to move and groove in ie6-8 and pretty much conquer all browsers in its path.
So in short, using jqueryui's draggable and paper.setSize has cured my cross browser zoom n' pan blues.
From what can be seen in the Fiddle, you are triggering a new rendering of the image by calling .translate() inside of a mousemove event handler:
mapContainer.translate(currentMapPosX, currentMapPosY);
rsrGroupies.translate(currentMapPosX, currentMapPosY);
This approach is toxic for performance in all browsers, let alone IE8. When dealing with VML in IE8 you should consider that each and every DOM change inside the image will result in the image being rendered again. Doing that while panning will always be painfully slow.
I see that you are already using jQuery in your Fiddle. If you want to increase performance of your panning, you should consider doing the following:
Render the image in Raphaƫl exactly once for the current zoom level. Do not attempt to change transformations in your VML/SVG image at any point in time while panning.
With the mousemove implementation of panning you already have, move or scroll the HTML container that holds your VML/SVG image instead. Imagine a <div> with overflow: hidden and simply move the image inside relatively, or scroll to the appropriate position.
This will require some adjustment of your coordinate calculations, but it will improve your performance in all browsers.

Desaturate effect with jQuery and Pixastic

Does anyone know how to use the Pixastic plugin and jQuery to where I could have an image fade from color to completely desaturated?
I am trying to avoid saving out two images and fading one out..
i did the inverse... having desaturated images fade in to color. achieved w/ only 1 image in conjuction w/ pixastic and livequery. i basically cloned the images, desaturated one of the copies, and stacked them on top of each other.... fading the top (desaturated) layer out on hover. i'm sure it could be more elegant, but it mostly works. you can see the effect at chicagointerhandball.org on all the "sponsor" logos
$('.sponsors').load(function() {
$('.sponsors').pixastic("desaturate");
}).each(function(index) {
var clone = $(this).clone().removeClass('sponsors').addClass('sponsors-color').css('opacity',.25);
$(this).parent().append(clone);
});
$('.sponsors-color').livequery(function(){
// use the helper function hover to bind a mouseover and mouseout event
$(this).hover(function() {
$(this).stop().animate({"opacity": 1});
}, function() {
$(this).stop().animate({"opacity": 0});
});
}, function() {
// unbind the mouseover and mouseout events
$(this)
.unbind('mouseover')
.unbind('mouseout');
});
Since all those pixastic image effects are generated on the fly I don't think it would be feasible to fade between saturated and desaturated. The saturation level of the image would have to be redrawn at each step of the fade. Your best bet would probably be to have two images, one saturated and one desaturated, and have them placed on top of one another. Then when you hover over one, fade in the other image.
Edit:
Just saw that you were trying to avoid having two images. Well, that's the only solution I can think of but I'd love to see if there were others. Depending on how many images there are, you could generate all the desaturated images on page load, place them on top of saturated images, hide them, and then fade them in on hover. Just a possibility.
you could get the best of both worlds by dynamically creating a duplication and desaturating that image with pixastic. Position the new desaturated image under the original and fade the original out.
You should be able to, it is in their jQuery documentation section.
// convert all images with class="photo" to greyscale
$(".photo").pixastic("desaturate");
Looks like this is possible with the canvas element.
With this you need to mix jQuery and the standard DOM calls. I was having the same issue just today about this. I couldn't get the hover to work cross platform from the examples given here and on their site. So I decided to think for myself on this one. Came up with a solution, hope it works for you:
http://you.arenot.me/2012/03/26/pixastic-desaturate-on-mouseover-mouseenter-mouseleave/

Resources