Electron

Electronのpreload、executeJavaScriptや、各種イベントの発生順序を調べてみた

More than 1 year has passed since last update.

Electronにはウィンドウオープン時のpreloadオプションとかexecuteJavaScript関数とかの、Javascriptを埋め込んで実行する便利機能がありますが、他のイベントと併せてこいつらはどういう順番で実行されるの? と混乱してきたので実験してみました。


テストプログラム


  • main.jsからindex.htmlを開く

  • index.htmlのpreloadオプションにpreload_index.jsを指定

  • index.html内にwebviewタグでwebview.htmlを読み込む

  • webview.htmlのpreloadにpreload_webview.jsを指定

イベントが発生したら、ipcでメインプロセスにメッセージを送信し、それを表示しています。

イベントの発生順にconsole.logにメッセージが表示されるはずです。


main.js

'use strict';

const {app, BrowserWindow, ipcMain} = require('electron');
const path = require('path');

let mainWindow = null;
app.on('window-all-closed', ()=>app.quit());

let webContentJs = `
let ipcRender = require('electron').ipcRenderer;
ipcRender.send('ipc', 'WebContents.executeJavaScriptで実行されたJavascript');`
;

app.on('ready', function() {
mainWindow = new BrowserWindow({
webPreferences: {
preload: path.resolve(path.join(__dirname, 'preload_index.js')),
},
});
mainWindow.loadURL(`file://${__dirname}/index.html`);

mainWindow.webContents.executeJavaScript(webContentJs);
mainWindow.webContents.on('did-finish-load', ()=> console.log('WebContents.did-finish-loadイベント'));
mainWindow.webContents.on('did-start-loading', ()=> console.log('WebContents.did-start-loadingイベント'));
mainWindow.webContents.on('dom-ready', ()=> console.log('WebContents.dom-readyイベント'));

ipcMain.on('ipc', (event, arg)=> console.log(arg));

mainWindow.on('closed', ()=> mainWindow = null);
mainWindow.webContents.openDevTools({mode:'undocked'});
});



index.html

<!DOCTYPE html>

<!-- メインウィンドウ-->
<html lang="ja">
<head>
<meta charset="utf-8" />
<script>
const {ipcRenderer} = require('electron');
ipcRenderer.send('ipc', 'index.html内の<script>タグ');
window.addEventListener('load', function() {
ipcRenderer.send('ipc', 'index.htmlのwindow.onload');
});
</script>
</head>
<body>
てすと<br>
<webview class="wv" src="webview.html" preload="./preload_webview.js"></webview>
</body>
</html>


preload_index.js

//" a script that will be loaded before other scripts run in the page."

const {ipcRenderer} = require('electron');
window.addEventListener('load', ()=> ipcRenderer.send('ipc', 'index.htmlのpreloadのwindow.onload'));
ipcRenderer.send('ipc', 'index.htmlのpreload');


webview.html

<!DOCTYPE html>

<!--index.html内に読み込まれるwebview-->
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>webview</title>
</head>
<body>
webview<br>
</body>
</html>


preload_webview.js

const {ipcRenderer} = require('electron');

window.addEventListener('load', ()=> ipcRenderer.send('ipc', 'webview.htmlのpreloadのwindow.onload'));
ipcRenderer.send('ipc', 'webview.htmlのpreload');


実行結果

こんな感じになりました。

index.htmlのpreload

index.html内の<script>タグ
WebContents.dom-readyイベント
index.htmlのpreloadのwindow.onload
index.htmlのwindow.onload
WebContents.did-finish-loadイベント
WebContents.executeJavaScriptで実行されたJavascript
webview.htmlのpreload
webview.htmlのpreloadのwindow.onload

WebContents.did-start-loadingは発生しないんですね。

リロードしてみました。

WebContents.did-start-loadingイベント

index.htmlのpreload
index.html内の<script>タグ
WebContents.dom-readyイベント
index.htmlのpreloadのwindow.onload
index.htmlのwindow.onload
WebContents.did-finish-loadイベント
webview.htmlのpreload
webview.htmlのpreloadのwindow.onload

webviewのpreloadは、WebContents.did-finish-loadingより先に実行されるかと思っていました。

しかもリロード時は、executeJavascriptは実行されないんですね。

実験してみるものですね。