GWT button clicks getting laggy very quickly using Places/Activities in GWT2.1 - gwt

i'm new to GWT2.1's Places and Activities.
I'm using the same ActivityMapper as example below and getting laggy button clicks after just a few navigations.
The MVP architecture I'm using has the Presenter create listeners and define the View interface, but View objects are singletons.
Is my problem with lag due to all the listeners building up exponentially? Should I change it so that the View creates all the listeners instead? Or should I try unbinding instead?
E.g. in the GWT2.1 example here a new Activity is created every time getActivity(Place) is called.
public Activity getActivity(Place place) {
if (place instanceof HelloPlace)
return new HelloActivity((HelloPlace) place, clientFactory);
else if (place instanceof GoodbyePlace)
return new GoodbyeActivity((GoodbyePlace) place, clientFactory);
return null;
}

The view here adds event handlers to its widgets. It later calls its presenter when appropiate. I don't think that unbindinding the events would free up much memory or speed up the browser's event queue.
I believe you should further investigate if the actual button click is slow, or if it's the creation of Activities happening upon the event, or whatever else.

In the end I changed the MVP architecture to the same as the example here with View defining Activity and ViewImpl containing the UI Handlers. Since the Activities no longer contain handlers and the ViewImpls are singletons the problem goes away.

Related

ICommand not binding in Loaded event using MVVMLight framework

I am wondering why binding a button inside the Loaded event in WPF page does not work and will only work after navigating to another page, and going back.
I have an inventory app and on the main page, most of the ViewModel are called because of a Back button which goes back to a specific lists and what causes that is, it will start binding the even if that command is not for that page and it will also load the collections for other pages.
So I used Loaded page event to call the necessary methods to populate the lists and also start binding commands for this specific page. I also used Unloaded page event for clean up like unsubscribing to some CRUD events.
The problem now though is, buttons does not get binding in Loaded page event. I do not know why..
I have made a miniature app to demo the problem. It can be downloaded here
(full source code included)
https://www.dropbox.com/s/qzumzyicuvrktsi/ICommandTest.zip?dl=0
This is because your views are not getting notified about the change of Command_ShowAddWindow and Command_ClickMe. Let me explain:
When your Page constructor is first run the bindings to your commands are initialized and transferred to the view, but by that time your commands are null, so the view binds both buttons' commands to null.
Then when your Loaded event is fired the commands are initialized, but the view is not getting notified about it, so it keeps command bindings to null.
The solutions to the problem are:
You manually call RaisePropertyChanged to notify the view about commands change when you initialize them:
void InitCommands()
{
Command_ShowAddWindow = new RelayCommand(Command_ShowAddWindow_Click);
Command_ClickMe = new RelayCommand(Command_ClickMe_Click);
RaisePropertyChanged("Command_ShowAddWindow");
RaisePropertyChanged("Command_ClickMe");
}
Or you initialize your commands in your ViewModel constructor before DataBindings are initialized:
public ViewModel_Page1()
{
InitCommands();
...
}

GWT event handlers blocking UI

I'm new to GWT. I creating a MVP based project (as described here) that uses a number of custom events. There are several widgets (10+) that listen for some global events and perform some action (including writing to the DOM) in the event handlers.
What I'm finding is that the UI blocks and doesn't update until each and every one of the handlers for the one event finishes processing. This is causing the UI to perform slowly on page load and for any other events that cause the widget to update.
I created a similar project in plain JavaScript/jQuery and this was not an issue with that project. In fact, the UI was blazing fast. What am I doing wrong here? The documentation states that GWT is very performant, so I have to conclude that I'm just doing it wrong.
One example, I have a drop down that selects a date preset (like Yesterday, or Last Week). When this happens I set the selected preset in the model like so:
public void setDateRange(DatePreset dateRange) {
this.dateRange = dateRange;
eventBus.fireEvent(new DateChangedEvent(dateRange));
}
Each of the widgets has access to the same eventbus and registers to handler DateChanged events. Each of the widgets needs to do a fair amount of logic and processing (including making an ajax call) to then update itself with correct data.
#Override
public void onDateChanged(DateChangedEvent event) {
DatePreset dateRange = event.getDate();
… additional processing and logic
… ajax call
}
I've determined after some basic profiling that each widget requires about 100-150ms to finish processing (which means there's a UI delay of over one to two seconds). When I say blocking, I mean the dropdown where I selected the date preset doesn't even close (and I see the spinny wheel) until everything finishes.
What can I do to make this run faster (and without UI blocking)? I am open to any ideas. Thanks!
Measuring the speed of the project in developer mode can be a reason for this extreme slowness.
You can check out the real speed of the application if you deploy it to an appserver or if you delete the &gwt.codesvr=127.0.0.1:9997 part from the end of the url in devmode.

