Index: components/core/src/main/java/org/hippoecm/hst/configuration/model/HstSiteConfigurationRootNodeImpl.java
===================================================================
--- components/core/src/main/java/org/hippoecm/hst/configuration/model/HstSiteConfigurationRootNodeImpl.java	(revision 28590)
+++ components/core/src/main/java/org/hippoecm/hst/configuration/model/HstSiteConfigurationRootNodeImpl.java	(working copy)
@@ -15,6 +15,9 @@
  */
 package org.hippoecm.hst.configuration.model;
 
+import java.util.Set;
+import java.util.TreeSet;
+
 import javax.jcr.Node;
 import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
@@ -25,6 +28,8 @@
 public class HstSiteConfigurationRootNodeImpl extends HstNodeImpl implements HstNode {
 
     private static final org.slf4j.Logger log = LoggerFactory.getLogger(HstNodeImpl.class);
+
+    private Set<String> inherited = new TreeSet<String>();
   
     public HstSiteConfigurationRootNodeImpl(Node jcrNode, HstNode parent, HstManagerImpl hstManagerImpl) throws HstNodeException {
         super(jcrNode, parent, true);
@@ -102,6 +107,10 @@
         
     }
 
+    public boolean isInherited(String name) {
+        return inherited.contains(name);
+    }
+
     private void merge(HstSiteConfigurationRootNodeImpl inheritedConfig) {
         merge(inheritedConfig, HstNodeTypes.NODENAME_HST_CATALOG);
         merge(inheritedConfig, HstNodeTypes.NODENAME_HST_SITEMAP);
@@ -126,6 +135,7 @@
         if(hstNode == null) {
             // inherit the node from inheritedConfig
             this.addNode(nodeName, inheritedNode);
+            inherited.add(nodeName);
         } else {
             // add the direct children that are in the inheritedConfig but not in the current.
             for(HstNode inheritedChild : inheritedNode.getNodes()) {
@@ -134,6 +144,7 @@
                     ((HstNodeImpl)hstNode).addNode(inheritedChild.getValueProvider().getName(), inheritedChild);
                 }
             }
+            inherited.remove(nodeName);
         }
         
     }
Index: components/core/src/main/java/org/hippoecm/hst/configuration/model/HstManagerImpl.java
===================================================================
--- components/core/src/main/java/org/hippoecm/hst/configuration/model/HstManagerImpl.java	(revision 28590)
+++ components/core/src/main/java/org/hippoecm/hst/configuration/model/HstManagerImpl.java	(working copy)
@@ -17,6 +17,8 @@
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
 
 import javax.jcr.Credentials;
 import javax.jcr.Node;
@@ -26,7 +28,10 @@
 import javax.jcr.Session;
 import javax.jcr.query.QueryResult;
 
+
+import org.apache.commons.lang.StringUtils;
 import org.hippoecm.hst.configuration.HstNodeTypes;
+import org.hippoecm.hst.configuration.components.HstComponentsConfigurationService;
 import org.hippoecm.hst.configuration.channel.ChannelManager;
 import org.hippoecm.hst.configuration.channel.ChannelManagerImpl;
 import org.hippoecm.hst.configuration.hosting.VirtualHosts;
@@ -37,6 +42,7 @@
 import org.hippoecm.hst.core.request.HstSiteMapMatcher;
 import org.hippoecm.hst.core.sitemapitemhandler.HstSiteMapItemHandlerFactory;
 import org.hippoecm.hst.core.sitemapitemhandler.HstSiteMapItemHandlerRegistry;
+import org.hippoecm.hst.provider.ValueProvider;
 import org.hippoecm.hst.service.ServiceException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -79,6 +85,11 @@
      * The map of all configurationRootNodes where the key is the path to the configuration
      */
     private Map<String, HstNode> configurationRootNodes = new HashMap<String, HstNode>();
