diff --git a/src/libs/extensionsystem/iplugin.cpp b/src/libs/extensionsystem/iplugin.cpp
index 5060b0a68d60dfdfb46856ec9185968173ded02d..e6ee6e4a6b95d3f575a38e9647865b94c79bffbf 100644
--- a/src/libs/extensionsystem/iplugin.cpp
+++ b/src/libs/extensionsystem/iplugin.cpp
@@ -98,6 +98,7 @@
     describing the reason.
 
     \sa extensionsInitialized()
+    \sa delayedInitialize()
 */
 
 /*!
@@ -112,6 +113,28 @@
     been provided by dependent plugins.
 
     \sa initialize()
+    \sa delayedInitialize()
+*/
+
+/*!
+    \fn bool IPlugin::delayedInitialize()
+    \brief Called after all plugins' IPlugin::extensionsInitialized() method has been called,
+    and after the IPlugin::delayedInitialize() method of plugins that depend on this plugin
+    have been called.
+
+    The plugins' delayedInitialize() methods are called after the application is already running,
+    with a few milliseconds delay to application startup, and between individual delayedInitialize
+    method calls. To avoid unnecessary delays, a plugin should return true from the method if it
+    actually implements it, to indicate that the next plugins' delayedInitialize() call should
+    be delayed a few milliseconds to give input and paint events a chance to be processed.
+
+    This method can be used if a plugin needs to do non-trivial setup that doesn't
+    necessarily needs to be done directly at startup, but still should be done within a
+    short time afterwards. This can increase the felt plugin/application startup
+    time a lot, with very little effort.
+
+    \sa initialize()
+    \sa extensionsInitialized()
 */
 
 /*!
diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h
index b3652aed3f386a0f6f53f69ad7eb6de39c1d5461..8d251820fd207ead5f06f32d9501afec9e68086f 100644
--- a/src/libs/extensionsystem/iplugin.h
+++ b/src/libs/extensionsystem/iplugin.h
@@ -62,6 +62,7 @@ public:
 
     virtual bool initialize(const QStringList &arguments, QString *errorString) = 0;
     virtual void extensionsInitialized() = 0;
+    virtual bool delayedInitialize() { return false; }
     virtual ShutdownFlag aboutToShutdown() { return SynchronousShutdown; }
     virtual void remoteCommand(const QStringList & /* options */, const QStringList & /* arguments */) { }
 
diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp
index 7d19c9ffbee2f86b720290d280d26f8cd3c1f37e..9420af85b46e93b5fc41e7ce7f39c548aed38f9e 100644
--- a/src/libs/extensionsystem/pluginmanager.cpp
+++ b/src/libs/extensionsystem/pluginmanager.cpp
@@ -55,6 +55,7 @@
 
 static const char C_IGNORED_PLUGINS[] = "Plugins/Ignored";
 static const char C_FORCEENABLED_PLUGINS[] = "Plugins/ForceEnabled";
+static const int DELAYED_INITIALIZE_INTERVAL = 20; // ms
 
 typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet;
 
@@ -782,12 +783,32 @@ PluginSpecPrivate *PluginManagerPrivate::privateSpec(PluginSpec *spec)
     return spec->d;
 }
 
+void PluginManagerPrivate::nextDelayedInitialize()
+{
+    while (!delayedInitializeQueue.isEmpty()) {
+        PluginSpec *spec = delayedInitializeQueue.takeFirst();
+        profilingReport(">delayedInitialize", spec);
+        bool delay = spec->d->delayedInitialize();
+        profilingReport("<delayedInitialize", spec);
+        if (delay)
+            break; // do next delayedInitialize after a delay
+    }
+    if (delayedInitializeQueue.isEmpty()) {
+        delete delayedInitializeTimer;
+        delayedInitializeTimer = 0;
+    } else {
+        delayedInitializeTimer->start();
+    }
+}
+
 /*!
     \fn PluginManagerPrivate::PluginManagerPrivate(PluginManager *pluginManager)
     \internal
 */
 PluginManagerPrivate::PluginManagerPrivate(PluginManager *pluginManager) :
     extension(QLatin1String("xml")),
+    delayedInitializeTimer(0),
+    shutdownEventLoop(0),
     m_profileElapsedMS(0),
     m_profilingVerbosity(0),
     settings(0),
