diff --git a/src/components/Map/Map.component.tsx b/src/components/Map/Map.component.tsx
index 67d4d216c793458cefe6cd83af70a72989112876..67b7187c64b3d5a96784e8e713ed4ba6747d02c0 100644
--- a/src/components/Map/Map.component.tsx
+++ b/src/components/Map/Map.component.tsx
@@ -2,6 +2,7 @@
 import { Drawer } from '@/components/Map/Drawer';
 import { Legend } from '@/components/Map/Legend';
 import { MapViewer } from '@/components/Map/MapViewer';
+import { MapLoader } from '@/components/Map/MapLoader/MapLoader.component';
 import { MapAdditionalActions } from './MapAdditionalActions';
 import { MapAdditionalOptions } from './MapAdditionalOptions';
 import { PluginsDrawer } from './PluginsDrawer';
@@ -18,6 +19,7 @@ export const Map = (): JSX.Element => {
       <PluginsDrawer />
       <Legend />
       <MapAdditionalActions />
+      <MapLoader />
     </div>
   );
 };
diff --git a/src/components/Map/MapLoader/MapLoader.component.test.tsx b/src/components/Map/MapLoader/MapLoader.component.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..eb35db6b6bfbafe153929763e5b5dffbe9e5069a
--- /dev/null
+++ b/src/components/Map/MapLoader/MapLoader.component.test.tsx
@@ -0,0 +1,107 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import {
+  getReduxWrapperWithStore,
+  InitialStoreState,
+} from '@/utils/testing/getReduxWrapperWithStore';
+import { StoreType } from '@/redux/store';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import { newReactionsLoadingSelector } from '@/redux/newReactions/newReactions.selectors';
+import { modelElementsLoadingSelector } from '@/redux/modelElements/modelElements.selector';
+import { isDrawerOpenSelector } from '@/redux/drawer/drawer.selectors';
+import { vectorRenderingSelector } from '@/redux/models/models.selectors';
+import {
+  arrowTypesLoadingSelector,
+  bioShapesLoadingSelector,
+  lineTypesLoadingSelector,
+} from '@/redux/shapes/shapes.selectors';
+import { layersLoadingSelector } from '@/redux/layers/layers.selectors';
+import { MapLoader } from './MapLoader.component';
+
+jest.mock('../../../redux/hooks/useAppSelector', () => ({
+  useAppSelector: jest.fn(),
+}));
+type SelectorFunction = (state: never) => string | boolean;
+
+const renderComponent = (initialStore?: InitialStoreState): { store: StoreType } => {
+  const { Wrapper, store } = getReduxWrapperWithStore(initialStore);
+
+  return (
+    render(
+      <Wrapper>
+        <MapLoader />
+      </Wrapper>,
+    ),
+    {
+      store,
+    }
+  );
+};
+
+describe('MapLoader', () => {
+  const mockUseAppSelector = useAppSelector as jest.Mock;
+
+  afterEach(() => {
+    jest.clearAllMocks();
+  });
+
+  it('should not render the LoadingIndicator when no data is loading', () => {
+    mockUseAppSelector.mockImplementation(selector => {
+      const selectorMap = new Map<SelectorFunction, string | boolean>([
+        [newReactionsLoadingSelector, 'succeeded'],
+        [modelElementsLoadingSelector, 'succeeded'],
+        [vectorRenderingSelector, true],
+        [bioShapesLoadingSelector, 'succeeded'],
+        [lineTypesLoadingSelector, 'succeeded'],
+        [arrowTypesLoadingSelector, 'succeeded'],
+        [layersLoadingSelector, 'succeeded'],
+        [isDrawerOpenSelector, false],
+      ]);
+
+      return selectorMap.get(selector) ?? false;
+    });
+    renderComponent();
+
+    expect(screen.queryByTestId('loading-indicator')).not.toBeInTheDocument();
+  });
+
+  it('should render the LoadingIndicator when vectorRendering is true and data is loading', () => {
+    mockUseAppSelector.mockImplementation(selector => {
+      const selectorMap = new Map<SelectorFunction, string | boolean>([
+        [newReactionsLoadingSelector, 'pending'],
+        [modelElementsLoadingSelector, 'succeeded'],
+        [vectorRenderingSelector, true],
+        [bioShapesLoadingSelector, 'succeeded'],
+        [lineTypesLoadingSelector, 'succeeded'],
+        [arrowTypesLoadingSelector, 'succeeded'],
+        [layersLoadingSelector, 'succeeded'],
+        [isDrawerOpenSelector, false],
+      ]);
+
+      return selectorMap.get(selector) ?? false;
+    });
+    renderComponent();
+
+    expect(screen.queryByTestId('loading-indicator')).toBeInTheDocument();
+  });
+
+  it('should not render the LoadingIndicator when vectorRendering is false even when data is loading', () => {
+    mockUseAppSelector.mockImplementation(selector => {
+      const selectorMap = new Map<SelectorFunction, string | boolean>([
+        [newReactionsLoadingSelector, 'pending'],
+        [modelElementsLoadingSelector, 'succeeded'],
+        [vectorRenderingSelector, false],
+        [bioShapesLoadingSelector, 'succeeded'],
+        [lineTypesLoadingSelector, 'succeeded'],
+        [arrowTypesLoadingSelector, 'succeeded'],
+        [layersLoadingSelector, 'succeeded'],
+        [isDrawerOpenSelector, false],
+      ]);
+
+      return selectorMap.get(selector) ?? false;
+    });
+    renderComponent();
+
+    expect(screen.queryByTestId('loading-indicator')).not.toBeInTheDocument();
+  });
+});
diff --git a/src/components/Map/MapLoader/MapLoader.component.tsx b/src/components/Map/MapLoader/MapLoader.component.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..fc457e0b62d735e95569b41fdbe41b598638f15c
--- /dev/null
+++ b/src/components/Map/MapLoader/MapLoader.component.tsx
@@ -0,0 +1,50 @@
+import { LoadingIndicator } from '@/shared/LoadingIndicator';
+import { useMemo } from 'react';
+import { newReactionsLoadingSelector } from '@/redux/newReactions/newReactions.selectors';
+import { modelElementsLoadingSelector } from '@/redux/modelElements/modelElements.selector';
+import { vectorRenderingSelector } from '@/redux/models/models.selectors';
+import {
+  arrowTypesLoadingSelector,
+  bioShapesLoadingSelector,
+  lineTypesLoadingSelector,
+} from '@/redux/shapes/shapes.selectors';
+import { layersLoadingSelector } from '@/redux/layers/layers.selectors';
+import './MapLoader.styles.css';
+import { isDrawerOpenSelector } from '@/redux/drawer/drawer.selectors';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+
+export const MapLoader = (): JSX.Element => {
+  const reactionsFetching = useAppSelector(newReactionsLoadingSelector);
+  const modelElementsFetching = useAppSelector(modelElementsLoadingSelector);
+  const vectorRendering = useAppSelector(vectorRenderingSelector);
+  const bioShapesFetching = useAppSelector(bioShapesLoadingSelector);
+  const lineTypesFetching = useAppSelector(lineTypesLoadingSelector);
+  const arrowTypesFetching = useAppSelector(arrowTypesLoadingSelector);
+  const layersLoading = useAppSelector(layersLoadingSelector);
+
+  const isDrawerOpen = useAppSelector(isDrawerOpenSelector);
+
+  const showLoader = useMemo(() => {
+    return [
+      reactionsFetching,
+      modelElementsFetching,
+      bioShapesFetching,
+      lineTypesFetching,
+      arrowTypesFetching,
+      layersLoading,
+    ].includes('pending');
+  }, [
+    reactionsFetching,
+    modelElementsFetching,
+    bioShapesFetching,
+    lineTypesFetching,
+    arrowTypesFetching,
+    layersLoading,
+  ]);
+
+  return (
+    <div className={`map-loader transition-all duration-500 ${isDrawerOpen ? 'move-right' : ''}`}>
+      {vectorRendering && showLoader && <LoadingIndicator width={48} height={48} />}
+    </div>
+  );
+};
diff --git a/src/components/Map/MapLoader/MapLoader.styles.css b/src/components/Map/MapLoader/MapLoader.styles.css
new file mode 100644
index 0000000000000000000000000000000000000000..750e4cb6fdd5ca1f3567fd02979f6ade9f566991
--- /dev/null
+++ b/src/components/Map/MapLoader/MapLoader.styles.css
@@ -0,0 +1,9 @@
+.map-loader {
+  position: absolute;
+  left: 120px;
+  top: 128px;
+}
+
+.map-loader.move-right {
+  left: 550px;
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
index 87f31fcf34f378176ec4fc91d070135875204e5f..43fabc2100dccdca69456cecd7cf1cba462b04cb 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -62,8 +62,10 @@ export const useOlMapReactionsLayer = ({
   const pointToProjection = usePointToProjection();
 
   useEffect(() => {
-    dispatch(getModelElements(currentModelId));
-    dispatch(getNewReactions(currentModelId));
+    if (currentModelId) {
+      dispatch(getModelElements(currentModelId));
+      dispatch(getNewReactions(currentModelId));
+    }
   }, [currentModelId, dispatch]);
 
   const groupedElementsOverlays = useMemo(() => {
diff --git a/src/models/mocks/modelsMock.ts b/src/models/mocks/modelsMock.ts
index 1684bf934c71c5ecf6fc05912aa57e41b7fbc1a2..53dac6b905d13af4459fa88d7a1f9e3fde5f8012 100644
--- a/src/models/mocks/modelsMock.ts
+++ b/src/models/mocks/modelsMock.ts
@@ -474,6 +474,7 @@ export const CORE_PD_MODEL_MOCK: MapModel = {
   modificationDates: [],
   minZoom: 2,
   maxZoom: 9,
+  vectorRendering: true,
 };
 
 export const MODEL_WITH_DESCRIPTION: MapModel = {
diff --git a/src/redux/layers/layers.selectors.ts b/src/redux/layers/layers.selectors.ts
index 987ec4ac2855d7e3c1a30857301034ef4dec7daf..d29698e0254a341147c7bbc16fe83456bb8ca7be 100644
--- a/src/redux/layers/layers.selectors.ts
+++ b/src/redux/layers/layers.selectors.ts
@@ -6,6 +6,8 @@ export const layersSelector = createSelector(
   state => state.layers?.data?.layers || [],
 );
 
+export const layersLoadingSelector = createSelector(rootSelector, state => state.layers.loading);
+
 export const layersVisibilitySelector = createSelector(
   rootSelector,
   state => state.layers?.data?.layersVisibility || {},
diff --git a/src/redux/modelElements/modelElements.selector.ts b/src/redux/modelElements/modelElements.selector.ts
index 54b4a75b00d98355f601dfa2ed2c49c1911f4258..3a9d8b54a29cabdda042e2ec63a3eb0c7465472d 100644
--- a/src/redux/modelElements/modelElements.selector.ts
+++ b/src/redux/modelElements/modelElements.selector.ts
@@ -5,3 +5,8 @@ export const modelElementsSelector = createSelector(
   rootSelector,
   state => state.modelElements.data,
 );
+
+export const modelElementsLoadingSelector = createSelector(
+  rootSelector,
+  state => state.modelElements.loading,
+);
diff --git a/src/redux/newReactions/newReactions.selectors.ts b/src/redux/newReactions/newReactions.selectors.ts
index 4dc2babe517c9850b03cf090644ebe2389550dcd..146bbc85efe9c374b3c4f7d5118e6651cd5d3a57 100644
--- a/src/redux/newReactions/newReactions.selectors.ts
+++ b/src/redux/newReactions/newReactions.selectors.ts
@@ -3,6 +3,11 @@ import { rootSelector } from '../root/root.selectors';
 
 export const newReactionsSelector = createSelector(rootSelector, state => state.newReactions);
 
+export const newReactionsLoadingSelector = createSelector(
+  newReactionsSelector,
+  state => state.loading,
+);
+
 export const newReactionsDataSelector = createSelector(
   newReactionsSelector,
   reactions => reactions.data || [],
diff --git a/src/redux/shapes/shapes.selectors.ts b/src/redux/shapes/shapes.selectors.ts
index cdd4fa160ae29d1a0197c847a0d20127c394365a..d23c9a97d97a744f6150d30757d2706dbeaa6a96 100644
--- a/src/redux/shapes/shapes.selectors.ts
+++ b/src/redux/shapes/shapes.selectors.ts
@@ -8,12 +8,27 @@ export const bioShapesSelector = createSelector(
   shapes => shapes.bioShapesState.data,
 );
 
+export const bioShapesLoadingSelector = createSelector(
+  shapesSelector,
+  shapes => shapes.bioShapesState.loading,
+);
+
 export const lineTypesSelector = createSelector(
   shapesSelector,
   shapes => shapes.lineTypesState.data || {},
 );
 
+export const lineTypesLoadingSelector = createSelector(
+  shapesSelector,
+  shapes => shapes.lineTypesState.loading,
+);
+
 export const arrowTypesSelector = createSelector(
   shapesSelector,
   shapes => shapes.arrowTypesState.data || {},
 );
+
+export const arrowTypesLoadingSelector = createSelector(
+  shapesSelector,
+  shapes => shapes.arrowTypesState.loading,
+);