+    
+    /**
+      * Cached hst components configuration services, only valid during construction of the sites
+      */
+    private transient Map<Set<String>, HstComponentsConfigurationService> configurationCache = null;
 
     /**
      * The map of all site nodes where the key is the path
@@ -251,11 +262,15 @@
                 }
             }
         }
-         
-        try {
+        
+        configurationCache = new HashMap<Set<String>, HstComponentsConfigurationService>(); 
+        
+        try {            
             this.virtualHosts = new VirtualHostsService(virtualHostsNode, this);
         } catch (ServiceException e) {
             throw new RepositoryNotAvailableException(e);
+        }finally {
+           configurationCache = null;
         }
     }
     
@@ -275,6 +290,94 @@
         return configurationRootNodes;
     }
     
+    
+    
+    /**
+     * build the components configuration, or retrieve it from cache.
+     * This method can only be invoked during the construction of the model ({@link #buildSites})
+     */
+    public HstComponentsConfigurationService getComponentsConfiguration(final String configurationPath)
+            throws ServiceException {
+        if (configurationCache == null) {
+            throw new IllegalStateException(
+                    "Components Configuration can only be retrieved during construction of sites");
+        }
+
+        Set<String> paths = new TreeSet<String>();
+        paths.add(configurationPath);
+
+        // if components configuration can be reused, do so
+        HstSiteConfigurationRootNodeImpl configurationNode = (HstSiteConfigurationRootNodeImpl) getConfigurationRootNodes()
+                .get(configurationPath);
+        String[] inheritsFrom = configurationNode.getValueProvider().getStrings(
+                HstNodeTypes.GENERAL_PROPERTY_INHERITS_FROM);
+        if (inheritsFrom.length > 0) {
+            boolean inherited = configurationNode.isInherited(HstNodeTypes.NODENAME_HST_CATALOG)
+                    && configurationNode.isInherited(HstNodeTypes.NODENAME_HST_PAGES)
+                    && configurationNode.isInherited(HstNodeTypes.NODENAME_HST_COMPONENTS)
+                    && configurationNode.isInherited(HstNodeTypes.NODENAME_HST_TEMPLATES);
+            if (inherited) {
+                paths.clear();
+                for (int i = 0; i < inheritsFrom.length; i++) {
+                    String configPath = configurationPath;
+                    String relPath = inheritsFrom[i];
+                    while (relPath.startsWith("../")) {
+                        relPath = relPath.substring(3);
+                        configPath = configPath.substring(0, configPath.lastIndexOf('/'));
+                    }
+                    configPath = configPath + "/" + relPath;
+                    paths.add(configPath);
+                }
+            }
+        }
+
+        if (!configurationCache.containsKey(paths)) {
+
+            if (configurationNode == null) {
+                throw new ServiceException("Cannot find configuration at '" + configurationPath + "'");
+            }
+
+            Map<String, HstNode> templateResourceMap = new HashMap<String, HstNode>();
+
+            // templates
+            HstNode hstTemplates = configurationNode.getNode(HstNodeTypes.NODENAME_HST_TEMPLATES);
+
+            if (hstTemplates == null) {
+                throw new ServiceException("There are no '" + HstNodeTypes.NODENAME_HST_TEMPLATES
+                        + "' present for the configuration at '" + configurationNode.getValueProvider().getPath() + "'");
+            }
+
+            for (HstNode template : hstTemplates.getNodes()) {
+                ValueProvider valueProvider = template.getValueProvider();
+                boolean renderPathExisting = valueProvider.hasProperty(HstNodeTypes.TEMPLATE_PROPERTY_RENDERPATH);
+                boolean scriptExisting = valueProvider.hasProperty(HstNodeTypes.TEMPLATE_PROPERTY_SCRIPT);
+
+                if (!renderPathExisting && !scriptExisting) {
+                    log.warn("Skipping template '{}' because missing property, either hst:renderpath or hst:script.",
+                            valueProvider.getPath());
+                    continue;
+                }
+
+                if (renderPathExisting && !scriptExisting) {
+                    String resourcePath = valueProvider.getString(HstNodeTypes.TEMPLATE_PROPERTY_RENDERPATH);
+
+                    if (StringUtils.isBlank(resourcePath)) {
+                        log.warn("Skipping template '{}' because of invalid hst:renderpath value.", valueProvider
+                                .getPath());
+                        continue;
+                    }
+                }
+
+                templateResourceMap.put(valueProvider.getName(), template);
+            }
+
+            // component configuration
+            configurationCache.put(paths, new HstComponentsConfigurationService(configurationNode, templateResourceMap,
+                    this));
+        }
+        return configurationCache.get(paths);
+    }
+    
     public HstNode getCommonCatalog(){
         return commonCatalog;
     }
Index: components/core/src/main/java/org/hippoecm/hst/configuration/site/HstSiteService.java
===================================================================
--- components/core/src/main/java/org/hippoecm/hst/configuration/site/HstSiteService.java	(revision 28590)
+++ components/core/src/main/java/org/hippoecm/hst/configuration/site/HstSiteService.java	(working copy)
@@ -15,10 +15,6 @@
  */
 package org.hippoecm.hst.configuration.site;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.lang.StringUtils;
 import org.hippoecm.hst.configuration.HstNodeTypes;
 import org.hippoecm.hst.configuration.components.HstComponentConfiguration;
 import org.hippoecm.hst.configuration.components.HstComponentsConfiguration;
