Bangle.js 2 speedups

Posted on
Page
of 3
Prev
/ 3
Next
  • Maybe it could be another option in the App Loader for now so that it can be turned on for those that are interested?

    That sounds like a good idea.
    But I was also asking because I really don't know enough about Espruino to estimate whether it is likely to have any real impact on top of the pretokenization. But if you think it might I'd be happy to spend some time investigating it.

  • But if you think it might I'd be happy to spend some time investigating it.

    I think there's a good chance. Espruino generally stores and searches for vars more efficiently when they are 4 chars or under long, so even on its own that would help. I don't think the current minifier is smart enough to do constant folding, but if it was that would really help.

    I'm just about to do some tweaks to the app loader anyway, so I'll add this at the same time

  • Ok, just added this to the dev app-loader as a setting. It broke the 'app.settings.js' files because their format meant the JS didn't have side-effects, so I had to do a quick hack to disable that. Otherwise it seems to work ok with the default apps - I'd be interested to see if it stops any from working.

    Quick tip: You can change the setting and then do Reinstall apps to try everything with the changed firmware

    edit: did a quick check with Anton clock and it doesn't appear to make any real difference to speed, but other apps may benefit...

  • Fyi: I'm running 2v15.93 for more then a week now without any noticed problems.

  • I just reinstalled all minimized apps, and so far at least nothing seems to be broken.

  • So I added a bit in https://github.com/espruino/BangleApps/p­ull/2276 but the IDE shows

    Uncaught Clock has no widgets, can't fast load

    Did I do something wrong?

  • You mean for hworldclock itself after the merge? Or in some other clock?

    The fast loading won't work if the clock doesn't have widgets - because it'd have to handle loading widgets for the next app and then somehow handle unloading then when you switched back to the clock.

  • Maybe the clock was manually set before the changes to the boot code and there is no value for settings.clockHasWidgets? In that case setting the clock again in the settings app should help. It seems to work for me.

    Edit: Actually works only once, it seems some more cleanup is needed. The app does not run in a scope and actively only cleans up the timeouts/intervals. So all variables stay globally available and that clashes on reloading the app during const SETTINGSFILE assignment as already existing.

  • You mean for hworldclock itself after the merge?

    yes.

    Actually works only once, it seems some more cleanup is needed

    Bummer, I hoped it was easier. Could you guys help me to tidy up the watchface somehow?
    It might look as I'm a programmer, but most I do is copy&paste (like a senior programmer - but without the background knowledge :) )

  • @Gordon and @halemmerich have given some pointers following comment #63 in the POC-thread. Information on how to declare functions with let to have them cleared on app exit is in comment #48.

    It basically boils down to:

    1. Wrap all your app code inside outer curly brackets: { all app code inside }
    2. Initialize variables with let or const, to utilize garbage collection.
    3. Define functions by: let myfun = function() { ... } instead of function myfun() { ... }, also to utilize garbage collection.
    4. Add to Bangle.setUI: remove : someRemoveFunction
    5. EDIT as per @halemmerich's post below: Clear timeouts/invervals etc in someRemoveFunction in the step above.
    6. Use Bangle.showLauncher(), Bangle.showClock() or Bangle.load() instead of load().

    For now it's generally best to only implement fast switching between clocks and launchers, and not for launching other apps or switching between them.

    There're also instructions going into the hardware reference here following line 5171.

    Examples where it's implemented: Slope clock, Desktop Launcher.

    EDIT: Using the RAM Widget have helped me during development. @Gordon has also suggested entering process.memory().usage into the console field of the Web IDE to get precise measurements. See @halemmerich tips below as well.

  • Edit: Removed duplication with @Ganblejs earlier post.

    • Check for any watches, timeouts, intervals that might survive the removal of the app and clear them in remove.
    • If code running in timeouts or intervals needs access to variables you might need to move them out of the block into the global scope. Those must then explicitly be deleted during remove.

    I use the following uploaded to RAM to do a smoke test for memory leaks:

    let app = "launch.app.js";
    
    print("Initally load app", process.memory().free);
    Bangle.load(app)
    
    setInterval(()=>{
      print("Reload app with free", process.memory().free);
      Bangle.load(app);
    },1000);
    

    This code loads the app over and over. It usually settles in after 1 or 2 iterations and does not change a lot after that with most apps. This will not cover all cases, but it should give you a start. As usual, do changes piece by piece and test between steps.

  • Thanks for those suggestions.
    Implemented most of them here

    Though, I am still not sure with the variables as I use some of them globally, so I use var instead of let. What's the best practice on that?
    (Sorry, I don't want to hijack this conversation for noob programming questions)

  • I have found two apps breaking with the new minification switch: imageclock and gpstrek.

    Imageclock breaks because the code generated by the customizer (and evaled in the app) references things that have been renamed by the minifier. What is the best way around this? Defining those globally and deleting them on remove?

    In gpstrek the minifier generates code like for (let a of a.getPoints()) { which not surprisingly results in Uncaught Error: Cannot read property 'getPoints' of undefined. a is a function parameter in this case before getting redefined in the for loop.

    Edit: During experimenting with iconlaunch the minifier generated a constant named g into a block of code calling Bangle.load which in turn calls g.reset(). That then fails because of the minifier-generated constant.

  • Hmm, ok. Maybe start a new thread for minifier problems?

    Imageclock references things that have been renamed by the minifier.

    I think there are 3 options?

    • ensure they were global
    • save your file as app.min.js in BangleApps even though it's not minified, and then the minifier won't touch it (I think)
    • In custom.html, merge all of imageclock.draw.js into imageclock.app.js - and then it'll all get minified together and should end up faster.

    for (let a of a.getPoints())

    It looks like a minifier bug? a = [3,4,5]; for (let a of a) console.log(a); fails in Node.js too so it's not a problem with Espruino not being spec compliant.

    the minifier generated a constant named g into a block of code calling Bangle.load which in turn calls g.reset()

    That feels like another minifier bug?

    I'd be interested to know what speed improvements you're seeing, because if it's not that much I wonder whether we should just consider not using minification.

  • hello, i have the same problem with iconlaunch and rebble.
    rebble I know it's a mess and should be fixed as suggested by @Ganblejs but,

    @Gordon

    The fast loading won't work if the clock doesn't have widgets

    does this mean that the fastload ( Bangle.showClock() ) will never work with full screen clocks?
    and if so, how does the launcher know which load to use to avoid problems?

    sorry in advance if I misunderstood

  • does this mean that the fastload ( Bangle.showClock() ) will never work with full screen clocks?

    Yes.

    how does the launcher know which load to use to avoid problems?

    with this code: https://github.com/espruino/BangleApps/c­ommit/779b16b67177cf8096f304113773acae8d­6d38d0

  • Just a note on this - I made a few more changes that squeezed another 10% or so performance boost out of the external flash.

    So I'm pretty pleased with where we are now:

    Bangle.js 2v15 - factory default firmware. Boot to watch via load() -> 600ms
    Bangle.js 2v16.6 - factory default firmware. Boot to watch via load() -> 340ms
    Bangle.js 2v16.6 - factory default firmware. Boot to watch via Bangle.load() (eg via launcher) -> 180ms

    So we're almost twice as fast normally, and then around 3.5x faster when swapping to/from the launcher!

  • Wow, very nice - impressive improvement!

  • Those are some really great numbers, definitely easy to see in daily use.

    The not yet fast load compatible clocks could be changed to loading widgets and then directly hiding them using widget_utils without ever drawing. That would be enough for fast loading them and would not disturb the full screen watch face. But it comes with the caveat that then the widgets are loaded to RAM and active. Especially their registered listeners do their thing and could for example react to touches or do whatever they usually do when visible.

  • The not yet fast load compatible clocks could be changed to loading widgets and then directly hiding them using widget_utils without ever drawing.

    Yes... Personally now 2v16 has overlays that can go offscreen I'd like to see as many watches as possible load the widgets and then put them offscreen so a downwards swipe would show them.

    I'll see about extending widget_utils to make that possible + easy

  • I would like to second what you're saying @Gordon. The swipe launcher should avoid the downward swipe as well.

  • Do you mean Quick Launch? Maybe the swipe down action should be remapped to act on duoble down swipes instead. I'll probably do a PR for that.

  • Quicklaunch: Please make it configurable, I would like to keep single down swipes.

    Also I would like the widgets to stay always visible on Anton Clock Plus.

  • Actually, Quicklaunch might already have it, simply because you just make it do nothing with single down swipes? Perhaps.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Bangle.js 2 speedups

Posted by Avatar for Gordon @Gordon

Actions