diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp
index 1ed939ba3..d04bc97fa 100644
--- a/src/libslic3r/Technologies.hpp
+++ b/src/libslic3r/Technologies.hpp
@@ -59,6 +59,7 @@
 // Enable G-Code viewer
 #define ENABLE_GCODE_VIEWER (1 && ENABLE_2_3_0_ALPHA1)
 #define ENABLE_GCODE_VIEWER_DEBUG_OUTPUT (0 && ENABLE_GCODE_VIEWER)
+#define ENABLE_GCODE_VIEWER_STATISTICS (0 && ENABLE_2_3_0_ALPHA1)
 
 
 #endif // _prusaslicer_technologies_h_
diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp
index 268b998fa..7426eafc9 100644
--- a/src/slic3r/GUI/GCodeViewer.cpp
+++ b/src/slic3r/GUI/GCodeViewer.cpp
@@ -7,12 +7,13 @@
 #include "PresetBundle.hpp"
 #include "Camera.hpp"
 #include "I18N.hpp"
-#if ENABLE_GCODE_VIEWER
 #include "GUI_Utils.hpp"
 #include "DoubleSlider.hpp"
 #include "GLCanvas3D.hpp"
 #include "libslic3r/Model.hpp"
-#endif // ENABLE_GCODE_VIEWER
+#if ENABLE_GCODE_VIEWER_STATISTICS
+#include <imgui/imgui_internal.h>
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 
 #include <GL/glew.h>
 #include <boost/log/trivial.hpp>
@@ -173,7 +174,9 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print&
 
 void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std::vector<std::string>& str_tool_colors)
 {
+#if ENABLE_GCODE_VIEWER_STATISTICS
     auto start_time = std::chrono::high_resolution_clock::now();
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 
     if (m_vertices.vertices_count == 0)
         return;
@@ -212,8 +215,9 @@ void GCodeViewer::refresh(const GCodeProcessor::Result& gcode_result, const std:
         }
     }
 
-    auto end_time = std::chrono::high_resolution_clock::now();
-    std::cout << "refresh: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() << "ms \n";
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    m_statistics.refresh_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time).count();
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 }
 
 void GCodeViewer::reset()
@@ -233,14 +237,25 @@ void GCodeViewer::reset()
     m_layers_zs = std::vector<double>();
     m_layers_z_range = { 0.0, 0.0 };
     m_roles = std::vector<ExtrusionRole>();
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    m_statistics.reset_all();
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 }
 
 void GCodeViewer::render() const
 {
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    m_statistics.reset_opengl();
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
+
     glsafe(::glEnable(GL_DEPTH_TEST));
     render_toolpaths();
     render_shells();
-    render_overlay();
+    render_legend();
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    render_statistics();
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 }
 
 bool GCodeViewer::is_toolpath_move_type_visible(GCodeProcessor::EMoveType type) const
@@ -310,7 +325,9 @@ bool GCodeViewer::init_shaders()
 
 void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
 {
+#if ENABLE_GCODE_VIEWER_STATISTICS
     auto start_time = std::chrono::high_resolution_clock::now();
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 
     // vertex data
     m_vertices.vertices_count = gcode_result.moves.size();
@@ -326,6 +343,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
         }
     }
 
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    m_statistics.vertices_size = vertices_data.size() * sizeof(float);
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
+
     // vertex data -> send to gpu
     glsafe(::glGenBuffers(1, &m_vertices.vbo_id));
     glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_vertices.vbo_id));
@@ -383,6 +404,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
     for (IBuffer& buffer : m_buffers)
     {
         buffer.data_size = buffer.data.size();
+#if ENABLE_GCODE_VIEWER_STATISTICS
+        m_statistics.indices_size += buffer.data_size * sizeof(unsigned int);
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
+
         if (buffer.data_size > 0) {
             glsafe(::glGenBuffers(1, &buffer.ibo_id));
             glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.ibo_id));
@@ -428,8 +453,9 @@ void GCodeViewer::load_toolpaths(const GCodeProcessor::Result& gcode_result)
     std::sort(m_extruder_ids.begin(), m_extruder_ids.end());
     m_extruder_ids.erase(std::unique(m_extruder_ids.begin(), m_extruder_ids.end()), m_extruder_ids.end());
 
-    auto end_time = std::chrono::high_resolution_clock::now();
-    std::cout << "toolpaths generation time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count() << "ms \n";
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    m_statistics.load_time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now() - start_time).count();
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 }
 
 void GCodeViewer::load_shells(const Print& print, bool initialized)