@@ -849,6 +870,11 @@ void PluginManagerPrivate::readSettings()
 */
 void PluginManagerPrivate::stopAll()
 {
+    if (delayedInitializeTimer && delayedInitializeTimer->isActive()) {
+        delayedInitializeTimer->stop();
+        delete delayedInitializeTimer;
+        delayedInitializeTimer = 0;
+    }
     QList<PluginSpec *> queue = loadQueue();
     foreach (PluginSpec *spec, queue) {
         loadPlugin(spec, PluginSpec::Stopped);
@@ -941,9 +967,19 @@ void PluginManagerPrivate::loadPlugins()
     QListIterator<PluginSpec *> it(queue);
     it.toBack();
     while (it.hasPrevious()) {
-        loadPlugin(it.previous(), PluginSpec::Running);
+        PluginSpec *spec = it.previous();
+        loadPlugin(spec, PluginSpec::Running);
+        if (spec->state() == PluginSpec::Running)
+            delayedInitializeQueue.append(spec);
     }
     emit q->pluginsChanged();
+
+    delayedInitializeTimer = new QTimer;
+    delayedInitializeTimer->setInterval(DELAYED_INITIALIZE_INTERVAL);
+    delayedInitializeTimer->setSingleShot(true);
+    connect(delayedInitializeTimer, SIGNAL(timeout()),
+            this, SLOT(nextDelayedInitialize()));
+    delayedInitializeTimer->start();
 }
 
 /*!
diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h
index 95f1db47c0424615f085cb8dd6382b54ad8161cc..be33e8ad793fdf94afa49c02a90808e082f5d44d 100644
--- a/src/libs/extensionsystem/pluginmanager_p.h
+++ b/src/libs/extensionsystem/pluginmanager_p.h
@@ -42,6 +42,7 @@
 
 QT_BEGIN_NAMESPACE
 class QTime;
+class QTimer;
 class QSettings;
 class QEventLoop;
 QT_END_NAMESPACE
@@ -90,6 +91,10 @@ public:
     QStringList defaultDisabledPlugins;
     QStringList disabledPlugins;
     QStringList forceEnabledPlugins;
+    // delayed initialization
+    QTimer *delayedInitializeTimer;
+    QList<PluginSpec *> delayedInitializeQueue;
+    // ansynchronous shutdown
     QList<PluginSpec *> asynchronousPlugins; // plugins that have requested async shutdown
     QEventLoop *shutdownEventLoop; // used for async shutdown
 
@@ -109,6 +114,7 @@ public:
     static PluginSpecPrivate *privateSpec(PluginSpec *spec);
 
 private slots:
+    void nextDelayedInitialize();
     void asyncShutdownFinished();
 
 private:
diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp
index eed4413b952969f7bc35dc45dd483326e74f6580..57c58992037af98005725ffc2d57711616dce5ca 100644
--- a/src/libs/extensionsystem/pluginspec.cpp
+++ b/src/libs/extensionsystem/pluginspec.cpp
@@ -1013,6 +1013,25 @@ bool PluginSpecPrivate::initializeExtensions()
     return true;
 }
 
+/*!
+    \fn bool PluginSpecPrivate::delayedInitialize()
+    \internal
+*/
+bool PluginSpecPrivate::delayedInitialize()
+{
+    if (hasError)
+        return false;
+    if (state != PluginSpec::Running) {
+        return false;
+    }
+    if (!plugin) {
+        errorString = QCoreApplication::translate("PluginSpec", "Internal error: have no plugin instance to perform delayedInitialize");
+        hasError = true;
+        return false;
+    }
+    return plugin->delayedInitialize();
+}
+
 /*!
     \fn bool PluginSpecPrivate::stop()
     \internal
diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h
index 25842ad563cd5d52d714cc8ca3df9b458668f6b3..2ae53438e18054b4df3abbfd9e71ec0e3bb2b708 100644
--- a/src/libs/extensionsystem/pluginspec_p.h
+++ b/src/libs/extensionsystem/pluginspec_p.h
@@ -60,6 +60,7 @@ public:
     bool loadLibrary();
     bool initializePlugin();
     bool initializeExtensions();
+    bool delayedInitialize();
     IPlugin::ShutdownFlag stop();
     void kill();
 
diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp
index 85d49a947889e4924eaa67b6b4d996374bcefa07..3fe8bd193224285c159ef612f83d917fea6d6262 100644
--- a/src/plugins/coreplugin/coreplugin.cpp
+++ b/src/plugins/coreplugin/coreplugin.cpp
@@ -31,13 +31,14 @@
 **************************************************************************/
 
 #include "coreplugin.h"
+#include "designmode.h"
 #include "editmode.h"
 #include "editormanager.h"
-#include "mainwindow.h"
-#include "modemanager.h"
 #include "fileiconprovider.h"
-#include "designmode.h"
+#include "helpmanager.h"
+#include "mainwindow.h"
 #include "mimedatabase.h"
+#include "modemanager.h"
 
 #include <extensionsystem/pluginmanager.h>
 
@@ -105,6 +106,12 @@ void CorePlugin::extensionsInitialized()
     m_mainWindow->extensionsInitialized();
 }
 
