diff --git a/src/web/app/boot.js b/src/web/app/boot.js
index 8c7a2e0fd6a349ea4f631ea5b289f62c4d5e935c..b22c5fc5be0e1d13a3d95d659a583820771b7235 100644
--- a/src/web/app/boot.js
+++ b/src/web/app/boot.js
@@ -4,7 +4,7 @@
 
 const riot = require('riot');
 require('velocity-animate');
-const api = require('./common/scripts/api.ls');
+const api = require('./common/scripts/api');
 const signout = require('./common/scripts/signout.ls');
 const generateDefaultUserdata = require('./common/scripts/generate-default-userdata.ls');
 const mixins = require('./common/mixins.ls');
diff --git a/src/web/app/common/mixins.ls b/src/web/app/common/mixins.ls
index 50918c68c4e23c4b69b8680ff59dc3a539caa6f6..0a3802e25c8f0668d430dc29ecd4fb2d1ecfb9a0 100644
--- a/src/web/app/common/mixins.ls
+++ b/src/web/app/common/mixins.ls
@@ -6,7 +6,7 @@ module.exports = (me) ~>
 	(require './scripts/i.ls') me
 
 	riot.mixin \api do
-		api: (require './scripts/api.ls').bind null i
+		api: (require './scripts/api').bind null i
 
 	riot.mixin \cropper do
 		Cropper: require \cropperjs
diff --git a/src/web/app/common/scripts/api.js b/src/web/app/common/scripts/api.js
new file mode 100644
index 0000000000000000000000000000000000000000..924d697ebc7c4934905210cc0413de8bfee7c34c
--- /dev/null
+++ b/src/web/app/common/scripts/api.js
@@ -0,0 +1,44 @@
+/**
+ * API Request
+ */
+
+let spinner = null;
+let pending = 0;
+
+/**
+ * Send a request to API
+ * @param  {string|Object} i  Credential
+ * @param  {string} endpoint  Endpoint
+ * @param  {Object} [data={}] Data
+ * @return {Promise<Object>} Response
+ */
+module.exports = (i, endpoint, data = {}) => {
+	if (++pending === 1) {
+		spinner = document.createElement('div');
+		spinner.setAttribute('id', 'wait');
+		document.body.appendChild(spinner);
+	}
+
+	// Append the credential
+	if (i != null) data.i = typeof i === 'object' ? i.token : i;
+
+	return new Promise((resolve, reject) => {
+		// Send request
+		fetch(endpoint.indexOf('://') > -1 ? endpoint : `${CONFIG.api.url}/${endpoint}`, {
+			method: 'POST',
+			body: JSON.stringify(data),
+			credentials: endpoint === 'signin' ? 'include' : 'omit'
+		}).then(res => {
+			if (--pending === 0) spinner.parentNode.removeChild(spinner);
+			if (res.status === 200) {
+				res.json().then(resolve);
+			} else if (res.status === 204) {
+				resolve();
+			} else {
+				res.json().then(err => {
+					reject(err.error);
+				});
+			}
+		}).catch(reject);
+	});
+};
diff --git a/src/web/app/common/scripts/api.ls b/src/web/app/common/scripts/api.ls
deleted file mode 100644
index 47182b6a5aeabcbe52c3aeecec75b173bc7c43db..0000000000000000000000000000000000000000
--- a/src/web/app/common/scripts/api.ls
+++ /dev/null
@@ -1,51 +0,0 @@
-riot = require \riot
-
-spinner = null
-pending = 0
-
-net = riot.observable!
-
-riot.mixin \net do
-	net: net
-
-module.exports = (i, endpoint, data = {}) ->
-	if ++pending == 1
-		spinner := document.create-element \div
-			..set-attribute \id \wait
-		document.body.append-child spinner
-	
-	if i? and typeof i == \object then i = i.token
-
-	# append user token when signed in
-	if i? then data.i = i
-
-	opts =
-		method: \POST
-		body: JSON.stringify data
-
-	if endpoint == \signin
-		opts.credentials = \include
-
-	ep = if (endpoint.index-of '://') > -1
-		then endpoint
-		else "#{CONFIG.api.url}/#{endpoint}"
-
-	new Promise (resolve, reject) ->
-		timer = set-timeout ->
-			net.trigger \detected-slow-network
-		, 5000ms
-
-		fetch ep, opts
-		.then (res) ->
-			clear-timeout timer
-			if --pending == 0
-				spinner.parent-node.remove-child spinner
-
-			if res.status == 200
-				res.json!.then resolve
-			else if res.status == 204
-				resolve!
-			else
-				res.json!.then (err) ->
-					reject err.error
-		.catch reject
diff --git a/src/web/app/desktop/scripts/update-avatar.ls b/src/web/app/desktop/scripts/update-avatar.ls
index 513a59074c257336d3cf62ef6b0fb4a6aa439c97..351e54fe51c3488014550c5286c1401eb931f2cd 100644
--- a/src/web/app/desktop/scripts/update-avatar.ls
+++ b/src/web/app/desktop/scripts/update-avatar.ls
@@ -3,7 +3,7 @@
 
 riot = require 'riot'
 dialog = require './dialog.ls'
