diff --git a/src/web/app/common/mios.ts b/src/web/app/common/mios.ts
index 5e76d82a38..cf7841d848 100644
--- a/src/web/app/common/mios.ts
+++ b/src/web/app/common/mios.ts
@@ -35,6 +35,13 @@ export default class MiOS extends EventEmitter {
 		return this.i != null;
 	}
 
+	/**
+	 * Whether is debug mode
+	 */
+	public get debug() {
+		return localStorage.getItem('debug') == 'true';
+	}
+
 	/**
 	 * A connection manager of home stream
 	 */
@@ -49,13 +56,37 @@ export default class MiOS extends EventEmitter {
 		super();
 
 		//#region BIND
+		this.log = this.log.bind(this);
+		this.logInfo = this.logInfo.bind(this);
+		this.logWarn = this.logWarn.bind(this);
+		this.logError = this.logError.bind(this);
 		this.init = this.init.bind(this);
 		this.api = this.api.bind(this);
 		this.getMeta = this.getMeta.bind(this);
-		this.swSubscribe = this.swSubscribe.bind(this);
+		this.registerSw = this.registerSw.bind(this);
 		//#endregion
 	}
 
+	public log(...args) {
+		if (!this.debug) return;
+		console.log.apply(null, args);
+	}
+
+	public logInfo(...args) {
+		if (!this.debug) return;
+		console.info.apply(null, args);
+	}
+
+	public logWarn(...args) {
+		if (!this.debug) return;
+		console.warn.apply(null, args);
+	}
+
+	public logError(...args) {
+		if (!this.debug) return;
+		console.error.apply(null, args);
+	}
+
 	/**
 	 * Initialize MiOS (boot)
 	 * @param callback A function that call when initialized
@@ -136,30 +167,20 @@ export default class MiOS extends EventEmitter {
 			// Finish init
 			callback();
 
-			//#region Service worker
-			const isSwSupported =
-				('serviceWorker' in navigator) && ('PushManager' in window);
+			//#region Post
 
-			if (isSwSupported && this.isSignedin) {
-				// When service worker activated
-				navigator.serviceWorker.ready.then(this.swSubscribe);
+			// Init service worker
+			this.registerSw();
 
-				// Register service worker
-				navigator.serviceWorker.register(`/sw.${VERSION}.${LANG}.js`).then(registration => {
-					// 登録成功
-					console.info('ServiceWorker registration successful with scope: ', registration.scope);
-				}).catch(err => {
-					// 登録失敗 :(
-					console.error('ServiceWorker registration failed: ', err);
-				});
-			}
 			//#endregion
 		};
 
 		// Get cached account data
 		const cachedMe = JSON.parse(localStorage.getItem('me'));
 
+		// キャッシュがあったとき
 		if (cachedMe) {
+			// とりあえずキャッシュされたデータでお茶を濁して(?)おいて、
 			fetched(cachedMe);
 
 			// 後から新鮮なデータをフェッチ
@@ -175,27 +196,64 @@ export default class MiOS extends EventEmitter {
 		}
 	}
 
-	private async swSubscribe(swRegistration: ServiceWorkerRegistration) {
-		this.swRegistration = swRegistration;
+	/**
+	 * Register service worker
+	 */
+	private registerSw() {
+		// Check whether service worker and push manager supported
+		const isSwSupported =
+			('serviceWorker' in navigator) && ('PushManager' in window);
 
-		// Subscribe
-		this.swRegistration.pushManager.subscribe({
-			// A boolean indicating that the returned push subscription
-			// will only be used for messages whose effect is made visible to the user.
-			userVisibleOnly: true
-		}).then(subscription => {
-			console.log('Subscribe OK:', subscription);
+		// Reject when browser not service worker supported
+		if (!isSwSupported) return;
 
-			// Register
-			this.api('sw/register', {
-				endpoint: subscription.endpoint,
-				auth: btoa(String.fromCharCode.apply(null, new Uint8Array(subscription.getKey('auth')))),
-				publickey: btoa(String.fromCharCode.apply(null, new Uint8Array(subscription.getKey('p256dh'))))
+		// Reject when not signed in to Misskey
+		if (!this.isSignedin) return;
+
+		// When service worker activated
+		navigator.serviceWorker.ready.then(registration => {
+			this.log('[sw] ready: ', registration);
+
+			this.swRegistration = registration;
+
+			// Options of pushManager.subscribe
+			const opts = {
+				// A boolean indicating that the returned push subscription
+				// will only be used for messages whose effect is made visible to the user.
+				userVisibleOnly: true
+			};
+
+			// Subscribe push notification
+			this.swRegistration.pushManager.subscribe(opts).then(subscription => {
+				this.log('[sw] Subscribe OK:', subscription);
+
+				function encode(buffer: ArrayBuffer) {
+					return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)));
+				}
+
+				// Register
+				this.api('sw/register', {
+					endpoint: subscription.endpoint,
+					auth: encode(subscription.getKey('auth')),
+					publickey: encode(subscription.getKey('p256dh'))
+				});
+			}).then(() => {
+				this.logInfo('[sw] Server Stored Subscription.');
+			}).catch(err => {
+				this.logError('[sw] Subscribe Error:', err);
 			});
-		}).then(() => {
-			console.log('Server Stored Subscription.');
+		});
+
+		// The path of service worker script
+		const sw = `/sw.${VERSION}.${LANG}.js`;
+
+		// Register service worker
+		navigator.serviceWorker.register(sw).then(registration => {
+			// 登録成功
+			this.logInfo('[sw] Registration successful with scope: ', registration.scope);
 		}).catch(err => {
-			console.error('Subscribe Error:', err);
+			// 登録失敗 :(
+			this.logError('[sw] Registration failed: ', err);
 		});
 	}
 
diff --git a/src/web/app/sw.js b/src/web/app/sw.js
index 463ae0c75e..a7c84d022a 100644
--- a/src/web/app/sw.js
+++ b/src/web/app/sw.js
@@ -6,25 +6,28 @@ import composeNotification from './common/scripts/compose-notification';
 
 // インストールされたとき
 self.addEventListener('install', () => {
-	console.log('[sw]', 'Your ServiceWorker is installed');
+	console.info('installed');
 });
 
 // プッシュ通知を受け取ったとき
 self.addEventListener('push', ev => {
+	console.log('pushed');
+
 	// クライアント取得
-	self.clients.matchAll({
+	ev.waitUntil(self.clients.matchAll({
 		includeUncontrolled: true
 	}).then(clients => {
 		// クライアントがあったらストリームに接続しているということなので通知しない
 		if (clients.length != 0) return;
 
 		const { type, body } = ev.data.json();
+
+		console.log(type, body);
+
 		const n = composeNotification(type, body);
-		if (n) {
-			self.registration.showNotification(n.title, {
-				body: n.body,
-				icon: n.icon,
-			});
-		}
-	});
+		return self.registration.showNotification(n.title, {
+			body: n.body,
+			icon: n.icon,
+		});
+	}));
 });