What could cause .wasm to load images so slowly? - uno-platform

In my Uno test project, it takes about 4 seconds to load 50 images into an ItemsWrapGrid on the UWP platform. The same images take 225 seconds (3 minute 45 seconds) to load into a WrapPanel. Since the only difference in the code is ItemsWrapGrid or WrapPanel, I'm thinking the problem is the WrapPanel, but I can't be sure, it could be in how the platforms implement the <Image ItemsSource=""/.
I don't have any experience with .wasm so I don't know if this is expected (is it?). Is there something I can do to Optimize for wasm?
or any other thoughts? 4- minutes is just not acceptable compared to about 4 seconds.
Thanks
Thanks for asking if I could repro in Uno Playground. I was unaware of the site.
I was NOT ABLE to repro on the playground, which led me to investigate other possibilities.
I have resolved the issue.
My design pattern was to define a single ObservableCollection without a property change notification:
public ObservableCollection<PictureViewModel> Pictures {get;set }
I would bind that to my UserControl and update by Pictures.Clear().
This is my snippet that resulted in the long render time:
List<Picture> PictList = await DataService.GetPicturesByEvent(this.SelectedEvent.EvtKey, clubkey, skipPosition, this.PagingViewModel.PageSize);
List<PictureViewModel> PictVMList = mapper.Map<List<Picture>, List<PictureViewModel>>(PictList);
if (PictVMList != null && this.SelectedEvent != null && !string.IsNullOrEmpty(SelectedEvent.FilePath))
{
this.Pictures.Clear();
foreach (PictureViewModel item in PictVMList)
{
item.Parent = this;
item.SetURL(SelectedEvent);
this.Pictures.Add(item);
}
this.SelectedPicture = PictVMList.Count > 0 ? PictVMList.First() : null;
}
To resolve the long render time. I:
Made my ObservableCollection observable.
Removed all instances of Picture.Clear();
Created a new ObservableCollection whenever it needed updating.
The Resolved code snippet is:
List<Picture> PictList = await DataService.GetPicturesByEvent(this.SelectedEvent.EvtKey, clubkey, skipPosition, this.PagingViewModel.PageSize);
List<PictureViewModel> PictVMList = mapper.Map<List<Picture>, List<PictureViewModel>>(PictList);
if (PictVMList != null && this.SelectedEvent != null && !string.IsNullOrEmpty(SelectedEvent.FilePath))
{
foreach (PictureViewModel item in PictVMList)
{
item.Parent = this;
item.SetURL(SelectedEvent);
}
this.SelectedPicture = PictVMList.Count > 0 ? PictVMList.First() : null;
}
Pictures = new ObservableCollection<PictureViewModel>(PictVMList);
I don't understand why my initial code pattern did not work as expected, but can live with adding an OnPropertyChanged("Pictures") notification.

