Titanium: ScrollView loads slowly - ios

I'm having some problems with how long a Titanium app I am making
takes to load a ScrollView.
Titanium SDK: 3.3.0.GA
I decided to run a test, comparing how long it would take for a titanium app
to load a similar view, and a native built version (iOS).
The test was loading 1000 textfields into a ScrollView.
For the natively built app, it took about 0.850 seconds to load
on an iPad mini (based on 3 trials).
For the titanium built app, it took about 59.3 seconds to load
on the same iPad mini (based on 3 trials).
Obviously, this is a significant difference. My code for the
Titanium build is below. Is there something I'm missing? Some option that
is making the ScrollView so slow?
59 seconds compared to 0.850 is pretty significant.
index.xml
<Alloy>
<Window class="container" >
<ScrollView id="scrollView" layout="vertical"></ScrollView>
</Window>
</Alloy>
index.tss
".container": {
backgroundColor:"white"
}
index.js
var startTime = new Date();
startTime = startTime.getTime() / 1000;
$.index.addEventListener('postlayout', calculateTimeToLoad);
loadThousandTextFields();
function calculateTimeToLoad() {
$.index.removeEventListener('postlayout',calculateTimeToLoad);
var endTime = new Date();
endTime = endTime.getTime() / 1000.0;
Ti.API.info("Total time taken:" + (endTime - startTime) + " seconds");
}
function loadThousandTextFields() {
for(var i = 0; i < 1000; i++) {
$.scrollView.add(Ti.UI.createTextField({
hintText: "Hint text"
}));
}
}
$.index.open();
Note: I am aware of Titanium's ListView, however, based on my experiments with it, it looks like it won't
work too well with the app I am making, as I need interaction between my various components and the ability to change
them based on that interaction. (For example, having a switch that, upon being turn off, would
clear a nearby textfield, or fill it with some text. ListViews seem to be very slow in updating views like that. If I'm wrong, please let me know).
Further Note: I tried running the same test on titanium sdk 3.2.3, and it took about 6 seconds as opposed to 59, on the same iPad mini. However, in the app that I am making, the scrollview actually took longer to load.
Thanks

In Mobile Application development. You have always remember Use low Memory or need to always clear unused memory.
Here you add approx 1000 textView at a time. That's why. your app going slow.
Please you try this Reference. In this example. when you scroll you table view then it will add next some row. and this will adding one by one according your display.
Example :- https://gist.github.com/mschmulen/805283

Related

How to scroll the page in Appium + Python

I create tests using Appium+Python to test IOs app.
I want to scroll the page.
Here is the code
def scroll_page(self):
action = TouchAction(self)
action.press(BrowsePageElements.firs_element_to_scroll(self)).
move_to(BrowsePageElements.second_element_to_scroll(self)).perform()
When I'm trying to run this function, I get an error
error screenshot
Could you help me to find out, how to fix this error?
Appium Python has a native scroll function. It works for both Android and iOS.
driver.scroll(origin_el, destination_el, duration=None), where duration is an optional argument. This function scrolls origin_el to the location of destination_el.
Link to scroll source code
The Appium documentation is rather spotty and needs updating. However, the source code is documented well enough to understand and learn the program.
This currently works for me:
...
SCROLL_DUR_MS = 3000
...
window_size = self.driver.get_window_size()
self.scroll_y_top = window_size['height'] * 0.2
self.scroll_y_bottom = window_size['height'] * 0.8
self.scroll_x = window_size['width'] * 0.5
...
def scroll_up(self):
self._y_scroll(self.scroll_y_top, self.scroll_y_bottom)
def scroll_down(self):
self._y_scroll(self.scroll_y_bottom, self.scroll_y_top)
def _y_scroll(self, y_start, y_end):
actions = TouchAction(self.driver)
actions.long_press(None, self.scroll_x, y_start, SCROLL_DUR_MS)
actions.move_to(None, self.scroll_x, y_end)
actions.perform()
It scrolls slowly over 3s because I want it to be controlled, but you could shorten SCROLL_DUR_MS (the duration of the scroll action in milliseconds) if you want something more zoomy. I also went away from using elements as the start and/or end points because I wanted something general that would work with any screen content.
For scroll_y_top and scroll_y_bottom I picked 20% in from the top and bottom of the screen just to make sure I wasn't hitting anything at the borders (like the navigation bar at the top of iOS Preferences or an info bar at the bottom of the app I was working in). I also ran into a "bug" where it wasn't scrolling when I left scroll_x as 0, but it turns out that it wasn't registering the left edge as inside the scrolling area for the app I was working in.
Hope this helps.
In the past when i've run into issues scrolling for one reason or another, I've simply swiped using coordinates to scroll down the page.
self.driver.swipe(100, 700, 100, 150)

Appium: How to wait for new element with same name as visible one to appear on screen?

We're using Appium with iOS Simulator and test functions written in Java.
We have an iOS App with screen 1 containing a UICollection view, and tell Appium to click on one of its elements.
This opens screen 2 (and the scrolling animation takes about 500 ms), which also contains an UICollection view. I want to find out the size of the UICollection view of the second screen with Appium.
The problem is that Appium is too fast and executes the findElements() method directly after the click, which causes it to find the UICollection view of the first screen.
clickOnElementOnFirstScreen();
webDriver.findElements( By.className( "UIACollectionCell" ) ).size();
// is supposed to find the UICollection view on the second screen,
// but actually finds the UICollection view on the first screen
Appium provides several waiting functions. However as far as I can see all of them are intended to be used in this fashion:
"wait until element at location X / with name X becomes visible"
If I try to use these waiting functions, they don't wait at all because they immediately find the UICollection view of the first screen, which has the same location and name as the one on the second screen.
The only solution I have found is to use Thread.sleep:
Thread.sleep(1000);
webDriver.findElements( By.className( "UIACollectionCell" ) ).size();
But we don't want to use Thread.sleep in code that will run on the client's server on hundreds of tests.
We might be able to modify the App and enter metadata into the views so that Appium is able to distinguish them, but this situation occurs in several places and the App is being programmed by the client, so we want to avoid this too.
What is a simple and safe way to wait for the new screen to appear, without modifying the code of the iOS App?
I have found only dirty workaround for this issue.
static waitFor(Duration duration) {
try {
def WebDriverWait wait = new WebDriverWait(mobileDriver, duration.standardSeconds)
wait.until(visibilityOfElementLocated(By.xpath("//Fail")))
//Wait until false case is visible to ensure proper timeout
} catch (Exception e) {
}
}
Another workaround/solution that has been posted on the Appium forums is:
First search for some other element that distinguishes the 2. screen from the 1. screen; once that is visible, it's safe to search for the originally desired element.

kinetic js crash on resize ipad

I use this code to resize the stage. On desktop everything is fine but the Ipad safari and chrome crashes. I tried to delete some other stuff and figured at that it can only be the resize that forces the crash. Strange allthough that this code worked a while ago and I was very surprised that it doesn't now. Anyone got an idea or maybe another method of resizing?
Thanks in advance
window.onresize = function(event) {
stage.setWidth(window.innerWidth);
stage.setHeight(window.innerHeight);
stage.draw();
}
The problem is that you're triggering stage.draw() hundreds of times per second. KineticJS v4.5.5 will resolve this problem with the stage.batchDraw() method, which hooks draws into the animation engine for performance. This way, if you call stage.batchDraw() hundreds of times per second via mousemove, the stage will only get drawn about 60 times per second.
It might be because the iPad doesn't support innerWidth and innerHeight (I know not all mobile devices support it), so your code could be crashing by trying to set the stage width and height to an undefined number.
You'll have to use an alternative to setting the stage to the screen size.
You could try something like:
if (window.innerWidth) {
width = window.innerWidth;
height = window.innerHeight;
} else {
width = screen.width;
height = screen.height;
}
If this doesn't work for you, you'll have to look into other ways to handle different screen dimensions. I came across this article a while back: http://tripleodeon.com/2011/12/first-understand-your-screen/

iPhone Simulator suddenly started running very slow

I have been working on an app in iphone simulator for a number of weeks and it has been running well up until now, but all of a sudden has begun running very slow both when loading content and animations. I have not made any changes to my code since I last tested it successfully.
I tried restarting the simulator (multiple times) and removing the app and doing a completely clean rebuild, but no luck. I also checked my cpu usage through the monitor while the simulator is running and I am only using about 30% of my cpu and 40% of memory.
I fully understand that the simulator is never a quick as the device itself, but it seems strange that it has suddenly started running slow after such a long time, and by slow I mean less than a quarter of its original speed.
In the iOS simulator, at the bar on the top, click on Debug → Toggle Slow Animations (or Slow Animations with Xcode 10+). Chances are you accidentally toggled it on.
Simple Command + T will fix this problem.
Command + T toggles the simulator's Slow Animations, which can be found under the Simulator Menu: Debug -> Slow Animations.
Go to the simulator's Debug menu and select "Toggle Slow Animations".
Update: In Xcode 10, it's just "Slow Animations":
Select Simulator,
Select Debug and uncheck slow animation.
shortcut
command + t
That's work for me.
If the Cmd-T (slow animations) option doesn't work for you and Debug -> Slow Animations is off but you still have slow animations try Simulator -> Reset Contents and Settings (or possibly Hardware -> Erase All Content and Settings). That worked for me when none of the other answers in here did. Anyone have a suggestion as to why?
Also having a debugger attached (at all) may make the animations very slow.
Another potential fix for React-Native users:
Chrome de-prioritizes Javascript running in any tabs not in the foreground. So if you have enabled remote debugging, be sure to put the debugger in its own window.
You accidentally pressed the slow animation on debug when using simulator.
So Run Simulator -> Debug -> Uncheck Slow Animation.
I think you pressed command + T instead of command + R by mistake.
I don't have the rep yet to leave a comment, but I upvoted some answers here and wanted to say more. I had a problem with slow animations in the iOS Simulator, especially on rotation, and I found this post via Google. Indeed, somehow "Toggle Slow Animations" must have been on, because three shifts fixed it. At first, I didn't think this was a problem because there's no checkmark next to "Toggle Slow Animations." It turns out there's never a checkmark, or any indication from the menu whether it's on or off. So just try toggling it and see if the rotation/navigation is faster/slower.
So, thank you!
Simulator -> Reset contents and settings works for me. The issue seems to reappear when I debug my react-native code remotely. It could also be to do with AsyncStorage as nomad suggested.
It is NOT only about slow animations. Xcode simulator has extremely low performance in global. It is Apple's bug. I have reported it via Feedback Assistant. I have created demo with code demonstrating that simulator is 200 times slower than any old real device. I have found that JavaScript code with Date object executed in WKWebView is pain for simulator. Changing options in simulator does not help in my case. See jsfiddle https://jsfiddle.net/kjms16cw/ I hope Apple will fix it soon!
var log = document.getElementById("log");
document.getElementById("button").onclick = function() { run(); };
function run() {
var d1 = new Date();
for (var i = 0; i < 1000; i++) {
var x = new Date();
x.setMilliseconds(0);
x.setSeconds(0);
x.setMinutes(0);
}
var d2 = new Date();
log.innerHTML = ((d2.getTime() - d1.getTime()) / 1000) + " seconds";
}
<h3>Xcode Simulator Extremely Low Performance</h3>
<p>This test runs fast (several tens milliseconds e.g. 30 ms)
in any browser any device any platform including very old iOS device
e.g. iPhone 5C and several years old iPad 2, BUT IN SIMULATOR IT TAKES 6000 ms
(yes, 6 seconds!). Terrible!</p>
<button id="button">run()</button>
<div id="log"></div>
You can try to turn off remote debugging (Cmd-D -> Stop Remote JS Debugging). That usually speed things up.
When the chrome debug is active and the browser tab is not in the foreground, the emulator is slow too. For me, I decided to put the guide in the foreground.
Go to menu of simulator
Device -> Restart
Then everything faster than you think -_-

iPad parallax flickering

I am using a parallax effect with javascript but I'm having issues with iPad.
I know the "$(window).scroll" is not triggered on webkit touch devides - only when we release the screen - so i'm using:
window.addEventListener("touchmove", triggerScroll, false);
function triggerScroll(event)
{
var scrollTop = $(window).scrollTop();//event.touches[0].pageY; //window.pageYOffset();
$("#allCanvas .divCanvas").each(function(index, element) {
var speed = $(element).data('speed');
var initialTop = $(element).data('initialtop');
$(element).css('top', initialTop-(scrollTop*speed));
});
}
The problem is that it flickers the .divCancas a few pixels to the top or bottom depending if I'm scrolling to top or down.
I tracked the TOP value passed on $(element).css('top', initialTop-(scrollTop*speed)); and it's every time correct. The correct "TOP" value, eventhough webkit move it for a few milleseconds to the wrong position.
I tried also:
-"margin-top" rather than "top" with no difference.
-Removing all other objects and making the ".each" loop through only one div, so I guess is not a jQuery performance issue.
Has anyone came across this problem?
Many thanks
Diego
Maybe try using some of the -webkit css animation features... these run very smoothly on iOS devices. Here's a great demo of that (webkit only): http://jibjub.com/demo/HTML5/cube.html

Resources