Createjs: Stage.update() internal working question for performance optimization. Does it happen at each tick, or each time it's called? - createjs

In order to optimize createjs code, I cannot find info on this matter.
Case:
I have a scrollbar component, and each time I move the scrollbar stage is updated to reflect changes in scrollbar visual. Also a scroll event is triggered.
Application listens to the event, and updates some visual in scrolled content, therefore another Stage.update() is triggered.
My question is: does stage get updated only at each "tick", or the above situation will cause stage to update twice in the same instant degrading performance?
In code, will:
stage.update();
stage.update();
stage.update();
Cause stage to update 3 times in a row? Or only once at next tick?
Thank you

There is no debouncing on the stage update, so each time you call it, the stage will be rendered. Additionally, internal counters like tick-based frame advances will be fired.
It is not advisable to run it more times than you need to. Usually apps either have a continuous Ticker, or are updated only when content changes.
If you want to create a hybrid, I recommend checking an update property that you set yourself. Then you can toggle it any time, and it will run once per tick max.
createjs.Ticker.on("tick", function(e) {
if (shouldUpdate) { stage.update(e); }
shouldUpdate = false;
});
Hope that helps!

Related

Nuxt EventBus - usage for many events

in my Nuxt app I have a Canvas that listens for mouse events. Now I want to send those mouse events to the DOM, everything is working fine. But I'm concerned that there are too many events for Vue, because there is like thousands of them. When I switch to the Vue dev tools, my Computer already begins to stutter. I feel like Vue is only made for simple click events, but I'm using it for a ton. Is there a better way to handle that?
init(){
document.addEventListener("mousemove", this.mouseMove.bind(this));
}
mouseMove(e){
EventBus.$emit("MOUSEMOVE", e);
}
It's okay if you need to add certain event listeners here and there. Just make sure you remove them when to component is destroyed, e.g.
mounted() {
window.addEventListener('eventName', yourMethod);
},
beforeDestroy() {
window.removeEventListener('eventName', yourMethod);
}
How about using debouncer for a short time limit.
I'm guessing that your DOM is not updating on every event and it takes some to self update. So slow down the event bus emit like in every 50/100 ms there will be an event fire. You can emit to event bus on every 50 MiliSecond or as per as your need. That would be helpful even if you solve the problem in other way.

Vuex two commits in same action does not trigger watch

When I watch $store.stateA, the watch callback function for the following seems to not trigger.
stateA: false
muationA(state,val){
state.stateA = val
}
actionA({commit},val) {
commit('mutationA', true)
commit('mutationB', false) //take this out would trigger the watch callback
}
So what is the case here? the entire action callback need to finish before the watch functions are triggered?
As Nit mentioned, both mutations cancel each other since they are done synchronously. Read the "Reactivity in Depth" section of the doc for more info. In particular (emphasis mine):
In case you haven’t noticed yet, Vue performs DOM updates asynchronously. Whenever a data change is observed, it will open a queue and buffer all the data changes that happen in the same event loop. If the same watcher is triggered multiple times, it will be pushed into the queue only once. This buffered de-duplication is important in avoiding unnecessary calculations and DOM manipulations. Then, in the next event loop “tick”, Vue flushes the queue and performs the actual (already de-duped) work.
Other watcher solutions do work differently and are triggered right away when the value changes (e.g. Backbone.js). Vue does not work that way.
I wanted once to use a vuex variable as an event transmitter across components and needed to set a boolean variable to false and immediately to true afterward. I however saw that the watch in the component did not pick it up. The issue as mentioned in the other post is that they cancel each other because they are in the same event loop.
In order to make that work, I just had to separate their event loop by waiting for the Vue.nextTick() as follows:
// First operation
await Vue.nextTick();
// Second operation

Can anyone explain more on VueJS Async Update Queue?

I am reading the vue official doc on Async Update Queue, and got confused on:
Whenever a data change is observed, it will open a queue and buffer
all the data changes that happen in the same event loop
what does it mean by the same event loop, are there gonna be multiple event loops at the same time? It also says the queue will be flushed in the next event loop “tick”, what does tick mean here? what if there is no next event loop or the next event loop never tick?
Let me try answering this question as par my understanding.
what does it mean by the same event loop, are there gonna be multiple event loops at the same time?
Instead of applying each and every change in any vue property/method/variable to the view, vue saves all those changes in queue and flush those changes later. In this process of pushing the changes in the queue, it optimises by not re-rendering on each change as is commented here:
/**
* Push a watcher into the watcher queue.
* Jobs with duplicate IDs will be skipped unless it's
* pushed when the queue is being flushed.
*/
export function queueWatcher (watcher: Watcher) {
...
...
the queue will be flushed in the next event loop “tick”, what does tick mean here?
Internally Vue tries native Promise.then and MutationObserver for the asynchronous queuing and falls back to setTimeout(fn, 0). Here you can see first preference for this is given to native Promise.then after that MutationObserver where native Promise is not available and in worst case fallback to setTimeout.

DurandalJS - Why are transitions not starting right away when a user navigates

Could someone explain why the transitions (at least the default one - entrance) are not starting right away when a user clicks on a link (navigate) with Durandal?
In other words, do we need two mechanisms (loader animation + transition) to indicate that there is an action underway (ex. ajax call inside the activate method).
I'm sure there's a good reason, or maybe I just have to modify the entrance transition?
It seems like Durandal's transitions run once the activate function resolves. I asked a similar question where I enumerated some of the possible solutions that I found which worked for my situation specifically:
Manually animate away every view in its deactivate() and animate it back in via its viewAttached()
Bind the .page-host div's visibility to router.isNavigating (using a custom binding to handle the transition such as the fadeVisible example from the knockout site)
Manually subscribe to router.isNavigating and run custom logic when it changes
Hopefully this helps.
If you did not compress your entire application then the first process will be requirejs downloading the next amd module and then downloading the appropriate view.
The next step is durandal calling activate on your module. Activate if it returns a Deferred then it will wait for the deferred to complete.
Once activate is complete then the transition is called. The transition is responsible for swapping out the old view for the new one.
So, if its taking a while to kick off the transition its probably because its lagging in downloading your module and view.. or your activate method is taking a bit of time to finish.

Dojo scroll problem with DataGrid

I have problem in DOJO with DataGrid. I refresh my grid on every 1 sec with this code
window.store_data_log= new dojo.data.ItemFileReadStore({data:{items:temp}});
var grid = dijit.byId("grid_log");
grid.setStore(window.store_data_log);
and it works fine ( put new data ). Problem is that when I have lot off rows and I scroll down, my grid refreshs and my scroll goes on top grid. How to solve this ?
Of course, you are totally clearing the store and resetting it every second from scratch. When you reset the store, you basically reset the grid. I would expect nothing less than the grid resetting the scroll position when you refresh its store.
You may want to learn how to properly use the store rather than just trying to reset it. I answered this here:
How to refresh datagrid
If you use dojo properly, you will get good results, but by just taking a shortcut and trying to refresh the store every second you are going to get an unusable grid.
You need to take a step back and solve your application architecture and not expect the grid refresh to be some kind of magic solution.
After going through (dojo) datagrid.js, I found how to resolve the issue:
//datastore you're using//
var store = new dojox.data.QueryReadStore({
//in the fetch()//
fetch: function (request){
//add the following://
request.isRender = false;
}
});
Important: Only set request.isRender to false when you don't want the grid to scroll back to the top. Just keep in mind that some situations (like sorting on a new column), it's probably best to set it to true. Just add some if/else statements to help with the logic.