As of Uno 3.10, ItemWrapGrid is not supported on WebAssembly. Using the WrapPanel control will force the materialization of all the items in the list, making the performance particularly slow.
You're not specifying which control you're using as a panel, but if you're using a ListView control, the virtualization will be enabled, though not with the layout wrapping that you need.
If you want virtualizing grid-like layouts, you can also use the ItemsRepeater control, and its layouts (e.g. FlowLayout, StackLayout, or WCT's WrapLayout).

Related

Find broken images in page & image replace by another image

Hi I am using selenium webdriver 2.25.0 & faceing the some serious issues,
how to find broken images in a page using Selenium Webdriver
How to find the image is replace by another image having same name (This is also bug) using webdriver.
Thanks in advance for your value-able suggestions.
The accepted answer requires that you use a proxy with an extra call to each image to determine if the images are broken or not.
Fortunately, there is another way you can do this using only javascript (I'm using Ruby, but you can use the same code in any executeScript method across the WebDriver bindings):
images = #driver.find_elements(:tag_name => "img")
broken_images = images.reject do |image|
#driver.execute_script("return arguments[0].complete && typeof arguments[0].naturalWidth != \"undefined\" && arguments[0].naturalWidth > 0", image)
end
# broken_images now has an array of any images on the page with broken links
# and we want to ensure that it doesn't have any items
assert broken_images.empty?
To your other question, I would recommend just taking a screenshot of the page and having a human manually verify the resulting screenshot has the correct images. Computers can do the automation work, but humans do have to check and verify its results from time to time :)
The next lines are not optimized, but they could find broken images:
List<WebElement> imagesList = _driver.findElements(By.tagName("img"));
for (WebElement image : imagesList)
{
HttpResponse response = new DefaultHttpClient().execute(new HttpGet(image.getAttribute("src");));
if (response.getStatusLine().getStatusCode() != 200)
// Do whatever you want with broken images
}
Regarding your second issue, I think I didn't understand it correctly. Could you explain it with more detail?
Based on the other answers, the code that eventually worked for me in an angular / protractor / webdriverjs setting is:
it('should find all images', function () {
var allImgElts = element.all(by.tagName('img'));
browser.executeAsyncScript(function (callback) {
var imgs = document.getElementsByTagName('img'),
loaded = 0;
for (var i = 0; i < imgs.length; i++) {
if (imgs[i].naturalWidth > 0) {
loaded = loaded + 1;
};
};
callback(loaded);
}).then(function (loadedImagesCount) {
expect(loadedImagesCount).toBe(allImgElts.count());
});
});
The webdriver code counts the number of img elements, and the function executed within the browser context counts the number of successfully loaded elements. These numbers should be the same.

InDesign SDK : Drag'n'Drop from a Flex Panel

I have a Flex panel, in InDesign, from which I drag an URL. If I drop this URL on a text editor or a web browser, it works. But when I try to drop it on my InDesign document, it's a little bit harder.
I have implemented a subclass of CDragDropTargetFlavorHelper. The drop works perfectly on Windows. But on mac, I have problems in the method CouldAcceptTypes :
DragDrop::TargetResponse AutocatDNDCustomFlavorHelper::CouldAcceptTypes(const DragDropTarget* target, DataObjectIterator* dataIter, const IDragDropSource* fromSource, const IDragDropController* controller) const
{
if (0 != dataIter && 0 != target)
{
DataExchangeResponse response = dataIter->FlavorExistsWithPriorityInAllObjects(kURLDExternalFlavor);
if (response.CanDo())
{
...
}
}
}
The problem is that response.canDo() answers kTrue on Windows, but kFalse on Mac. I tried to explore the content of dataIter, but a call on dataIter->First() returns nil. I tried a controller->GetItemCount(), which returns 1. But if I try a controller->GetDragItem(1), I get a nil pointer. I have the impress there is no item. Though, the drop works on another app than InDesign, as I said.
Is it a problem of internalization ? Or something else ? It let me dry.
Thanks in advance
-------------------------- EDIT -----------------------------------
I solved this problem, but discovered another one. The flavor sent by the flex panel has been changed, so that it's a text flavor instead of an URL flavor. My method couldAcceptType works now :
DragDrop::TargetResponse AutocatDNDCustomFlavorHelper::CouldAcceptTypes(const DragDropTarget* target, DataObjectIterator* dataIter, const IDragDropSource* fromSource, const IDragDropController* controller) const
{
if (0 != dataIter && 0 != target)
{
// Check for URL Flavor in the drag
DataExchangeResponse response = dataIter->FlavorExistsWithPriorityInAllObjects(kTEXTExternalFlavor);
if (response.CanDo())
{
return DragDrop::TargetResponse(response, DragDrop::kDropWillCopy);
}
}
return DragDrop::kWontAcceptTargetResponse;
}
The problem is now in the ProcessDragDropCommand method. Here is the code :
ErrorCode AutocatDNDCustomFlavorHelper::ProcessDragDropCommand(IDragDropTarget* target, IDragDropController* controller, DragDrop::eCommandType action)
{
// retrieve drop data
IPMDataObject* dragDataObject = controller->GetDragItem(1);
uint32 dataSize = dragDataObject->GetSizeOfFlavorData(kTEXTExternalFlavor) ;
...
}
The problem is the IMPDataObject I get is nil. There is no item in the controller. However, there were items in the CouldAcceptTypes method, in the DataObjectIterator. So, where are my items ?
I tried using a custom CDataExchangeHandlerFor, but could not really understand what its usage was for. It didn't work anyway.
Has anyone an idea ?
Regards,
RĂ©mi
The problem is the argument of the GetDragItem. It is 1 on PC. It is a strange value on Mac (something like 719853). The only dirty solution I found is doing a memcpy from the object retrieved drom the dataIter in the CouldAcceptTypes method, and use it in the ProcessDragDropCommand method.

Creating Flex Elements Server Side

i wonder if it is possible to pre-configurate Flex Elements on the Server. I have the Problem with a custom ItemRenderer which turns out to be very slow. It would be very cool to pre-process such an element on the server instead in the clients browser... somehow? Maybe it is possible to produce the MXML dynamically on the server for that.
This is it basically. I create a Label for each data entry in an array list. This entry is added to a BorderContainer and this goes to the containing element as a whole here. Sometimes i add 200 - 300 items this way which is costing very high computing cost at client side. So i wonderd if i could just pass this as a whole dynamic mxml element to the client.
override public function set data(value:Object):void {
_data = value as WordResultObject;
var data:WordResultObject = _data as WordResultObject;
this.removeAllElements();
if(_data!=null)
{
_l.text = data.wordform;
_l.setStyle("fontSize", data.fontSize);
_l.setStyle("color", data.color);
_l.toolTip = "Frequency: " + data.freq;
if(data.date != null)
{
_l.toolTip += "\nDate: " + AppUtils.TimeString(data.date as Date);
_l.addClickEvent(data.id as int, data.date as Date);
}
_border.addElement(_l);
this.addElement(_border);
}
}
Thank you
Andreas
I wonder if it is possible to
pre-configurate Flex Elements on the
Server.
Not that I know of. Perhaps if you go back to Flex 1 / 1.5 which was primarily a server based platform. I do not expect rolling your code back to an "old" server would improve efficiency at all, though. How would you expect this work? What benefit are you expecting to receive.
I have the Problem with a custom
ItemRenderer which turns out to be
very slow.
Show your code; and perhaps we can help you with writing your renderer to be more efficient.

Resetting target values in a composite effect

We need to be able to handle a "playable" (play/pause/seek) effect in which the nature of the effect cannot be determined at compile time.
The problem we are running into is resetting the target(s) state after the effect has completed. If we manually drag the seek slider back to the beginning, everything works fine. However, if we set the playheadTime of the composite effect back to 0, the effected targets retain their original value until the playheadTime gets to the correct position to effect the target.
Here is a simplified (as much as I could) test case with view source enabled:
http://www.openbaseinteractive.com/_tmp/PlayableEffectTest/
The problem is demonstrated if you let it play to the end, and then hit the play button to start it over.
What is the best way to go about manually resetting the target values given that the exact nature of the effect is unknown?
Many thanks for your time!
edit
I forgot to mention we are using Flex 4.5 preview release.
Have you tried:
effect.reverse()
More info
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/effects/IEffect.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/effects/IEffect.html#reverse()
Well it's a little kludgy, but I was able to accomplish this by calling some internal methods on the effect to capture the start values, then assigned those values to the targets on a reset.
import mx.core.mx_internal;
use namespace mx_internal;
private var _propertyChangesArray:Array;
protected function captureStartValues(effect:Object):void
{
effect.captureStartValues();
_propertyChangesArray = effect.propertyChangesArray;
}
protected function reset(effect:Object):void
{
for each(var change:PropertyChanges in _propertyChangesArray)
{
var target:Object = change.target;
for(var p:String in change.start)
{
if(target.hasOwnProperty(p))
{
var startVal:* = change.start[p];
var endVal:* = target[p];
if(!isNaN(startVal) && startVal != endVal)
{
target[p] = startVal;
}
}
}
}
effect.playheadTime = 0;
}
I don't know if this is the best way to accomplish this, but it seems to be working so far. I am absolutely open to suggestions for a better method.
Cheers!

Process Lock Code Illustration Needed

I recently started this question in another thread (to which Reed Copsey
graciously responded) but I don't feel I framed the question well.
At the core of my question, I would like an illustration of how to gain
access to data AS it is being get/set.
I have Page.aspx.cs and, in the codebehind, I have a loop:
List<ServerVariable> files = new List<ServerVariable>();
for (i = 0; i <= Request.Files.Count - 1; i++)
{
m_objFile = Request.Files[i];
m_strFileName = m_objFile.FileName;
m_strFileName = Path.GetFileName(m_strFileName);
files.Add(new ServerVariable(i.ToString(),
this.m_strFileName, "0"));
}
//CODE TO COPY A FILE FOR UPLOAD TO THE
//WEB SERVER
//WHEN THE UPLOAD IS DONE, SET THE ITEM TO
//COMPLETED
int index = files.FindIndex(p => p.Completed == "0");
files[index] = new ServerVariable(i.ToString(),
this.m_strFileName, "1");
The "ServerVariable" type gets and sets ID, File, and Completed.
Now, I need to show the user the file upload "progress" (in effect,
the time between when the loop adds the ServerVariable item to the
list to when the Completed status changes from 0 to 1.
Now, I have a web service method "GetStatus()" that I would like to
use to return the files list (created above) as a JSON string (via
JQuery). Files with a completed status of 0 are still in progress,
files with a 1 are done.
MY QUESTION IS - what does the code inside GetStatus() look like? How
do I query List **as* it is being populated and
return the results real-time? I have been advised that I need to lock
the working process (setting the ServerVariable data) while I query
the values returned in GetStatus() and then unlock that same process?
If I have explained myself well, I'd appreciate a code illustration of
the logic in GetStatus().
Thanks for reading.
Have a look at this link about multi threading locks.
You need to lock the object in both read and write.

Resources