-api = require '../../common/scripts/api.ls'
+api = require '../../common/scripts/api'
 
 module.exports = (I, cb, file = null) ~>
 
diff --git a/src/web/app/desktop/scripts/update-banner.ls b/src/web/app/desktop/scripts/update-banner.ls
index 5754cdcdb16230020a407c8466e9ec359b059f65..2417b8ab2acd1f1a2bea10f2101ab6f0a8c615d6 100644
--- a/src/web/app/desktop/scripts/update-banner.ls
+++ b/src/web/app/desktop/scripts/update-banner.ls
@@ -3,7 +3,7 @@
 
 riot = require 'riot'
 dialog = require './dialog.ls'
-api = require '../../common/scripts/api.ls'
+api = require '../../common/scripts/api'
 
 module.exports = (I, cb, file = null) ~>
 
diff --git a/src/web/app/desktop/scripts/update-wallpaper.ls b/src/web/app/desktop/scripts/update-wallpaper.ls
index 49632400c0a84efec742194b0327919b4f680f32..e7394a0d0cc311067b8deb36daa2627a8e599042 100644
--- a/src/web/app/desktop/scripts/update-wallpaper.ls
+++ b/src/web/app/desktop/scripts/update-wallpaper.ls
@@ -3,7 +3,7 @@
 
 riot = require 'riot'
 dialog = require './dialog.ls'
-api = require '../../common/scripts/api.ls'
+api = require '../../common/scripts/api'
 
 module.exports = (I, cb, file = null) ~>
 
diff --git a/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag b/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag
deleted file mode 100644
index 09a746fb9ba2f9b52088955d8bceeaa269fb43a9..0000000000000000000000000000000000000000
--- a/src/web/app/desktop/tags/detect-slow-internet-connection-notice.tag
+++ /dev/null
@@ -1,60 +0,0 @@
-<mk-detect-slow-internet-connection-notice><i><i class="fa fa-exclamation"></i></i>
-	<div>
-		<p>インターネット回線が遅いようです。</p>
-	</div>
-	<style type="stylus">
-		:scope
-			display block
-			pointer-events none
-			position fixed
-			z-index 16384
-			top 64px
-			right 16px
-			margin 0
-			padding 0
-			width 298px
-			font-size 0.9em
-			background #fff
-			box-shadow 0 1px 4px rgba(0, 0, 0, 0.25)
-			opacity 0
-
-			> i
-				display block
-				width 48px
-				line-height 48px
-				margin-right 0.25em
-				text-align center
-				color $theme-color-foreground
-				font-size 1.5em
-				background $theme-color
-
-			> div
-				display block
-				position absolute
-				top 0
-				left 48px
-				margin 0
-				width 250px
-				height 48px
-				color #666
-
-				> p
-					display block
-					margin 0
-					padding 8px
-
-	</style>
-	<script>
-		@mixin \net
-
-		@net.on \detected-slow-network ~>
-			Velocity @root, {
-				opacity: 1
-			} 200ms \linear
-			set-timeout ~>
-				Velocity @root, {
-					opacity: 0
-				} 200ms \linear
-			, 10000ms
-	</script>
-</mk-detect-slow-internet-connection-notice>
diff --git a/src/web/app/desktop/tags/home.tag b/src/web/app/desktop/tags/home.tag
index c7dc82efc9f3c4422e0b20fede41a00c76f0ce4e..b969aec444af5fb5fd8f45ff51bcfb4e14fe90a6 100644
--- a/src/web/app/desktop/tags/home.tag
+++ b/src/web/app/desktop/tags/home.tag
@@ -7,7 +7,6 @@
 		</main>
 		<div class="right" ref="right"></div>
 	</div>
-	<mk-detect-slow-internet-connection-notice></mk-detect-slow-internet-connection-notice>
 	<style type="stylus">
 		:scope
 			display block
diff --git a/src/web/app/desktop/tags/index.js b/src/web/app/desktop/tags/index.js
index 449bb71ae1d009bf09f17c87d19629cde1e926a6..e88d8d27e99cd802fb5720ee23239fd9e36f9d1c 100644
--- a/src/web/app/desktop/tags/index.js
+++ b/src/web/app/desktop/tags/index.js
@@ -54,7 +54,6 @@ require('./following-setuper.tag');
 require('./ellipsis-icon.tag');
 require('./ui.tag');
 require('./home.tag');
-require('./detect-slow-internet-connection-notice.tag');
 require('./user-header.tag');
 require('./user-profile.tag');
 require('./user-timeline.tag');