OH3: to use or not to use JS (ECMAscript 2021)

As already pointed out, Blockly generates old ECMAScript 5.1 code and without usage of any helper libraries which leads to not the cleanest code.
But: Work is ongoing to make Blockly generate ECMAScript 2021/JS Scripting code.

That was normal until a few days ago, because the injection of the openHAB JavaScript library, that provides easy access to openHAB APIs, takes some time due to its relatively large codebase.
I have implemented a caching mechanism to improve injection speed (13 seconds without caching and 2 seconds with caching on my Pi 3), see [jsscripting] Cache openhab-js injection to improve performance by florian-h05 · Pull Request #14135 · openhab/openhab-addons · GitHub. This enhancement is coming with openHAB 4.

2 Likes

Thanks for the info. Is there something like a language specification, where functions like parseFloat() are described?

Hi Florian,

and on Github you wrote

the code needs to be evaluated once before it is cached.

what does that mean in detail? Is it your code which needs to be evaluated to be cached or is it our rule that needs to be evaluated to be cached?
The performance increase you measured was done on a freshly started oh-instance?

See JavaScript | MDN or JavaScript Tutorial.

The injection of the openHAB JavaScript library is cached by default (you can disable this to use a version from the node_modules folder). As a user, you don’t have to do anything to have the caching work.
When openHAB starts, the library code is loaded and then it‘s injection is evaluated once by the first JS script to run. All JS scripts that run after this initial run take advantage of the cached version, but the very first run after an openHAB start will take longer than the subsequent ones.

The performance increased I measured was on two dev systems, that were started at some time and then I performed the tests. As already mentioned, the first script to run after openHAB or addon Start takes a bit longer than the following ones because the cache is not initialized yet.

1 Like

Ok. This means we better create a „startup“ rule with zero content to force the injection being evaluated to avoid the first rule being delayed?

Yes, would be an option.
I don’t know how long the first evaluation takes on your system and whether that’s something annoying for the first rule to run, but if you want to create a „startup“ rule, I would recommend to put a .js file inside automation/js with e.g. console.log(„JS Scripting cache initialised“); as content.

I have updated today to OH3.4.1 and also updated JS scripting (openhabian-config → Openhab related → Install openhab-js). Now compilation takes even almost one minute on my Pi3. This is too much. Can I do anything about it? Can I downgrade?

2023-01-09 14:28:29.036 [INFO ] [openhab.event.RuleUpdatedEvent      ] - Rule '517365d010' has been updated.
2023-01-09 14:29:24.649 [ERROR] [b.automation.script.javascript.stack] - Failed to execute script:

Why have you upgrade openhab-js? I guess that’s the reason why compilation time increased, because the version in the file system is in a different format than the included version.
I’d recommend to run the openHABian-config → openHAB related → Uninstall openhab-js option.

I need previousStateTimestamp() what is missing in OH3.4. Is there workaround not to use previousStateTimestamp ?

https://openhab.github.io/openhab-js/items.ItemHistory.html#previousStateTimestamp

This is what I have done now, but compilation time is still about 50s. Can it be caused by OH3.4.1 ?
I’m getting this error message again, as previousStateTimestamp() is not available now. Any proposal? Thanks!

org.graalvm.polyglot.PolyglotException: TypeError: itemEnergyReading.history.previousStateTimestamp is not a function

If you need it, it is available in newer versions.

No. openHAB 3.4.1 has absolutely NO changes in JS Scripting.
What’s the problem with „compilation“ takes about 50s? This is required once, after then the scripts run immediate. Anyway, I am wondering why the evaluation time increased from 15s to 50s. On my Pi it is 15s. The only one who knows what changed on your system is you, I can only tell you that openHAB 3.4.1 changed nothing at JS Scripting.

You have three options if you want higher speed:

  • Switch to a more powerful system
  • Disable the use of the built-in variables and manually import the required openHAB JavaScript library APIs (not sure if that really helps, just an idea)
  • Wait for openHAB 4

I have a compilation time of JS scripts of about 30s in OH4 on a Raspberry Pi 3. Is this ok? I think you have implemented some caching which reduces it to 2s?

Yes, I implemented caching of the library injection in [jsscripting] Cache openhab-js injection to improve performance by florian-h05 · Pull Request #14135 · openhab/openhab-addons · GitHub, and as reported in the PR, I measured some nice performance improvements.
However it seems that those performance improvements are not as reproducible as we all wish.
After we had some problems where first evaluation of a script took longer with caching than without, I was able to fix that and @stefan.hoehn verified that caching helps.

What I really do not understand is, why compilation time is that different on systems that we think are the same. Can you please disable caching of the library injection and then measure compilation time? And which openHAB version are you using exactly?

Something we also found out that seems to be relevant, is 32/64-bit. It seems that GraalJS performs much better on 64-bit JDKs than on 32-bit, but this has to be verified by some more testing.

Please note that the compilation time is only a problem for UI-based rules/scripts at all.
For file-based rules, those files are loaded on openHAB startup or on file change, and therefore there is no compilation time on the first run of a rule.

I have done some performance tests on my Raspberry 3 with this script on openHAB 4.0.4.
Whenever I trigger a recompile by adding spaces to the script it takes 30-35s compilation time.
For development of new scripts this is pretty annoying as you always need to wait.
How can I disable the caching?

var item = items.getItem('ITEM');
console.info("Performance Test", item.name); 

It’s the second options in the addon settings.

I understand that you are set on jsscripting. I’m just curious how JRuby performs on an rpi 3, as I’ve never tested it and I cannot locate my rpi3. Would you mind doing a quick install test and uninstall?

The equivalent code is

item = items["ITEM"]
logger.info("Ruby test #{item.name}")

Do you mean this option?

This does not really make any difference in compilation time.

JRuby compilation took first time 25s, all next times 8s.
Interesting, faster than JS.