How to manage the creation of instances when navigating

I am programming WP7 application adhering the MVVM pattern.
I have ViewModelLocator which ensures that each instance of ViewModel is only one. These ViewModels are created when application is launched. ViewModels communicating with each other using messages. I use messages for navigatig to next Page (For this I am using NavigationService.Navigate(), which is Raised from MainPage CodeBehind - it is the only functionality that is in CodeBehind ). View and ViewModels are connected together by setting the DataContext in the Page to ViewModelLocator.
Everythig works at first sight.
But during each navigation, there is created new Page instance, which is connected to the ViewModel from ViewModelLocator(which is designed for it). The result is that: when a user often switches between pages, there are multiple instances of a page connected to one ViewModel. Of course, there is visible only one page at one point.
Very simple solution could be setting NavigationCache, but it is readonly in WP7.
I am looking for solution of unwanted behavior.
Every time you Navigate somewhere a new instance is created for that page.
You could avoid this by using NavigationService.GoBack(); where ever you can.
You should also unregister from every event when navigating away from the page, so that way the garbage collector can clear out that page.
I hope this helps.
You may try to declare an instance of your ViewModel at App.xaml.cs, such as,
private static YourViewModel viewModel = null;
public static YourViewModel ViewModel
{
get
{
// Delay creation of the view model until necessary
if (viewModel == null)
viewModel = ViewModelLocator.MainStatic;
return viewModel;
}
}
Then from the page you will navigate to, you can reference it as App.ViewModel.
If your page is in different assembly form your main application, you could declare following in your App.xaml,
<vm:ViewModelLocator x:Key="VMLocator" />
Where vm referencing to your main app, then you can use is as following,
((ViewModelLocator)Application.Current.Resources["VMLocator"]).YourViewModel;
Hope it would help.

Best Practices GWT Event Handling

