Question: Could someone please help me to implement a loading animation for my Electron app ?
I am learning this new technology and it would be nice to understand the correct way to do that.

I am thinking about something like :

```
app.on('ready', () => {
     // show main content
})

app.on('not-ready', () => {
     // show loading animation
})

```

Answer: 
As far as I know there is no event emitted from `app` before `ready` (only exception is [`will-finish-launching`](https://github.com/electron/electron/blob/master/docs/api/app.md#event-will-finish-launching) available only on macOS).

Furthermore, you cannot open any `BrowserWindow` before `app` is `ready`, so you should really wait it.

However, if your main application window loading very slow, you can still open a "loading window" before that and switch them when your main window is ready.

```js
const { app, BrowserWindow } = require('electron')

app.on('ready', () => {
  let main = null
  let loading = new BrowserWindow({show: false, frame: false})

  loading.once('show', () => {
    main = new BrowserWindow({show: false})
    main.webContents.once('dom-ready', () => {
      console.log('main loaded')
      main.show()
      loading.hide()
      loading.close()
    })
    // long loading html
    main.loadURL('http://spacecrafts3d.org')
  })
  loading.loadURL('loding.html')
  loading.show()
})

```

---

*You can use `win.on('ready-to-show')` instead of `win.webContents.on('dom-ready')` everywhere if you want to eliminate visual flash (but losing some speed)*

---

`window.open()`

If you want to do the same for `BrowserWindow` opened in renderer process by `window.open()`, you can use `new-window` event of `webContents` if `nativeWindowOpen` is `true`

```js
main = new BrowserWindow({
  webPreferences: {
    nativeWindowOpen: true
  }
})
main.webContents.on('new-window', (event, url) => {
  // there are more args not used here
  event.preventDefault()
  const win = new BrowserWindow({show: false})
  win.webContents.once('dom-ready', () => {
    win.show()
    loading.hide() // don't destroy in this case
  })
  win.loadURL(url)
  loading.show()
  event.newGuest = win
})

```
It can be done by displaying a new BrowserWindow displaying the activity loader , until the main app fully loads .

Let's define a `createWindow` funtion (as given in docs) which is responsible for loading the main app for the user as :

```

var loadingwindow = null; // Responsible for creating activity loader

function createWindow () {

  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true
    }
  })

  win.loadFile('index.html')
  loadingwindow.hide() // Used to hide the loading screen when the contents in main app are loaded

}

```

Now , in order to display the `loadingwindow` screen , we need to place it in `app.on('ready' , callback_fn)`  as shows here :

```

app.on("ready" , () => {

  loadingwindow = new BrowserWindow({
    frame : false,
    movable : false,
  })

  loadingwindow.loadFile('activity.html') // To load the activity loader html file
  loadingwindow.show();
})

```

That's it ! ,
To check if it is working properly , wrap the `setTimeout` function over the `app.whenReady().then(createWindow)`