@@ -36,7 +32,6 @@
 import org.hippoecm.hst.configuration.sitemenu.HstSiteMenusConfigurationService;
 import org.hippoecm.hst.core.linking.LocationMapTree;
 import org.hippoecm.hst.core.linking.LocationMapTreeImpl;
-import org.hippoecm.hst.provider.ValueProvider;
 import org.hippoecm.hst.service.ServiceException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -68,52 +63,18 @@
         canonicalContentPath = site.getCanonicalContentPath();
         canonicalIdentifier = site.getValueProvider().getIdentifier();
         configurationPath = site.getConfigurationPath();
-        
+
         HstNode configurationNode = hstManager.getConfigurationRootNodes().get(configurationPath);
-        
         if(configurationNode == null) {
             throw new ServiceException("Cannot find configuration at '"+configurationPath+"' for site '"+getName()+"'" );
         }
-        
-        init(configurationNode, hstManager);
+        componentsConfigurationService = hstManager.getComponentsConfiguration(configurationPath);
+
+        init(configurationNode);
     }
 
     
-    private void init(HstNode configurationNode, HstManagerImpl hstManager) throws ServiceException {
-       Map<String, HstNode> templateResourceMap = new HashMap<String, HstNode>();
-       
-       // templates
-       HstNode hstTemplates = configurationNode.getNode(HstNodeTypes.NODENAME_HST_TEMPLATES);
-       
-       if(hstTemplates == null) {
-           throw new ServiceException("There are no '"+HstNodeTypes.NODENAME_HST_TEMPLATES+"' present for the configuration at '"+configurationNode.getValueProvider().getPath()+"'");
-       }
-       
-       for(HstNode template : hstTemplates.getNodes()) {
-           ValueProvider valueProvider = template.getValueProvider();
-           boolean renderPathExisting = valueProvider.hasProperty(HstNodeTypes.TEMPLATE_PROPERTY_RENDERPATH);
-           boolean scriptExisting = valueProvider.hasProperty(HstNodeTypes.TEMPLATE_PROPERTY_SCRIPT);
-           
-           if (!renderPathExisting && !scriptExisting) {
-               log.warn("Skipping template '{}' because missing property, either hst:renderpath or hst:script.", valueProvider.getPath());
-               continue;
-           }
-           
-           if (renderPathExisting && !scriptExisting) {
-               String resourcePath = valueProvider.getString(HstNodeTypes.TEMPLATE_PROPERTY_RENDERPATH);
-               
-               if (StringUtils.isBlank(resourcePath)) {
-                   log.warn("Skipping template '{}' because of invalid hst:renderpath value.", valueProvider.getPath());
-                   continue;
-               }
-           }
-           
-           templateResourceMap.put(valueProvider.getName(), template);
-       }
-       
-       // component configuration
-       this.componentsConfigurationService = new HstComponentsConfigurationService(configurationNode, templateResourceMap, hstManager); 
-       
+    private void init(HstNode configurationNode) throws ServiceException {
        // sitemapitem handlers
        
        HstNode sitemapItemHandlersNode = configurationNode.getNode(HstNodeTypes.NODENAME_HST_SITEMAPITEMHANDLERS);
Index: demosuite/site/src/main/webapp/WEB-INF/jsp/components/main/sitesoverview.jsp
===================================================================
--- demosuite/site/src/main/webapp/WEB-INF/jsp/components/main/sitesoverview.jsp	(revision 28590)
+++ demosuite/site/src/main/webapp/WEB-INF/jsp/components/main/sitesoverview.jsp	(working copy)
@@ -27,35 +27,44 @@
      <input type="hidden" name="type" value="addnewsites"/>
      <input type="submit" value="add 1 New Site" /> 
   </form>
-  
   <form method="post" action="<hst:actionURL/>">
      <input type="hidden" name="number" value="5"/>
      <input type="hidden" name="type" value="addnewsites"/>
      <input type="submit" value="add 5 New Sites" /> 
   </form>
-  
-   <form method="post" action="<hst:actionURL/>">
+  <form method="post" action="<hst:actionURL/>">
      <input type="hidden" name="number" value="10"/>
      <input type="hidden" name="type" value="addnewsites"/>
      <input type="submit" value="add 10 New Sites" /> 
   </form>
-   <form method="post" action="<hst:actionURL/>">
+  <form method="post" action="<hst:actionURL/>">
      <input type="hidden" name="number" value="25"/>
      <input type="hidden" name="type" value="addnewsites"/>
      <input type="submit" value="add 25 New Sites" /> 
   </form>
-   <form method="post" action="<hst:actionURL/>">
+  <form method="post" action="<hst:actionURL/>">
      <input type="hidden" name="number" value="100"/>
      <input type="hidden" name="type" value="addnewsites"/>
      <input type="submit" value="add 100 New Sites" /> 
   </form>
-  
-  
-   <form method="post" action="<hst:actionURL/>">
+  <form method="post" action="<hst:actionURL/>">
      <input type="hidden" name="number" value="1000"/>
      <input type="hidden" name="type" value="addnewsites"/>
      <input type="submit" value="add 1000 New Sites" /> 
   </form>
+
+  <form method="post" action="<hst:actionURL/>">
+     <input type="hidden" name="number" value="100"/>
+     <input type="hidden" name="copycomponents" value="false"/>
+     <input type="hidden" name="type" value="addnewsites"/>
+     <input type="submit" value="add 100 New Sites - Sitemap, Sitemenu only" /> 
+  </form>
+  <form method="post" action="<hst:actionURL/>">
+     <input type="hidden" name="number" value="1000"/>
+     <input type="hidden" name="copycomponents" value="false"/>
+     <input type="hidden" name="type" value="addnewsites"/>
+     <input type="submit" value="add 1000 New Sites - Sitemap, Sitemenu only" /> 
+  </form>
    
   <br/>
   <br/>
Index: demosuite/site/src/main/java/org/hippoecm/hst/demo/components/SitesOverview.java
===================================================================
--- demosuite/site/src/main/java/org/hippoecm/hst/demo/components/SitesOverview.java	(revision 28590)
+++ demosuite/site/src/main/java/org/hippoecm/hst/demo/components/SitesOverview.java	(working copy)
@@ -59,7 +59,10 @@
             String numberStr = request.getParameter("number");
             int numberToAdd = Integer.parseInt(numberStr);
             int tryToAdd = 1;
-            
+
+            String copyComponentsStr = request.getParameter("copycomponents");
+            boolean copyComponents = copyComponentsStr != null ? Boolean.parseBoolean(copyComponentsStr) : true;
+
             while(numberToAdd > 0) {
                 System.out.println("numberToAdd " + numberToAdd);
                 numberToAdd--;
@@ -87,20 +90,25 @@
                 String[] modes = {"single"};
                 content.setProperty("hippo:modes", modes);
                 content.setProperty("hippo:docbase", writableSession.getNode("/hst:hst/hst:sites/demosite-test-many-live/hst:content").getProperty("hippo:docbase").getString());
-                
-                // now copy the hst:configurations 
-                
+
+                writableSession.save();
+
+                // now copy the hst:configurations
+
                 Node config = writableSession.getNode("/hst:hst/hst:configurations").addNode("demosite-test-many" + tryToAdd, "hst:configuration");
                 String[] inherits = {"../democommon"};
                 config.setProperty("hst:inheritsfrom", inherits);
-                
+
                 writableSession.save();
-                
-                
+
+
                 writableSession.getWorkspace().copy("/hst:hst/hst:configurations/demosite-test-many/hst:sitemap", config.getPath() + "/hst:sitemap");
                 writableSession.getWorkspace().copy("/hst:hst/hst:configurations/demosite-test-many/hst:sitemenus", config.getPath() + "/hst:sitemenus");
-                writableSession.getWorkspace().copy("/hst:hst/hst:configurations/demosite-test-many/hst:pages", config.getPath() + "/hst:pages");
-                writableSession.getWorkspace().copy("/hst:hst/hst:configurations/demosite-test-many/hst:templates", config.getPath()  + "/hst:templates");
+
+                if (copyComponents) {
+                    writableSession.getWorkspace().copy("/hst:hst/hst:configurations/demosite-test-many/hst:pages", config.getPath() + "/hst:pages");
+                    writableSession.getWorkspace().copy("/hst:hst/hst:configurations/demosite-test-many/hst:templates", config.getPath()  + "/hst:templates");
+                }
             }
             
         } catch (RepositoryException e) {
@@ -115,4 +123,4 @@
         
     }
 
-}
\ No newline at end of file
+}