I have a question regarding the event handling on client side in GWT.
In our application we have a quite complex structure of different modules and pages which are communicating via the gwt eventbus on client side. Now the amount of events is growing to fast for my opinion. E.g. I am opening a popup I need:
An event for opening the popup
An event for asking some data within the client
An event for getting back the data and fill in the dialog
An event for closing the popup
An event for handling the save Button
Am I thinking a little bit to complicated or missing something in the EventBus implementation? I just wanted to have some feedback out of the community as you are facing the same issues.
For what it's worth, I have lots of events and more growing. And yes, I wonder if I can do with less, but when I skip an event and link elements directly, I regret it.
Here's an example that I just fixed up yesterday. I have a DataGrid widget. I also support re-ordering of columns, hiding of columns, re-sizing columns, and coloring columns with a popup dialog. You click on a configure button, and a popup with the columns listed shows, and the user can click checkboxes to show or hide columns, click on a Move Up / Move Down button to re-order columns, and so on. Hit Apply on the popup and the popup disappears and the DataGrid re-configures.
Except that it didn't. You'd click on Apply and the popup would just sit there, the user would wonder what was going on, the DataGrid would re-configure underneath, and then the popup would go away. We're only talking a short amount of time -- maybe a second or a bit more -- but it was so so noticeable. Why was it happening? Because I got lazy and tied the popup directly to the configure button, and the Apply button directly to the DataGrid. You'd hit Apply, for example, and the call would be made to the DataGrid with the new configuration information. Only when the call returned would the popup would be torn down.
I knew it was bad when I did it, but I was being lazy. So I took the 20 minutes I needed to write up two messages and associated handlers in my mediator singleton. One message is issued by the DataGrid to start the configuration dialog, and one is issued by the popup to configure the DataGrid. Now the widgets are de-coupled, and the performance is much snappier. There is no sense of "stickiness".
Now to your example, can you not combine (1) and (2)? And also (3), (4), and (5)? When the user clicks the configure button on my app, the event carries with it the current configuration information (including a reference to the DataGrid that originated the request). You can call this information the "payload". When the user clicks the Apply button on the popup, the event payload includes all the new configuration information (including a reference to that original target DataGrid) that the event handler feeds to the target DataGrid when the event is handled. Two events -- one to kick off the configuration and one to apply the end result.
Yes there are a plethora of events in any app that does something interesting, but events can carry a lot of information, so I would look at whether your event organization is too fractured.
As a extra bit, here is the code I use. I shamelessly copied elements of this pattern from one of Google's examples.
The user can ask for help using a menu item:
#UiField
MenuItem help;
help.setCommand(new Command() {
#Override
public void execute() {
BagOfState.getInstance().getCommonEventBus().fireEvent(new MenuHelpEvent());
}
});
For the event (in this case, the event fired when the user clicks on the Help menu item):
public class MenuHelpEvent extends GwtEvent<MenuHelpEvent.Handler> {
private static final Type<Handler> TYPE = new Type<Handler>();
public interface Handler extends EventHandler {
void doMenuHelp();
}
#Override
public GwtEvent.Type<Handler> getAssociatedType() {
return TYPE;
}
#Override
protected void dispatch(Handler handler) {
handler.doMenuHelp();
}
public static HandlerRegistration register(EventBus eventBus, Handler handler) {
return eventBus.addHandler(TYPE, handler);
}
}
I have a singleton called Mediator in which ALL events are registered:
MenuHelpEvent.register(BagOfState.getInstance().getCommonEventBus(),
new MenuHelpEvent.Handler() {
#Override
public void doMenuHelp() {
new MenuHelp().execute();
}
});
Every event is mated with a Command object to do the work:
public class MenuHelp implements Command {
#Override
public void execute() {
new InfoMessage(BagOfState.APP_MSG.unimplementedFeatureCaption())
.setTextAndCenter(BagOfState.APP_MSG.unimplementedFeature());
}
}
Everything is decoupled. The menu widget is bound to a command that executes and then completes. The command fires the event on the bus then completes. The event fires off the execution of a Command and the completes. The Command shows the popup help panel (in this case, an "unimplemented" message to the user -- yeah, I'll get to it soon). Every interaction with a user's input is handled extremely quickly and resolves. It can kick off a series of events to perform a long action, but never tying up the GUI to do so. And of course, since the elements are decoupled, I can call the same elements in other places (for instance, call the help Command through a button push as well as a menu item).

GWT Propagate Event on views in activities

How to throw a View event, such click on a button, in view's activity? View doesn't know activity eventBus..
I miss something? I'm using 2.3 sdk
I think the best option is to keep a reference to the Activity in the view and then forward the event to the Activity, which can then use the EventBus in it's own method.
There is a small example on this page:
http://code.google.com/intl/sv-SE/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html
But basically, I usually use #UiHandler to handle the ClickEvent, and then invoke a method in the Activity. In the Activity I then perform the action that uses the EventBus, RPC, or so. I know some people prefer handling the event directly in the Activity but to me this seems like a nicer separation of concern and keeps the View nicely "stupid".
An example:
Button says something like "Select active customer"
View handles ClickEvent for the button, invokes presenter.customerSelected(...)
Activity has customerSelected method and creates a ActiveCustomerSelectedEvent, which is sends on the EventBus.