diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp
index 0390d493cd0288a2675abc559396817a6cf55196..52a17f7416b46dc5dda303ad22a6a37859c8c6dc 100644
--- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.cpp
@@ -154,6 +154,15 @@ void QmlProfilerDataModel::addEvent(const QmlEvent &event)
     d->eventStream << event;
 }
 
+void QmlProfilerDataModel::addEvents(const QVector<QmlEvent> &events)
+{
+    Q_D(QmlProfilerDataModel);
+    for (const QmlEvent &event : events) {
+        d->modelManager->dispatch(event, d->eventTypes[event.typeIndex()]);
+        d->eventStream << event;
+    }
+}
+
 void QmlProfilerDataModel::clear()
 {
     Q_D(QmlProfilerDataModel);
diff --git a/src/plugins/qmlprofiler/qmlprofilerdatamodel.h b/src/plugins/qmlprofiler/qmlprofilerdatamodel.h
index 5bb97abea4f7f0c5e175594398b2851a4208cec2..4698dac409e1ffe31a2f9ce06cf50687cb7724e2 100644
--- a/src/plugins/qmlprofiler/qmlprofilerdatamodel.h
+++ b/src/plugins/qmlprofiler/qmlprofilerdatamodel.h
@@ -52,6 +52,7 @@ public:
     void clear();
     bool isEmpty() const;
     void addEvent(const QmlEvent &event);
+    void addEvents(const QVector<QmlEvent> &events);
     void replayEvents(qint64 startTime, qint64 endTime,
                       QmlProfilerModelManager::EventLoader loader) const;
     void finalize();
diff --git a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
index 4c933040e6487fa2a0b62bc59e0096282685bbd1..6a236a12f9d8bd7282dc5301accc98bd755abba3 100644
--- a/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilermodelmanager.cpp
@@ -378,8 +378,8 @@ void QmlProfilerModelManager::load(const QString &filename)
     connect(reader, &QmlProfilerFileReader::notesLoaded,
             d->notesModel, &QmlProfilerNotesModel::setNotes);
 
-    connect(reader, &QmlProfilerFileReader::qmlEventLoaded,
-            d->model, &QmlProfilerDataModel::addEvent);
+    connect(reader, &QmlProfilerFileReader::qmlEventsLoaded,
+            d->model, &QmlProfilerDataModel::addEvents);
 
     connect(reader, &QmlProfilerFileReader::success, this, [this, reader]() {
         d->traceTime->setTime(reader->traceStart(), reader->traceEnd());
diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
index 67188e32fa1aee5d5ca0ba3e54e13da12dda3c80..ec9195bbd0416c09d20dbf9133c3c80669c48bb3 100644
--- a/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertracefile.cpp
@@ -123,7 +123,7 @@ QmlProfilerFileReader::QmlProfilerFileReader(QObject *parent) :
     m_loadedFeatures(0)
 {
     static int meta[] = {
-        qRegisterMetaType<QmlEvent>(),
+        qRegisterMetaType<QVector<QmlEvent> >(),
         qRegisterMetaType<QVector<QmlEventType> >(),
         qRegisterMetaType<QVector<QmlNote> >()
     };
@@ -248,7 +248,9 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
     emit notesLoaded(m_notes);
     updateProgress(device);
 
-    QmlEvent event;
+    const int eventBufferLength = 1024;
+    QVector<QmlEvent> eventBuffer(eventBufferLength);
+    int eventBufferIndex = 0;
     while (!stream.atEnd()) {
         stream >> data;
         buffer.setData(qUncompress(data));
@@ -256,6 +258,7 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
         while (!buffer.atEnd()) {
             if (isCanceled())
                 return false;
+            QmlEvent &event = eventBuffer[eventBufferIndex];
             bufferStream >> event;
             if (bufferStream.status() == QDataStream::Ok) {
                 if (event.typeIndex() >= m_eventTypes.length()) {
@@ -263,7 +266,6 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
                     return false;
                 }
                 m_loadedFeatures |= (1ULL << m_eventTypes[event.typeIndex()].feature());
-                emit qmlEventLoaded(event);
             } else if (bufferStream.status() == QDataStream::ReadPastEnd) {
                 break; // Apparently EOF is a character so we end up here after the last event.
             } else if (bufferStream.status() == QDataStream::ReadCorruptData) {
@@ -272,10 +274,16 @@ bool QmlProfilerFileReader::loadQzt(QIODevice *device)
             } else {
                 Q_UNREACHABLE();
             }
+            if (++eventBufferIndex == eventBufferLength) {
+                emit qmlEventsLoaded(eventBuffer);
+                eventBufferIndex = 0;
+            }
         }
         buffer.close();
         updateProgress(device);
     }
+    eventBuffer.resize(eventBufferIndex);
+    emit qmlEventsLoaded(eventBuffer);
     emit success();
     return true;
 }
@@ -499,8 +507,7 @@ void QmlProfilerFileReader::loadEvents(QXmlStreamReader &stream)
                 std::sort(events.begin(), events.end(), [](const QmlEvent &a, const QmlEvent &b) {
                     return a.timestamp() < b.timestamp();
                 });
-                foreach (const QmlEvent &event, events)
-                    emit qmlEventLoaded(event);
+                emit qmlEventsLoaded(events);
                 return;
             }
             break;
diff --git a/src/plugins/qmlprofiler/qmlprofilertracefile.h b/src/plugins/qmlprofiler/qmlprofilertracefile.h
index 937ec1de298782f92f2b0353ea0cc6376acdf28d..b705f07e689412a183c15b990a28b7c46ce7d049 100644
--- a/src/plugins/qmlprofiler/qmlprofilertracefile.h
+++ b/src/plugins/qmlprofiler/qmlprofilertracefile.h
@@ -62,7 +62,7 @@ public:
 signals:
     void typesLoaded(const QVector<QmlProfiler::QmlEventType> &types);
     void notesLoaded(const QVector<QmlProfiler::QmlNote> &notes);
-    void qmlEventLoaded(const QmlProfiler::QmlEvent &event);
+    void qmlEventsLoaded(const QVector<QmlProfiler::QmlEvent> &event);
     void error(const QString &error);
     void success();