@@ -558,6 +584,10 @@ void GCodeViewer::render_toolpaths() const
                     glsafe(::glEnable(GL_PROGRAM_POINT_SIZE));
                     glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
                     glsafe(::glDisable(GL_PROGRAM_POINT_SIZE));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_points_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -572,6 +602,10 @@ void GCodeViewer::render_toolpaths() const
                     glsafe(::glEnable(GL_PROGRAM_POINT_SIZE));
                     glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
                     glsafe(::glDisable(GL_PROGRAM_POINT_SIZE));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_points_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -586,6 +620,10 @@ void GCodeViewer::render_toolpaths() const
                     glsafe(::glEnable(GL_PROGRAM_POINT_SIZE));
                     glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
                     glsafe(::glDisable(GL_PROGRAM_POINT_SIZE));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_points_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -600,6 +638,10 @@ void GCodeViewer::render_toolpaths() const
                     glsafe(::glEnable(GL_PROGRAM_POINT_SIZE));
                     glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
                     glsafe(::glDisable(GL_PROGRAM_POINT_SIZE));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_points_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -614,6 +656,10 @@ void GCodeViewer::render_toolpaths() const
                     glsafe(::glEnable(GL_PROGRAM_POINT_SIZE));
                     glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
                     glsafe(::glDisable(GL_PROGRAM_POINT_SIZE));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_points_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -628,6 +674,10 @@ void GCodeViewer::render_toolpaths() const
                     glsafe(::glEnable(GL_PROGRAM_POINT_SIZE));
                     glsafe(::glDrawElements(GL_POINTS, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
                     glsafe(::glDisable(GL_PROGRAM_POINT_SIZE));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_points_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -639,6 +689,10 @@ void GCodeViewer::render_toolpaths() const
 
                     set_color(current_program_id, extrusion_color(path));
                     glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_line_strip_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -650,6 +704,10 @@ void GCodeViewer::render_toolpaths() const
 
                     set_color(current_program_id, (m_view_type == EViewType::Feedrate || m_view_type == EViewType::Tool || m_view_type == EViewType::ColorPrint) ? extrusion_color(path) : travel_color(path));
                     glsafe(::glDrawElements(GL_LINE_STRIP, GLsizei(path.last - path.first + 1), GL_UNSIGNED_INT, (const void*)(path.first * sizeof(GLuint))));
+
+#if ENABLE_GCODE_VIEWER_STATISTICS
+                    ++m_statistics.gl_line_strip_calls_count;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
                 }
                 break;
             }
@@ -678,7 +736,7 @@ void GCodeViewer::render_shells() const
 //    glsafe(::glDepthMask(GL_TRUE));
 }
 
-void GCodeViewer::render_overlay() const
+void GCodeViewer::render_legend() const
 {
     static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f);
     static const ImU32 ICON_BORDER_COLOR = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
