My understanding is that the portable executable extracts the application to a temp folder to run it.
The problem I have is that the users are stuck waiting for the extraction process before they see the application has launched. The process is rather fast on my flash PC with its SSD and ridiculous CPU clock speeds but when you start running on a PC that is still running a 3rd Gen i3 CPU and HDD that's equally as old, you find that people are impatient and often end up opening the executable 4-5 times before the initial one opens.
Therefore, my proposal is that there be an option to include a splash screen/image that shows when the portable application executable is opened to indicate that something is actually happening in the background.
Instead of splash screen, we _should_ use ZSTD instead of LZMA2 compression.
+1
Upcoming electron-builder versions allows you to use ZIP compression, so, decompression will be very fast.
"portable": {
"useZip": true
}
Are we not using ZSTD now?
What is the reasoning behind this?
ZIP would generate a much larger file than the current.
7Z: 35MB (default).
ZSTD: 42MB (experimental, not released).
ZIP: 54MB
Size difference: 12MB
Speed: even if ZSTD decompression speed ~ equals to ZIP decompression (or even faster, see https://raw.githubusercontent.com/facebook/zstd/master/doc/images/Dspeed4.png), ZSTD implemented as tar + zstd. It means, that NSIS will write all 42MB data to a temp file, and then this file will be extracted to real files. So, in case of ZSTD, it is additional time to copy 42MB (can be relatively slow on HDD).
So, I decided to simply use built-in NSIS ZIP compression instead. Also, it is portable — it means that user downloads it and then uses on some portable device (USB?).
Do you disagree?
BTW — 7z rocks not only because of lzma2, but just because 7z is excellent. XZ also uses LZMA2, but sucks in all aspects. For example, 7z automatically applies filters and supports compression chains. That's why 35 MB :)
Thanks for the explanation. Makes sense. Great Work! :1st_place_medal:
If your app is big and you have some use case where ZSTD size will be better — custom solution can be implemented instead of NSIS (e.g. program in golang that simply appends tar.zst file to exe (it is possible and works without issues) and then unpack it directly without intermediate temp file).
Hello,
i tried to used this new option for my app but i have an error on latest version.
My build looks like :
"build": {
"appId": "my-app",
"win": {
"target": "portable"
},
"portable": {
"useZip": true
},
"compression": "normal"
}
and the error :
• electron-builder version=20.8.0
• loaded configuration file=package.json ("build" field)
• writing effective config file=dist\electron-builder-effective-config.yaml
• no native production dependencies
• packaging platform=win32 arch=x64 electron=1.8.4 appOutDir=dist\win-unpacked
• default Electron icon is used reason=application icon is not set
• building target=portable file=dist\grace 0.0.1.exe archs=
Error: C:\Users\xxx\AppData\Local\electron-builder\cache\nsis\nsis-3.0.3.0\Bin\makensis.exe exited with code 1
Output:
Command line defined: "APP_ID=my-app"
Command line defined: "APP_GUID=59fa3a41-a3f5-5e7a-bbe8-7ec9c36adfba"
Command line defined: "PRODUCT_NAME=app"
Command line defined: "PRODUCT_FILENAME=app"
Command line defined: "APP_FILENAME=app"
Command line defined: "APP_DESCRIPTION=app test"
Command line defined: "VERSION=0.0.1"
Command line defined: "PROJECT_DIR=C:\Projet\app\dist"
Command line defined: "BUILD_RESOURCES_DIR=C:\Projet\app\dist\build"
Command line defined: "COMPANY_NAME=Test"
Command line defined: "APP_INSTALLER_STORE_FILE=app\installer.exe"
Command line defined: "ZIP_COMPRESSION"
Command line defined: "COMPRESSION_METHOD=zip"
Command line defined: "REQUEST_EXECUTION_LEVEL=user"
Command line defined: "COMPRESS=auto"
Processing config: C:\Users\xxx\AppData\Local\electron-builder\cache\nsis\nsis-3.0.3.0\nsisconf.nsh
Processing script file: "<stdin>" (ACP)
Error output:
File: "${APP_32}" -> no files found.
Usage: File [/nonfatal] [/a] ([/r] [/x filespec [...]] filespec [...] |
/oname=outfile one_file_only)
Error in macro ia32_app_files on macroline 2
Error in macro extractEmbeddedAppPackage on macroline 20
Error in script "<stdin>" on line 94 -- aborting creation process
at ChildProcess.childProcess.once.code (C:\Projet\app\dist\node_modules\builder-util\src\util.ts:251:14)
at Object.onceWrapper (events.js:219:13)
at ChildProcess.emit (events.js:127:13)
at maybeClose (internal/child_process.js:936:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:220:5)
If i removed
"portable": {
"useZip": true
},
it works great but it can be too long when started
So, you don't plan adding a splash screen?
Seems like the splash screen is a good feature. I tested the default package and one built with "useZip": true, and both opened in ~20 seconds (across multiple tests)... there really isn't any significant difference as far as I can tell. By comparison, the packaged app before building the nsis package launches in under 1 second. Like the original report said, users aren't likely to patiently wait that long if they don't see anything happen in that time.
Seems like this came up a second time in #3972 as well.
I'm not familiar with how this all works, but stumbled upon https://nsis.sourceforge.io/Examples/AdvSplash/Example.nsi and https://nsis.sourceforge.io/Examples/Splash/Example.nsi ... These may be for the installers? Does that apply to whatever the portable process is doing?
Perhaps something like that added to https://github.com/electron-userland/electron-builder/blob/d738644d6e55b027c81e9b7cdd27dc5af9189b0a/packages/app-builder-lib/templates/nsis/portable.nsi ?
@develar Looks like this may need to be re-visited.
The problem with both Splash and AdvSplash is that they are blocking dialogs. As far as I can tell (which is mostly trial and error, as I have never used NSIS before), when you show the splash screen with either plugin, it will block for that amount of time, and only after the splash screen goes away does it begin extracting. Effectively, this just makes users wait longer, and there's still a period between the splash image and the app opening where they are expected to patiently wait without assuming something went horribly wrong.
I am trying to work out a solution of using a non-silent installer with a "background image", and then hiding the regular GUI itself so that the user only sees the background image.
I tested this in the pre-release version 22.9.1 (note: for now, you need to install this version specifically, as it is not yet latest), and it works now 🎉
A quick note though: the image must be a bitmap (bmp), and it seems that not all bitmap images are supported. This is a limitation of NSIS itself. I found that IrfanView creates bmp images that work, but popular node modules (like jimp or bmp-js) do not work, resulting in bmp images that NSIS simply ignores silently. I am not sure why that is. However, for those that want to automate generating these splash images from existing images they have, I created and tested @catdad/to-bmp specifically for this reason, and have ensured that bmp result images work in NSIS.
Most helpful comment
So, you don't plan adding a splash screen?