How to achieve Provider.select behaviour using built in InheritedWidget like MediaQuery? - performance

In my chat app every message depends on MediaQuery (font scaling). When keyboard is appear on Android 11+ then bottom insets in MediaQuery are animated from 0 to keyboard height. It cause unwanted rebuilds of all messages, but they depends only from font scaling. With Provider library I can use method select for this case. How to achieve same result with MediaQuery?

Since there is no code provided in the question, I'll try to help based on the question description. I see multiple potential issues here.
The viewInsets animation of MediaQuery is probably not what's causing the rebuild.
One might think the dependence on MediaQuery's textScaleFactor is the cause of rebuilds whenever MediaQuery changes, but I'm willing to bet that, even if you remove the dependency and just simply return an empty Container, it would still rebuild during the keyboard collapse animation.
So what's causing the rebuilds? Probably the fact that the app area expanded/shrank due to keyboards popping up.
For example, the total height of a Scaffold would actually shrink, when a keyboard is visible. If you don't want this, you can set resizeToAvoidBottomInset for it, like so:
return Scaffold(
resizeToAvoidBottomInset: false,
// ...
You can access text scale factor much earlier in the widget tree.
If you really want to only get the text scale factor of MediaQuery, you can access it from much earlier in the widget tree, and save it as a variable, and pass it down however you like (provider, etc):
final scaleFactor = MediaQuery.of(context).textScaleFactor;
print(scaleFactor);
You can remove viewInsets from MediaQuery if you really want to.
If you want to remove viewInsets (or set it to a fixed value), you can override it by inserting another MediaQuery on the tree:
return MediaQuery(
data: MediaQuery.of(context).copyWith(
viewInsets: EdgeInsets.zero,
),
child: Container( /* always zero insets */ ),
);
Rebuilding shouldn't be a problem.
Lastly, Flutter widgets should be prepared to be rebuilt at any time and shouldn't cause any issues. So I assume you are only noticing your widgets being rebuilt because Flutter Inspector, or you added a print in the build method, and noticed a bunch of prints in the console. I wouldn't worry too much about it unless you are actually experiencing REAL performance issues. However, if your widgets don't behave properly when rebuilt at "unexpected times", you should fix that, because Flutter WILL rebuild your widgets all the time, not just when the keyboard is collapsed :D

Related

JavaFX DragView Image has lowered opacity compared to actual image... Can that be changed?

I have been working on using Drag and Drop with JavaFX, and one thing I notice is that items are given lowered opacity compared to their actual images, as well as the larger the image the made "Faded/transparent" the image gets. I am working on am application that can drag fairly large items which end up almost invisible when dragging, which defeats the purpose of using a DragView Image in the first place, and makes this unusable for larger items (the way I'm using the DragView I want the images to be a certain size compared to the scene in which I'm dragging onto).
My application essentially has 2 Windows (Stages) where the data is in one Stage and I get the item from a list and drag it onto the scene. The DragView image is a representation of the object going onto the scene, so when I drop the DragView Image, it gets dropped exactly into place on the scene, so the DragView is important to my overall application.
Just a NOTE: There is also backing data in my transfer in order to recreate the box, as well as additional data that gets transferred with the Drag and Drop.
I tried looking at the FX DragView Internal code but didn't find anything that sets the Opacity or anything like that, so one of my assumptions of "it's built into the OS" is something I keep thinking about, as lowered opacity is something I remember being built in, and when trying it it does happen, but very very slight, and not as bad as what I'm experiencing (Also possible that since the icons are much smaller they don't run into the "larger image opacity issue."
I am running Windows 7 64-Bit for those who are wondering.
My question is, is it possible to change the opacity settings of the Drag and Drop ImageView either via JavaFX or possibly Native with using something along the lines of JNI?
I don't have any example code at the moment, but can add if someone is interested, but I'm sure for those who know about Drag and Drop ImageViews should already know about the opacity.
Thank you all.

Firefox canvas not showing anything after removed and added

I have a problem with the <canvas> in Firefox. Second time I remove and add it with Javascript, nothing will be drawn. I've checked the code and it seems find, it's even working in Chromium and Opera without any problems. Does anyone recognize this? I don't know how to debug the canvas.
I wish I could provide a code snippet, but I haven't been able to reproduce the bug outside it's code base.
Canvas is passive to changes that may affect the content. It doesn't keep track of these things.
The solution is to always update the content when a change occur such as in this case.
You can also tap into window.resize (Chrome for example may clear the canvas if you use the dialogs etc.) and there can be other unknown factors. So never assume canvas will contain what is drawn but always redraw everything in those cases.

EaselJS and multi layered canvas system: performance tuning, game developing, event handling

I'm an engineer and we are currently porting our Red5 + Flash game into a Node.js + Easeljs html5 application.
Basicly: it's a board game, not an rpg. The layer system means we have multiple canvasses, based on functionally. For example there is a static background stage, with images. There is a layer for just the timers.
At default, all canvas size is 1920x1080, if needed we downscale to fit to the resolution.
The first approach used kinetic.js, but the performance fallen when the game got complex. Then we switched to easel, because it's abstraction level is lower, so we can decide how to implement some more function, not just use the provided robust one.
I was optimistic, but now it's starting to show slowness again, that's why I want to look deeper inside and do fine performance tuning. (Of course everything is fine in Chrome, Firefox is the problem, but the game must run smoothly on all modern browser).
The main layer (stage) is the map, contains ~30 containers, in each there is a complex custom shape, ~10 images. The containers are listening to mouse events, like mouseover, out, click. Currently, for example on mouseover I refill the shape with gradient.
Somehow, when I use cache, like the way in the tuts the performance get even worse, so I assume I'm messing up something.
I collected some advanced questions:
In the described situation when can I use cache and how? I've already tried cache on init, cacheUpdate after fill with other color or gradient, then stage.update(). No impact.
If I have a static, never changing stage cache doesn't make sense on that layer, right?
What stage.update() exactly do? Triggering the full layer redraw? The doc mentions some kind of intelligent if changed then redraw effect.
If I want to refill a custom shape with new color or gradient I have to completely redraw its graphics, not just use a setFill method, right?
In easel there is no possibility to redraw just a container for example, so how can I manage to not update the whole stage, but just the one container that changed? I thought I can achieve this with caching, cache all containers the just update the one that changed, but this way didn't work at all for me.
Does it make sense to cache bitmap images? If there are custom shapes and images in a container what is better? Cache the container or just the shape in container.
I found a strange bug, or at least an interesting clue. My canvas layers totally overlapping. On the inferior layers the mouseover listening is working well, but the click isn't on the very same container/object.
How can I produce a click event propagation to overlapped layers those have click listeners? I've tried it with simple DOM, jquery, but the event objects were far away from what canvas listeners wanted to get.
In brief, methods and props I've already played with bare success when tried tuning: cache(), updateCache(), update(), mouseEnabled, snapToPixel, clear(), autoClear, enableMouseOver, useRAF, setFPS().
Any answer, suggestion, starting point appreciated.
UPDATE:
This free board game is a strategy game, so you are facing a world map, with ~30 territories. The custom shapes are the territories and a container holds a territory shape and the icons that should be over the territory. This container overlapping is minimal.
An example mouse event is a hover effect. The player navigate over the territory shape then the shape is getting recolored, resized, etc and a bubble showing up with details about the place.
Basically, maximum amount of 1-3 container could change at once (except the init phase -> all at this time). Not just the animations and recoloring slow in FF, but the listener delay is high too.
I wrote a change handler, so I only stage.update() up on tick the modified stages and the stages where an animation is running (tweenjs).
In my first approach I put every image to the container that could be needed at least once during the game, so I only set visible flags on images (not vectors).
Regarding caching:
There are some strange caching-issues, somehow the performance can drop with certain sizes of the caching rectangle: CreateJS / EaselJS Strange Performance with certain size shapes
(2) Depending on how often you call stage.update();
(3)
Each time the update method is called, the stage will tick any
descendants exposing a tick method (ex. BitmapAnimation) and render
its entire display list to the canvas. Any parameters passed to update
will be passed on to any onTick handlers.
=> Afaik it rerenders everything if not cached
(4) Yes.
(5) No. (I don't know of any)
(6) If the content's of the container don't change often, I'd cache the whole container, otherwise the container will be reconstructed every frame.
I have a question though: Why do you use multiple canvases? How many do you use? I could imagine that using multiple canvases might slow down the game.
How many sprites do you use in total?
2: if your layer or stage doesn't change, don't call stage.update() for that layer (so it doesn't gets rerendered, gives me a much lower cpu!)
For example, keep a global "stagechanged" variable and set this to true when something has changed:
createjs.Ticker.addEventListener("tick",
function() {
if (stagechanged)
{
stagechanged = false;
stage.update();
}
});
(or do you already use this, as stated in your "update"?)
4: I found a way to update for example the fill color :)
contaier1.shape1.graphics._fillInstructions[0].params[1] = '#FFFFFF';
(use chrome debugger to look at the _fillInstructions array to see which array position contains your color)
5: I found a way to just paint one container :)
//manual draw 1 component (!)
var a = stage.canvas.getContext("2d");
a.save();
container1.updateContext(a); //set position(x,y) on context
container1.draw(a);
a.restore();

Stop animation for expandAll on a tree panel

IE8 has a horrible time collapsing a medium sized tree panel with multiple columns. It is way too slow.
I am looking for ways to speedup the transitions from expandAll to collapseAll states.
One such way would seem to me is cancelling animation for IE8. It seems that in previous versions there were options that maybe specified on expand/collpase methods to enable or disable animation. However I don't see these options anymore.
Has anyone done this on 4.1x?
TreePanel has animate property that can be set to disable the animation:
animate:!Ext.isIE
Tried this and it works. However the effect is opposite to what I expected :(
With no animation IE just sits there and thinks it over, and over and over until it calculates every node and then repaints the entire tree at once. This makes it look like it takes longer not shorter, since with animation you can at least see IE struggling ...

CALayer flickering when adding a foreground layer to IKImageBrowserView items with garbage collection on

I'm trying to implement a technique similar to the one in the ImageBrowserViewAppearance sample code from Apple (located here: http://developer.apple.com/library/mac/#samplecode/ImageBrowserViewAppearance/Introduction/Intro.html ), where CALayers are generated on top of the items in the IKImageBrowserView to customize the appearances of the objects in the image browser.
However, I'm getting a weird problem when I turn on garbage collection, and I can reproduce it in the Apple sample code. Simply turn on Garbage Collection in the target, and build and launch the ImageBrowserAppearance sample app. Then, add some photos to the image browser using the "Add Photos..." button.
Now, click on an empty portion of the IKImageBrowserView, and click and drag to start selecting multiple items in the browser view. As you drag the selection box around, you should notice that sometimes the pin and gloss overlay for some of the items flicker and briefly appear in the bottom-left corner of the IKImageBrowserView. All of the CALayers seem to do this occasionally, I've seen the white surrounding slide area flicker down into the bottom-left corner as well.
When I mimic the technique in my own code, I (not surprisingly) also can reproduce this badge flickering. However, this problem disappears when garbage collection is off.
Anybody have a clue what could be going wrong here? I'd like to use garbage collection in my app in conjunction with this technique, but the flickering is kind of annoying.
I bookmarked this a while back but Apple's changed the URL and the text. Fortunately I quoted it when I bookmarked it:
The Core Graphics APIs (Quartz 2D) see an approximately 25% reduction in drawing performance for applications compiled to use garbage collection.
That "25% reduction in drawing performance" text has been rewritten into a "slight overhead in code execution" and that was for 10.5. Perhaps Apple fixed it for 10.6. And you're talking Core Animation, not Core Graphics.
Still, Core Animation eventually has to talk to Core Graphics, and perhaps that performance issue hasn't gone away, and you're being bitten by it.
I fooled around with this a bit and can confirm I get the same behavior running the project with GC turned on. In fact, if you're patient enough and slowly change the selection one image at a time using the arrow keys, eventually it'll trigger the behavior and you can see the layers from one image in the view are displayed in the lower left corner instead of on top of the image. I haven't been able to find any sort of pattern as to when it happens, or any relation between which image is selected and which image has its layers missing. I'm assuming that for whatever reason, those layers are getting their frame origin set to {0, 0}, but heck if I know why.

Resources