diff --git a/__tests__/src/components/PrimaryWindow.test.js b/__tests__/src/components/PrimaryWindow.test.js
index 5cdcccfe63b6c8f4ec3125a91dc6c9ce13a0b619..d9961f9f14ef37777fb13314e9206f0a711996bc 100644
--- a/__tests__/src/components/PrimaryWindow.test.js
+++ b/__tests__/src/components/PrimaryWindow.test.js
@@ -2,8 +2,6 @@ import React from 'react';
 import { shallow } from 'enzyme';
 import { PrimaryWindow } from '../../../src/components/PrimaryWindow';
 import WindowSideBar from '../../../src/containers/WindowSideBar';
-import WindowViewer from '../../../src/containers/WindowViewer';
-import GalleryView from '../../../src/containers/GalleryView';
 import CollectionDialog from '../../../src/containers/CollectionDialog';
 
 /** create wrapper */
@@ -26,17 +24,22 @@ describe('PrimaryWindow', () => {
     const wrapper = createWrapper();
     expect(wrapper.find(WindowSideBar)).toHaveLength(1);
   });
-  it('should render nothing if manifest is still f etching', () => {
+  it('should render nothing if manifest is still fetching', () => {
     const wrapper = createWrapper({ isFetching: true });
-    expect(wrapper.find(WindowViewer)).toHaveLength(0);
+    const suspenseComponent = wrapper.find('Suspense');
+    expect(suspenseComponent).toEqual({});
   });
   it('should render <WindowViewer> if manifest is present', () => {
     const wrapper = createWrapper({ isFetching: false });
-    expect(wrapper.find(WindowViewer)).toHaveLength(1);
+    const suspenseComponent = wrapper.find('Suspense');
+    const lazyComponent = suspenseComponent.dive().find('lazy');
+    expect(lazyComponent.type().displayName).toBe('WindowViewer');
   });
   it('should render <GalleryView> if manifest is present and view is gallery', () => {
     const wrapper = createWrapper({ isFetching: false, view: 'gallery', windowId: 'window-2' });
-    expect(wrapper.find(GalleryView)).toHaveLength(1);
+    const suspenseComponent = wrapper.find('Suspense');
+    const lazyComponent = suspenseComponent.dive().find('lazy');
+    expect(lazyComponent.type().displayName).toBe('GalleryView');
   });
   it('should render <CollectionDialog> and <SelectCollection> if manifest is collection and isCollectionDialogVisible', () => {
     const wrapper = createWrapper({ isCollection: true, isCollectionDialogVisible: true });
diff --git a/__tests__/src/components/WindowViewer.test.js b/__tests__/src/components/WindowViewer.test.js
index 373ca1d41366e07eef2a0b194a9d89f0056bff55..2aa83431727aec29c720eefcb53da39cee3c1eb3 100644
--- a/__tests__/src/components/WindowViewer.test.js
+++ b/__tests__/src/components/WindowViewer.test.js
@@ -1,27 +1,34 @@
 import React from 'react';
 import { shallow } from 'enzyme';
 import { WindowViewer } from '../../../src/components/WindowViewer';
-import OSDViewer from '../../../src/containers/OpenSeadragonViewer';
 import WindowCanvasNavigationControls from '../../../src/containers/WindowCanvasNavigationControls';
 
 /** create wrapper */
-function createWrapper(props) {
+function createWrapper(props, suspenseFallback) {
   return shallow(
     <WindowViewer
       windowId="xyz"
       {...props}
     />,
+    { suspenseFallback },
   );
 }
 
 describe('WindowViewer', () => {
   let wrapper;
-  it('renders properly', () => {
-    wrapper = createWrapper();
-    expect(wrapper.matchesElement(
-      <OSDViewer>
-        <WindowCanvasNavigationControls />
-      </OSDViewer>,
-    )).toBe(true);
+  describe('when lazy imorts have not loaded', () => {
+    it('renders fallback', () => {
+      wrapper = createWrapper({}, true);
+      const suspenseComponent = wrapper.find('Suspense').dive();
+      expect(suspenseComponent.find('div').length).toBe(1);
+    });
+  });
+  describe('when lazy imorts have loaded', () => {
+    it('renders expected components', () => {
+      wrapper = createWrapper({}, false);
+      const suspenseComponent = wrapper.find('Suspense').dive();
+      expect(suspenseComponent.find('lazy').props().windowId).toBe('xyz');
+      expect(suspenseComponent.find(WindowCanvasNavigationControls).props().windowId).toBe('xyz');
+    });
   });
 });
diff --git a/src/components/PrimaryWindow.js b/src/components/PrimaryWindow.js
index aeda8cfe493552e2fb261bf6384d8213e7cba11a..05a9c2f55ac9bc13c4876183db250f65f3db644e 100644
--- a/src/components/PrimaryWindow.js
+++ b/src/components/PrimaryWindow.js
@@ -1,15 +1,18 @@
-import React, { Component, lazy } from 'react';
+import React, { Component, lazy, Suspense } from 'react';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
 import WindowSideBar from '../containers/WindowSideBar';
-import WindowViewer from '../containers/WindowViewer';
-import GalleryView from '../containers/GalleryView';
 import CompanionArea from '../containers/CompanionArea';
 import CollectionDialog from '../containers/CollectionDialog';
 import ns from '../config/css-ns';
 
+const GalleryView = lazy(() => import('../containers/GalleryView'));
 const SelectCollection = lazy(() => import('../containers/SelectCollection'));
+const WindowViewer = lazy(() => import('../containers/WindowViewer'));
+
+GalleryView.displayName = 'GalleryView';
 SelectCollection.displayName = 'SelectCollection';
+WindowViewer.displayName = 'WindowViewer';
 
 /**
  * WindowMiddleContent - component that renders the "middle" area of the
@@ -61,7 +64,9 @@ export class PrimaryWindow extends Component {
       <div className={classNames(ns('primary-window'), classes.primaryWindow)}>
         <WindowSideBar windowId={windowId} />
         <CompanionArea windowId={windowId} position="left" />
-        {this.renderViewer()}
+        <Suspense fallback={<div />}>
+          {this.renderViewer()}
+        </Suspense>
       </div>
     );
   }
diff --git a/src/components/WindowViewer.js b/src/components/WindowViewer.js
index 7a7d1acc697ea00338b6ce34db34dad0c2316cb9..667b99bff1fd32d65a8081972e3ab1a21283ece0 100644
--- a/src/components/WindowViewer.js
+++ b/src/components/WindowViewer.js
@@ -1,8 +1,9 @@
-import React, { Component } from 'react';
+import React, { Component, lazy, Suspense } from 'react';
 import PropTypes from 'prop-types';
-import OSDViewer from '../containers/OpenSeadragonViewer';
 import WindowCanvasNavigationControls from '../containers/WindowCanvasNavigationControls';
 
+const OSDViewer = lazy(() => import('../containers/OpenSeadragonViewer'));
+
 /**
  * Represents a WindowViewer in the mirador workspace. Responsible for mounting
  * OSD and Navigation
@@ -33,11 +34,13 @@ export class WindowViewer extends Component {
     }
 
     return (
-      <OSDViewer
-        windowId={windowId}
-      >
-        <WindowCanvasNavigationControls windowId={windowId} />
-      </OSDViewer>
+      <Suspense fallback={<div />}>
+        <OSDViewer
+          windowId={windowId}
+        >
+          <WindowCanvasNavigationControls windowId={windowId} />
+        </OSDViewer>
+      </Suspense>
     );
   }
 }