+bool CorePlugin::delayedInitialize()
+{
+    HelpManager::instance()->setupHelpManager();
+    return true;
+}
+
 void CorePlugin::remoteCommand(const QStringList & /* options */, const QStringList &args)
 {
     m_mainWindow->openFiles(args, ICore::SwitchMode);
diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h
index b3f27a2bd98e666ba5ad27678710c67998dca230..947abf800f61766b2c3f693417b66b186680ff1e 100644
--- a/src/plugins/coreplugin/coreplugin.h
+++ b/src/plugins/coreplugin/coreplugin.h
@@ -50,10 +50,11 @@ public:
     CorePlugin();
     ~CorePlugin();
 
-    virtual bool initialize(const QStringList &arguments, QString *errorMessage = 0);
-    virtual void extensionsInitialized();
-    virtual ShutdownFlag aboutToShutdown();
-    virtual void remoteCommand(const QStringList & /* options */, const QStringList &args);
+    bool initialize(const QStringList &arguments, QString *errorMessage = 0);
+    void extensionsInitialized();
+    bool delayedInitialize();
+    ShutdownFlag aboutToShutdown();
+    void remoteCommand(const QStringList & /* options */, const QStringList &args);
 
 public slots:
     void fileOpenRequest(const QString&);
diff --git a/src/plugins/coreplugin/helpmanager.cpp b/src/plugins/coreplugin/helpmanager.cpp
index f32032488ba94b4fc38d40d3ec60802c37ddb192..7f54267e0b08aaafafadf4645d25f5f39293664c 100644
--- a/src/plugins/coreplugin/helpmanager.cpp
+++ b/src/plugins/coreplugin/helpmanager.cpp
@@ -40,7 +40,6 @@
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 #include <QtCore/QStringList>
-#include <QtCore/QTimer>
 
 #include <QtHelp/QHelpEngineCore>
 
@@ -91,7 +90,6 @@ HelpManager::HelpManager(QObject *parent) :
 {
     Q_ASSERT(!m_instance);
     m_instance = this;
-    connect(Core::ICore::instance(), SIGNAL(coreOpened()), SLOT(delayedSetupHelpManager()));
 }
 
 HelpManager::~HelpManager()
@@ -102,11 +100,6 @@ HelpManager::~HelpManager()
     delete d;
 }
 
-void HelpManager::delayedSetupHelpManager()
-{
-    QTimer::singleShot(100, this, SLOT(setupHelpManager()));
-}
-
 HelpManager *HelpManager::instance()
 {
     Q_ASSERT(m_instance);
diff --git a/src/plugins/coreplugin/helpmanager.h b/src/plugins/coreplugin/helpmanager.h
index f72faa5d20e28d403966a63a495544a37b508a88..90924ae52eb0c837dcddd3015673e5a3183d87b2 100644
--- a/src/plugins/coreplugin/helpmanager.h
+++ b/src/plugins/coreplugin/helpmanager.h
@@ -46,6 +46,10 @@ QT_FORWARD_DECLARE_CLASS(QUrl)
 namespace Core {
 struct HelpManagerPrivate;
 
+namespace Internal {
+class CorePlugin;
+}
+
 class CORE_EXPORT HelpManager : public QObject
 {
     Q_OBJECT
@@ -91,13 +95,11 @@ signals:
     void collectionFileChanged();
     void helpRequested(const QUrl &url);
 
-private slots:
-    void delayedSetupHelpManager();
-    void setupHelpManager();
-
 private:
+    void setupHelpManager();
     void verifyDocumenation();
     HelpManagerPrivate *d;
+    friend class Internal::CorePlugin; // setupHelpManager
 };
 
 }   // Core
diff --git a/src/plugins/locator/locatorplugin.cpp b/src/plugins/locator/locatorplugin.cpp
index 9291901635dd7c6661afa022f1aaad4856d526c4..868135e3d1cc85cf1cb72e81763f5cc4d744b853 100644
--- a/src/plugins/locator/locatorplugin.cpp
+++ b/src/plugins/locator/locatorplugin.cpp
@@ -139,7 +139,6 @@ bool LocatorPlugin::initialize(const QStringList &, QString *)
 
     addAutoReleasedObject(new LocatorFiltersFilter(this, m_locatorWidget));
 
-    connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(startSettingsLoad()));
     return true;
 }
 
@@ -167,10 +166,11 @@ void LocatorPlugin::extensionsInitialized()
     setFilters(m_filters);
 }
 
-void LocatorPlugin::startSettingsLoad()
+bool LocatorPlugin::delayedInitialize()
 {
     connect(&m_loadWatcher, SIGNAL(finished()), this, SLOT(settingsLoaded()));
     m_loadWatcher.setFuture(QtConcurrent::run(this, &LocatorPlugin::loadSettings));
+    return true;
 }
 
 void LocatorPlugin::loadSettings()