@@ -692,10 +750,6 @@ void GCodeViewer::render_overlay() const
     ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
     imgui.begin(std::string("Legend"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
 
-    if (ImGui::IsWindowAppearing())
-        // force an extra farme
-        wxGetApp().plater()->get_current_canvas3D()->request_extra_frame();
-
     ImDrawList* draw_list = ImGui::GetWindowDrawList();
 
     auto add_item = [draw_list, &imgui](const std::array<float, 3>& color, const std::string& label) {
@@ -893,6 +947,64 @@ void GCodeViewer::render_overlay() const
     ImGui::PopStyleVar();
 }
 
+#if ENABLE_GCODE_VIEWER_STATISTICS
+void GCodeViewer::render_statistics() const
+{
+    static const ImVec4 ORANGE(1.0f, 0.49f, 0.22f, 1.0f);
+    static const float offset = 250.0f;
+
+    if (!m_legend_enabled || m_roles.empty())
+        return;
+
+    ImGuiWrapper& imgui = *wxGetApp().imgui();
+
+    imgui.begin(std::string("Statistics"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
+    ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
+
+    ImGui::PushStyleColor(ImGuiCol_Text, ORANGE);
+    imgui.text(std::string("Load time:"));
+    ImGui::PopStyleColor();
+    ImGui::SameLine(offset);
+    imgui.text(std::to_string(m_statistics.load_time) + "ms");
+
+    ImGui::PushStyleColor(ImGuiCol_Text, ORANGE);
+    imgui.text(std::string("Resfresh time:"));
+    ImGui::PopStyleColor();
+    ImGui::SameLine(offset);
+    imgui.text(std::to_string(m_statistics.refresh_time) + "ms");
+
+    ImGui::Separator();
+
+    ImGui::PushStyleColor(ImGuiCol_Text, ORANGE);
+    imgui.text(std::string("GL_POINTS calls:"));
+    ImGui::PopStyleColor();
+    ImGui::SameLine(offset);
+    imgui.text(std::to_string(m_statistics.gl_points_calls_count));
+
+    ImGui::PushStyleColor(ImGuiCol_Text, ORANGE);
+    imgui.text(std::string("GL_LINE_STRIP calls:"));
+    ImGui::PopStyleColor();
+    ImGui::SameLine(offset);
+    imgui.text(std::to_string(m_statistics.gl_line_strip_calls_count));
+
+    ImGui::Separator();
+
+    ImGui::PushStyleColor(ImGuiCol_Text, ORANGE);
+    imgui.text(std::string("Vertices:"));
+    ImGui::PopStyleColor();
+    ImGui::SameLine(offset);
+    imgui.text(std::to_string(m_statistics.vertices_size) + " bytes");
+
+    ImGui::PushStyleColor(ImGuiCol_Text, ORANGE);
+    imgui.text(std::string("Indices:"));
+    ImGui::PopStyleColor();
+    ImGui::SameLine(offset);
+    imgui.text(std::to_string(m_statistics.indices_size) + " bytes");
+
+    imgui.end();
+}
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
+
 } // namespace GUI
 } // namespace Slic3r
 
diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp
index d2eb103f6..be239e20c 100644
--- a/src/slic3r/GUI/GCodeViewer.hpp
+++ b/src/slic3r/GUI/GCodeViewer.hpp
@@ -2,7 +2,6 @@
 #define slic3r_GCodeViewer_hpp_
 
 #if ENABLE_GCODE_VIEWER
-
 #include "GLShader.hpp"
 #include "3DScene.hpp"
 #include "libslic3r/GCode/GCodeProcessor.hpp"
@@ -133,6 +132,39 @@ class GCodeViewer
         void reset_ranges() { ranges.reset(); }
     };
 
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    struct Statistics
+    {
+        long long load_time{ 0 };
+        long long refresh_time{ 0 };
+        long long gl_points_calls_count{ 0 };
+        long long gl_line_strip_calls_count{ 0 };
+        long long vertices_size{ 0 };
+        long long indices_size{ 0 };
+
+        void reset_all() {
+            reset_times();
+            reset_opengl();
+            reset_sizes();
+        }
+
+        void reset_times() {
+            load_time = 0;
+            refresh_time = 0;
+        }
+
+        void reset_opengl() {
+            gl_points_calls_count = 0;
+            gl_line_strip_calls_count = 0;
+        }
+
+        void reset_sizes() {
+            vertices_size = 0;
+            indices_size = 0;
+        }
+    };
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
+
 public:
     enum class EViewType : unsigned char
     {
@@ -161,6 +193,9 @@ private:
     Shells m_shells;
     EViewType m_view_type{ EViewType::FeatureType };
     bool m_legend_enabled{ true };
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    mutable Statistics m_statistics;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
 
 public:
     GCodeViewer() = default;
@@ -205,7 +240,10 @@ private:
     void load_shells(const Print& print, bool initialized);
     void render_toolpaths() const;
     void render_shells() const;
-    void render_overlay() const;
+    void render_legend() const;
+#if ENABLE_GCODE_VIEWER_STATISTICS
+    void render_statistics() const;
+#endif // ENABLE_GCODE_VIEWER_STATISTICS
     bool is_visible(ExtrusionRole role) const {
         return role < erCount && (m_extrusions.role_visibility_flags & (1 << role)) != 0;
     }
diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp
index fa38aca47..91b8e3792 100644
--- a/src/slic3r/GUI/GLCanvas3D.cpp
+++ b/src/slic3r/GUI/GLCanvas3D.cpp
@@ -4050,9 +4050,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
         if (m_selection.is_empty())
             m_gizmos.reset_all_states();
 
+#if ENABLE_GCODE_VIEWER
+        m_dirty = true;
+#else
         // Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor hovers over.
         if (m_picking_enabled)
             m_dirty = true;
+#endif // ENABLE_GCODE_VIEWER
     }
     else
         evt.Skip();