diff --git a/lib/private/route/router.php b/lib/private/route/router.php
index 806bbf51abf8f04ef8a53683a3c7c640e7068a8c..28c27b601c180e35b060874ed4695f268eb172f7 100644
--- a/lib/private/route/router.php
+++ b/lib/private/route/router.php
@@ -47,6 +47,8 @@ class Router implements IRouter {
 
 	protected $loaded = false;
 
+	protected $loadedApps = array();
+
 	public function __construct() {
 		$baseUrl = \OC_Helper::linkTo('', 'index.php');
 		if (!\OC::$CLI) {
@@ -93,27 +95,44 @@ class Router implements IRouter {
 	/**
 	 * loads the api routes
 	 */
-	public function loadRoutes() {
+	public function loadRoutes($app = null) {
 		if ($this->loaded) {
 			return;
 		}
-		$this->loaded = true;
-		foreach ($this->getRoutingFiles() as $app => $file) {
+		if (is_null($app)) {
+			$this->loaded = true;
+			$routingFiles = $this->getRoutingFiles();
+		} else {
+			if (isset($this->loadedApps[$app])) {
+				return;
+			}
+			$this->loadedApps[$app] = true;
+			$file = \OC_App::getAppPath($app) . '/appinfo/routes.php';
+			if (file_exists($file)) {
+				$routingFiles = array($file);
+			} else {
+				$routingFiles = array();
+			}
+		}
+		foreach ($routingFiles as $app => $file) {
 			$this->useCollection($app);
 			require_once $file;
 			$collection = $this->getCollection($app);
 			$collection->addPrefix('/apps/' . $app);
 			$this->root->addCollection($collection);
 		}
-		$this->useCollection('root');
-		require_once 'settings/routes.php';
-		require_once 'core/routes.php';
-
-		// include ocs routes
-		require_once 'ocs/routes.php';
-		$collection = $this->getCollection('ocs');
-		$collection->addPrefix('/ocs');
-		$this->root->addCollection($collection);
+		if (!isset($this->loadedApps['core'])) {
+			$this->loadedApps['core'] = true;
+			$this->useCollection('root');
+			require_once 'settings/routes.php';
+			require_once 'core/routes.php';
+
+			// include ocs routes
+			require_once 'ocs/routes.php';
+			$collection = $this->getCollection('ocs');
+			$collection->addPrefix('/ocs');
+			$this->root->addCollection($collection);
+		}
 	}
 
 	/**
@@ -158,7 +177,12 @@ class Router implements IRouter {
 	 * @throws \Exception
 	 */
 	public function match($url) {
-		$this->loadRoutes();
+		if (substr($url, 0, 6) === '/apps/') {
+			list(, , $app,) = explode('/', $url, 4);
+			$this->loadRoutes($app);
+		} else {
+			$this->loadRoutes();
+		}
 		$matcher = new UrlMatcher($this->root, $this->context);
 		$parameters = $matcher->match($url);
 		if (isset($parameters['action'])) {
diff --git a/lib/public/route/irouter.php b/lib/public/route/irouter.php
index df397bc875891bf0dea29b5b14b933d4af742062..125cd29e81b582519f217a8edfca25595fd26b55 100644
--- a/lib/public/route/irouter.php
+++ b/lib/public/route/irouter.php
@@ -22,7 +22,7 @@ interface IRouter {
 	/**
 	 * loads the api routes
 	 */
-	public function loadRoutes();
+	public function loadRoutes($app = null);
 
 	/**
 	 * Sets the collection to use for adding routes