diff --git a/src/plugins/locator/locatorplugin.h b/src/plugins/locator/locatorplugin.h
index 09e6e140b21c4b8f3ef6049edb96514ac879f690..59ca5164449fcd0f4d0634944598fc7807dcc37d 100644
--- a/src/plugins/locator/locatorplugin.h
+++ b/src/plugins/locator/locatorplugin.h
@@ -63,6 +63,7 @@ public:
 
     bool initialize(const QStringList &arguments, QString *errorMessage);
     void extensionsInitialized();
+    bool delayedInitialize();
 
     QList<ILocatorFilter*> filters();
     QList<ILocatorFilter*> customFilters();
@@ -77,7 +78,6 @@ public slots:
     void openLocator();
 
 private slots:
-    void startSettingsLoad();
     void settingsLoaded();
     void updatePlaceholderText(Core::Command *command = 0);
 
diff --git a/src/plugins/qtsupport/qtsupportplugin.cpp b/src/plugins/qtsupport/qtsupportplugin.cpp
index 84a19b1d72446a20461a8b82319a76e2a7807b57..21426016ded0876e5748dd6d7c7d4a518f38a645 100644
--- a/src/plugins/qtsupport/qtsupportplugin.cpp
+++ b/src/plugins/qtsupport/qtsupportplugin.cpp
@@ -80,7 +80,11 @@ bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMes
 void QtSupportPlugin::extensionsInitialized()
 {
     QtVersionManager::instance()->extensionsInitialized();
+}
 
+bool QtSupportPlugin::delayedInitialize()
+{
+    return QtVersionManager::instance()->delayedInitialize();
 }
 
 Q_EXPORT_PLUGIN(QtSupportPlugin)
diff --git a/src/plugins/qtsupport/qtsupportplugin.h b/src/plugins/qtsupport/qtsupportplugin.h
index 12726fda01ffb105f91e68f3911687c5517019b9..8ea327febdeb90b175f8bcadce5b687f77c7533e 100644
--- a/src/plugins/qtsupport/qtsupportplugin.h
+++ b/src/plugins/qtsupport/qtsupportplugin.h
@@ -49,6 +49,7 @@ class QtSupportPlugin : public ExtensionSystem::IPlugin
 public:
     bool initialize(const QStringList &arguments, QString *errorMessage);
     void extensionsInitialized();
+    bool delayedInitialize();
 
 private slots:
 #ifdef WITH_TESTS
diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp
index bb8242ca77ed9ece028678a690985b28f47fdf99..757cc131afee700d38bbb015e5626bd4a5c6718f 100644
--- a/src/plugins/qtsupport/qtversionmanager.cpp
+++ b/src/plugins/qtsupport/qtversionmanager.cpp
@@ -138,10 +138,15 @@ void QtVersionManager::extensionsInitialized()
         findSystemQt();
     }
 
-    connect(Core::ICore::instance(), SIGNAL(coreOpened()), this, SLOT(delayedUpdateDocumentation()));
     saveQtVersions();
 }
 
+bool QtVersionManager::delayedInitialize()
+{
+    updateDocumentation();
+    return true;
+}
+
 QtVersionManager::~QtVersionManager()
 {
     qDeleteAll(m_versions);
@@ -513,11 +518,6 @@ void QtVersionManager::updateDumpFor(const Utils::FileName &qmakeCommand)
     emit dumpUpdatedFor(qmakeCommand);
 }
 
-void QtVersionManager::delayedUpdateDocumentation()
-{
-    QTimer::singleShot(100, this, SLOT(updateDocumentation()));
-}
-
 int QtVersionManager::getUniqueId()
 {
     return m_idcount++;
diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h
index 611d82f379ff4f94e589701be8a33f9d09c647ca..97690293adb9fdfd0bed1fc841504b59f577dc89 100644
--- a/src/plugins/qtsupport/qtversionmanager.h
+++ b/src/plugins/qtsupport/qtversionmanager.h
@@ -62,6 +62,7 @@ public:
     QtVersionManager();
     ~QtVersionManager();
     void extensionsInitialized();
+    bool delayedInitialize();
 
     // This will *always* return at least one (Qt in Path), even if that is
     // unconfigured.
@@ -110,10 +111,6 @@ signals:
 public slots:
     void updateDumpFor(const Utils::FileName &qmakeCommand);
 
-private slots:
-    void delayedUpdateDocumentation();
-    void updateDocumentation();
-
 private:
     // This function is really simplistic...
     static bool equals(BaseQtVersion *a, BaseQtVersion *b);
@@ -130,6 +127,7 @@ private:
     void findSystemQt();
     void updateFromInstaller();
     void saveQtVersions();
+    void updateDocumentation();
     // Used by QtOptionsPage
     void setNewQtVersions(QList<BaseQtVersion *> newVersions);
     // Used by QtVersion