Electron トラブルシュート:白画面(White Screen)問題を 3 分で切り分け

Electron アプリを開発していて、突然真っ白な画面が表示された経験はありませんか。一瞬で心配になり、「何が原因なのか」「どこから調べればいいのか」と困惑してしまいますよね。
この白画面問題は Electron 開発でよく遭遇するトラブルの一つです。しかし、適切な手順で診断すれば、わずか 3 分で原因を特定できます。今回は、原因別のアプローチで効率的に問題を切り分ける方法をご紹介しましょう。
背景
Electron アプリケーションにおける白画面問題は、様々な場面で発生します。開発中にコードを変更した直後、ビルド後の実行時、または本番環境へのデプロイ後など、タイミングは多岐にわたります。
mermaidflowchart TD
start[Electron アプリ起動] --> main[メインプロセス開始]
main --> window[BrowserWindow 作成]
window --> load[HTML ファイル読み込み]
load --> render[レンダラープロセス開始]
render --> display[画面表示]
main -->|エラー| error1[メインプロセス エラー]
load -->|失敗| error2[リソース読み込み エラー]
render -->|クラッシュ| error3[レンダラープロセス エラー]
error1 --> white[白画面表示]
error2 --> white
error3 --> white
上図が示すように、Electron の起動フローは複数のステップから構成されており、各段階でエラーが発生する可能性があります。
開発者が直面する典型的なシナリオとしては、以下のようなケースが挙げられます。
- 新しい機能を追加した後の初回起動時
- 依存関係を更新した後の動作確認時
- パッケージングした実行ファイルの動作テスト時
- 異なる環境での動作確認時
これらの状況では、エラーメッセージが表示されずに単純な白画面になってしまうことが多く、原因の特定が困難になります。
課題
Electron の白画面問題における最大の課題は、原因の特定に時間がかかることです。従来のウェブ開発とは異なり、Electron では以下の要因が問題を複雑化させます。
複数プロセスによる複雑性
Electron はメインプロセスとレンダラープロセスの 2 つのプロセスで動作します。どちらのプロセスで問題が発生しているかを判断するだけでも、相当な時間を要する場合があります。
エラー情報の不足
白画面の状態では、通常のエラーメッセージやスタックトレースが表示されません。そのため、ログファイルや開発者ツールを駆使して情報を収集する必要があります。
環境依存の問題
開発環境では正常に動作していたアプリが、本番環境やパッケージング後に白画面になるケースも少なくありません。環境の違いによる影響を特定するには、系統的なアプローチが必要です。
これらの課題を解決するために、効率的な診断手順を確立することが重要になります。
解決策
白画面問題を 3 分で切り分けるためには、発生頻度の高い原因から順番にチェックしていく戦略的なアプローチが有効です。以下の 3 つの主要原因に分けて、具体的な診断方法をご説明します。
原因 1:レンダラープロセスのクラッシュ
レンダラープロセスのクラッシュは、白画面問題の最も一般的な原因の一つです。JavaScript のエラーや DOM 操作の問題が主な要因となります。
DevTools での確認方法
まず、DevTools を開いて Console タブを確認しましょう。
javascript// メインプロセス側で DevTools を開く設定
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
// 開発時は DevTools を自動で開く
devTools: true,
},
});
// DevTools を手動で開く
mainWindow.webContents.openDevTools();
DevTools が開いたら、以下の手順で確認を進めます。
javascript// Console タブで確認すべきエラーの例
// 1. JavaScript の実行エラー
Uncaught TypeError: Cannot read property 'name' of undefined
// 2. モジュール読み込みエラー
Uncaught Error: Cannot resolve module './component.js'
// 3. DOM 操作エラー
Uncaught DOMException: Failed to execute 'appendChild' on 'Node'
Console タブでエラーが確認できた場合は、該当するコードを修正することで問題を解決できます。
プロセス監視ツールの活用
DevTools でエラーが見つからない場合は、プロセス監視ツールを使用してレンダラープロセスの状態を確認します。
javascript// メインプロセスでレンダラープロセスの状態を監視
mainWindow.webContents.on('crashed', (event, killed) => {
console.log('レンダラープロセスがクラッシュしました');
console.log('強制終了:', killed);
// クラッシュ時の復旧処理
mainWindow.reload();
});
// プロセスの応答状況を確認
mainWindow.webContents.on('unresponsive', () => {
console.log('レンダラープロセスが応答していません');
});
mainWindow.webContents.on('responsive', () => {
console.log('レンダラープロセスが応答を再開しました');
});
これらのイベントリスナーを設定することで、レンダラープロセスの異常を検出できます。
原因 2:メインプロセスの初期化エラー
メインプロセスの初期化でエラーが発生すると、BrowserWindow 自体が正常に作成されず、結果として白画面が表示されます。
ログ出力の確認
メインプロセスのログは、通常のコンソール出力として確認できます。
javascript// メインプロセスでのエラーハンドリング
process.on('uncaughtException', (error) => {
console.error(
'メインプロセスで捕捉されない例外が発生しました:',
error
);
// ログファイルに出力
const fs = require('fs');
const path = require('path');
const logPath = path.join(__dirname, 'error.log');
fs.appendFileSync(
logPath,
`${new Date().toISOString()}: ${error.stack}\n`
);
});
// Promise の reject をキャッチ
process.on('unhandledRejection', (reason, promise) => {
console.error('未処理の Promise rejection:', reason);
});
起動シーケンスの検証
Electron の起動シーケンスを段階的に確認し、どの時点でエラーが発生しているかを特定します。
javascript// 起動シーケンスのデバッグログ
const { app, BrowserWindow } = require('electron');
console.log('1. アプリケーション初期化開始');
app.whenReady().then(() => {
console.log('2. アプリケーション準備完了');
try {
console.log('3. BrowserWindow 作成開始');
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
console.log('4. BrowserWindow 作成完了');
console.log('5. ファイル読み込み開始');
mainWindow
.loadFile('index.html')
.then(() => {
console.log('6. ファイル読み込み完了');
})
.catch((error) => {
console.error('ファイル読み込みエラー:', error);
});
} catch (error) {
console.error('BrowserWindow 作成エラー:', error);
}
});
このようなログ出力により、初期化のどの段階で問題が発生しているかを特定できます。
原因 3:リソース読み込み失敗
HTML、CSS、JavaScript ファイルなどのリソース読み込みに失敗すると、白画面が表示される場合があります。
ファイルパスの検証
最も一般的な原因は、ファイルパスの間違いです。特に相対パスと絶対パスの使い分けに注意が必要です。
javascript// 正しいファイルパス指定の例
const path = require('path');
// HTML ファイルの読み込み
mainWindow.loadFile(path.join(__dirname, 'src', 'index.html'));
// 画像リソースの読み込み(HTML 内)
// 相対パス(推奨)
<img src="./assets/images/logo.png" alt="ロゴ">
// 絶対パス(避けるべき)
<img src="/Users/username/project/assets/images/logo.png" alt="ロゴ">
ファイルの存在確認も重要なチェック項目です。
javascript// ファイル存在確認のユーティリティ
const fs = require('fs');
function checkFileExists(filePath) {
try {
fs.accessSync(filePath, fs.constants.F_OK);
console.log(`ファイルが存在します: ${filePath}`);
return true;
} catch (error) {
console.error(`ファイルが存在しません: ${filePath}`);
return false;
}
}
// メインファイルの確認
const indexPath = path.join(__dirname, 'src', 'index.html');
if (checkFileExists(indexPath)) {
mainWindow.loadFile(indexPath);
} else {
console.error('index.html が見つかりません');
}
CORS エラーの確認
Electron アプリでは、ローカルファイルからの読み込みで CORS エラーが発生する場合があります。
javascript// CORS エラーを回避する設定
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
// ローカルファイルの制限を緩和
allowRunningInsecureContent: true,
webSecurity: false, // 開発時のみ使用
},
});
Network タブでリソースの読み込み状況を確認することも重要です。
javascript// リソース読み込みの監視
mainWindow.webContents.on(
'did-fail-load',
(event, errorCode, errorDescription, validatedURL) => {
console.error('リソース読み込み失敗:', {
errorCode,
errorDescription,
url: validatedURL,
});
}
);
// リソース読み込み完了の確認
mainWindow.webContents.on('did-finish-load', () => {
console.log('すべてのリソースの読み込みが完了しました');
});
具体例
実際の開発現場で遭遇する具体的なケースとその対処法をご紹介します。これらの例を参考に、自分のプロジェクトでの問題解決に活用してください。
ケース 1:JavaScript モジュール読み込みエラー
症状: アプリ起動時に白画面が表示され、Console に以下のエラーが出力される
javascript// エラーログ例
Uncaught Error: Cannot resolve module './components/Header.js'
at Module.require (webpack-internal:///./src/main.js:15:23)
at Object.<anonymous> (webpack-internal:///./src/main.js:3:18)
原因: ファイルパスの間違いまたはファイルの不存在
解決手順:
- エラーで指摘されたファイルパスを確認
- 実際のファイル構造と照らし合わせ
- 正しいパスに修正
javascript// 修正前(エラーの原因)
import Header from './components/Header.js'; // ファイルが存在しない
// 修正後
import Header from './components/HeaderComponent.js'; // 正しいファイル名
ケース 2:CSS 読み込み失敗による部分白画面
症状: HTML の構造は表示されるが、スタイルが適用されず白っぽい画面になる
html<!-- 問題のある CSS 読み込み -->
<link rel="stylesheet" href="/styles/main.css" />
エラーログ例:
perlGET file:///styles/main.css net::ERR_FILE_NOT_FOUND
解決手順:
- Network タブで CSS ファイルの読み込み状況を確認
- ファイルパスを相対パスに変更
- ファイルの存在確認
html<!-- 修正後 -->
<link rel="stylesheet" href="./assets/css/main.css" />
ケース 3:非同期処理の競合による白画面
症状: アプリは起動するが、データ読み込み後に白画面になる
javascript// 問題のあるコード例
async function loadUserData() {
const userData = await fetchUserFromAPI();
document.getElementById('user-info').innerHTML =
userData.name; // エラーの原因
}
// fetchUserFromAPI() が失敗した場合、userData が undefined になり
// userData.name でエラーが発生
エラーログ例:
javascriptUncaught TypeError: Cannot read property 'name' of undefined
at loadUserData (main.js:45:67)
解決手順:
- 非同期処理にエラーハンドリングを追加
- データの存在確認を実装
- フォールバック処理を設定
javascript// 修正後のコード
async function loadUserData() {
try {
const userData = await fetchUserFromAPI();
// データの存在確認
if (userData && userData.name) {
document.getElementById('user-info').innerHTML =
userData.name;
} else {
document.getElementById('user-info').innerHTML =
'ユーザー情報を取得できませんでした';
}
} catch (error) {
console.error('ユーザーデータ読み込みエラー:', error);
document.getElementById('user-info').innerHTML =
'エラーが発生しました';
}
}
ケース 4:パッケージング後の白画面
症状: 開発環境では正常に動作するが、パッケージング後に白画面になる
主な原因:
javascript// 開発時は動作するが、パッケージング後にエラーになるコード例
const fs = require('fs');
const path = require('path');
// 開発時のパス(動作する)
const configPath = path.join(__dirname, 'config.json');
// パッケージング後は __dirname の場所が変わるため、ファイルが見つからない
解決手順:
- パッケージング後のディレクトリ構造を確認
- リソースファイルの配置場所を修正
- アプリケーションリソースパスを使用
javascript// 修正後のコード
const { app } = require('electron');
// パッケージング後も動作するパス指定
const configPath = path.join(
app.getAppPath(),
'config.json'
);
// または、ユーザーデータディレクトリを使用
const userDataPath = app.getPath('userData');
const configPath = path.join(userDataPath, 'config.json');
これらの具体例を参考に、段階的に問題を切り分けることで、効率的に白画面問題を解決できます。
まとめ
Electron の白画面問題を 3 分で切り分けるための手順をまとめました。以下のチェックリストを活用して、迅速な問題解決を図ってください。
3 分切り分けチェックリスト
時間 | チェック項目 | 確認方法 | 対処法 |
---|---|---|---|
1 分目 | DevTools Console 確認 | Ctrl+Shift+I で Console タブ | エラーメッセージに従ってコード修正 |
1 分目 | ファイル存在確認 | fs.accessSync() または手動確認 | 正しいパスに修正、ファイル作成 |
2 分目 | メインプロセスログ確認 | ターミナル/コマンドプロンプト | 初期化エラーを修正 |
2 分目 | レンダラープロセス監視 | crashed イベントリスナー設定 | プロセス再起動、エラー原因特定 |
3 分目 | Network タブ確認 | DevTools の Network タブ | リソースパス修正、CORS 設定調整 |
3 分目 | 環境差異確認 | 開発環境とパッケージング後比較 | パス指定方法の見直し |
予防策の提案
今後の白画面問題を予防するために、以下の開発手法を取り入れることをお勧めします。
1. エラーハンドリングの充実
javascript// 包括的なエラーハンドリングの実装
function setupErrorHandling() {
// メインプロセスのエラー
process.on('uncaughtException', handleMainProcessError);
process.on(
'unhandledRejection',
handleUnhandledRejection
);
// レンダラープロセスのエラー
window.addEventListener('error', handleRendererError);
window.addEventListener(
'unhandledrejection',
handlePromiseRejection
);
}
2. ログ機能の強化
javascript// ログレベル別の出力機能
const logger = {
debug: (message) => console.log(`[DEBUG] ${message}`),
info: (message) => console.info(`[INFO] ${message}`),
warn: (message) => console.warn(`[WARN] ${message}`),
error: (message) => console.error(`[ERROR] ${message}`),
};
3. 開発時の自動チェック機能
javascript// 開発時の自動診断機能
function performStartupDiagnostics() {
const requiredFiles = [
'./src/index.html',
'./src/main.js',
'./assets/css/main.css',
];
requiredFiles.forEach((file) => {
if (!fs.existsSync(file)) {
logger.error(`必須ファイルが見つかりません: ${file}`);
}
});
}
適切な診断手順と予防策を組み合わせることで、Electron 開発における白画面問題を効率的に解決し、開発生産性を向上させることができます。問題が発生した際は、このガイドを参考に段階的なアプローチで原因を特定してください。
関連リンク
- article
Electron トラブルシュート:白画面(White Screen)問題を 3 分で切り分け
- article
Electron 入門 2025:Web 技術でデスクトップアプリを作る全体像
- article
TauriとElectronのパフォーマンス比較
- article
Tauriとは?Electronと何が違うのか徹底解説
- article
Vite + Electron:デスクトップアプリ開発への応用
- article
【比較検証】Convex vs Firebase vs Supabase:リアルタイム性・整合性・学習コストの最適解
- article
【徹底比較】Preact vs React 2025:バンドル・FPS・メモリ・DX を総合評価
- article
GPT-5-Codex vs Claude Code / Cursor 徹底比較:得意領域・精度・開発速度の違いを検証
- article
Astro × Cloudflare Workers/Pages:エッジ配信で超高速なサイトを構築
- article
【2025 年版】Playwright vs Cypress vs Selenium 徹底比較:速度・安定性・学習コストの最適解
- article
Apollo を最短導入:Vite/Next.js/Remix での初期配線テンプレ集
- blog
iPhone 17シリーズの発表!全モデルiPhone 16から進化したポイントを見やすく整理
- blog
Googleストアから訂正案内!Pixel 10ポイント有効期限「1年」表示は誤りだった
- blog
【2025年8月】Googleストア「ストアポイント」は1年表記はミス?2年ルールとの整合性を検証
- blog
Googleストアの注文キャンセルはなぜ起きる?Pixel 10購入前に知るべき注意点
- blog
Pixcel 10シリーズの発表!全モデル Pixcel 9 から進化したポイントを見やすく整理
- blog
フロントエンドエンジニアの成長戦略:コーチングで最速スキルアップする方法
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来