diff --git src/wp-admin/css/customize-controls.css src/wp-admin/css/customize-controls.css
index fe82af7..353a69b 100644
--- src/wp-admin/css/customize-controls.css
+++ src/wp-admin/css/customize-controls.css
@@ -3,6 +3,18 @@ body {
 	-webkit-text-size-adjust: 100%;
 }
 
+button.not-a-button {
+	background: transparent;
+	border: none;
+	-webkit-box-shadow: none;
+	box-shadow: none;
+	-webkit-border-radius: 0;
+	border-radius: 0;
+	outline: 0;
+	padding: 0;
+	margin: 0;
+}
+
 #customize-controls a {
 	text-decoration: none;
 }
diff --git src/wp-admin/css/customize-nav-menus.css src/wp-admin/css/customize-nav-menus.css
index 38716c6..35e381f 100644
--- src/wp-admin/css/customize-nav-menus.css
+++ src/wp-admin/css/customize-nav-menus.css
@@ -612,18 +612,6 @@
 	background: transparent;
 }
 
-button.not-a-button {
-	background: transparent;
-	border: none;
-	-webkit-box-shadow: none;
-	box-shadow: none;
-	-webkit-border-radius: 0;
-	border-radius: 0;
-	outline: 0;
-	padding: 0;
-	margin: 0;
-}
-
 #available-menu-items .accordion-section-title button {
 	display: block;
 	width: 28px;
diff --git src/wp-includes/class-wp-customize-manager.php src/wp-includes/class-wp-customize-manager.php
index 485e164..a304b99 100644
--- src/wp-includes/class-wp-customize-manager.php
+++ src/wp-includes/class-wp-customize-manager.php
@@ -191,11 +191,32 @@ final class WP_Customize_Manager {
 		require_once( ABSPATH . WPINC . '/class-wp-customize-panel.php' );
 		require_once( ABSPATH . WPINC . '/class-wp-customize-section.php' );
 		require_once( ABSPATH . WPINC . '/class-wp-customize-control.php' );
-		require_once( ABSPATH . WPINC . '/class-wp-customize-widgets.php' );
-		require_once( ABSPATH . WPINC . '/class-wp-customize-nav-menus.php' );
 
-		$this->widgets = new WP_Customize_Widgets( $this );
-		$this->nav_menus = new WP_Customize_Nav_Menus( $this );
+		/**
+		 * Filter the core Customizer components to load.
+		 *
+		 * This allows Core components to be omitted from being instantiated by
+		 * filtering them out of the array. Note that this filter generally runs
+		 * during the <code>plugins_loaded</code> action, so it cannot be added
+		 * in a theme.
+		 *
+		 * @since 4.4.0
+		 *
+		 * @see WP_Customize_Manager::__construct()
+		 *
+		 * @param array                $components List of core components to load.
+		 * @param WP_Customize_Manager $this       WP_Customize_Manager instance.
+		 */
+		$components = apply_filters( 'customize_loaded_components', array( 'widgets', 'nav_menus' ), $this );
+
+		if ( in_array( 'widgets', $components ) ) {
+			require_once( ABSPATH . WPINC . '/class-wp-customize-widgets.php' );
+			$this->widgets = new WP_Customize_Widgets( $this );
+		}
+		if ( in_array( 'nav_menus', $components ) ) {
+			require_once( ABSPATH . WPINC . '/class-wp-customize-nav-menus.php' );
+			$this->nav_menus = new WP_Customize_Nav_Menus( $this );
+		}
 
 		add_filter( 'wp_die_handler', array( $this, 'wp_die_handler' ) );
 
diff --git tests/phpunit/tests/customize/manager.php tests/phpunit/tests/customize/manager.php
index b9e7f31..6da2d96 100644
--- tests/phpunit/tests/customize/manager.php
+++ tests/phpunit/tests/customize/manager.php
@@ -327,4 +327,63 @@ class Tests_WP_Customize_Manager extends WP_UnitTestCase {
 		$this->assertArrayHasKey( 'save', $data['nonce'] );
 		$this->assertArrayHasKey( 'preview', $data['nonce'] );
 	}
+
+	/**
+	 * @ticket 33552
+	 */
+	function test_customize_loaded_components_filter() {
+		$manager = new WP_Customize_Manager();
+		$this->assertInstanceOf( 'WP_Customize_Widgets', $manager->widgets );
+		$this->assertInstanceOf( 'WP_Customize_Nav_Menus', $manager->nav_menus );
+
+		add_filter( 'customize_loaded_components', array( $this, 'return_array_containing_widgets' ), 10, 2 );
+		$manager = new WP_Customize_Manager();
+		$this->assertInstanceOf( 'WP_Customize_Widgets', $manager->widgets );
+		$this->assertEmpty( $manager->nav_menus );
+		remove_all_filters( 'customize_loaded_components' );
+
+		add_filter( 'customize_loaded_components', array( $this, 'return_array_containing_nav_menus' ), 10, 2 );
+		$manager = new WP_Customize_Manager();
+		$this->assertInstanceOf( 'WP_Customize_Nav_Menus', $manager->nav_menus );
+		$this->assertEmpty( $manager->widgets );
+		remove_all_filters( 'customize_loaded_components' );
+
+		add_filter( 'customize_loaded_components', '__return_empty_array' );
+		$manager = new WP_Customize_Manager();
+		$this->assertEmpty( $manager->widgets );
+		$this->assertEmpty( $manager->nav_menus );
+		remove_all_filters( 'customize_loaded_components' );
+	}
+
+	/**
+	 * @see Tests_WP_Customize_Manager::test_customize_loaded_components_filter()
+	 *
+	 * @param array                $components         Components.
+	 * @param WP_Customize_Manager $customize_manager  Manager.
+	 *
+	 * @return array Components.
+	 */
+	function return_array_containing_widgets( $components, $customize_manager ) {
+		$this->assertInternalType( 'array', $components );
+		$this->assertContains( 'widgets', $components );
+		$this->assertContains( 'nav_menus', $components );
+		$this->assertInternalType( 'array', $components );
+		$this->assertInstanceOf( 'WP_Customize_Manager', $customize_manager );
+		return array( 'widgets' );
+	}
+
+	/**
+	 * @see Tests_WP_Customize_Manager::test_customize_loaded_components_filter()
+	 *
+	 * @param array                $components         Components.
+	 * @param WP_Customize_Manager $customize_manager  Manager.
+	 *
+	 * @return array Components.
+	 */
+	function return_array_containing_nav_menus( $components, $customize_manager ) {
+		$this->assertInternalType( 'array', $components );
+		$this->assertContains( 'widgets', $components );
+		$this->assertContains( 'nav_menus', $components );
+		return array( 'nav_menus' );
+	}
 }
