diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/BaseEntityModel.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/BaseEntityModel.java
index 2305cf9c5379e2a3115c2022ca5761f67a725a69..945fe76f9d7192b4ea554902e1598790f07f0ca6 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/BaseEntityModel.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/model/BaseEntityModel.java
@@ -49,6 +49,11 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 public class BaseEntityModel<T> extends SimplifiedBaseModelData
 {
     private static final long serialVersionUID = 1L;
+    
+    public static <T> BaseEntityModel<T> create(GridRowModel<T> entity, List<IColumnDefinitionUI<T>> columnDefinitions)
+    {
+        return null;
+    }
 
     public BaseEntityModel(final GridRowModel<T> entity,
             IColumnDefinitionKind<T>[] staticColumnDefinitions)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
index 1a335ca75b92a2b4d41588ad4295abafbc13a6e5..b6ebcb2e1f0edee95862b683a1d50e5c4ebbe1f0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/TypedTableGrid.java
@@ -165,6 +165,8 @@ public abstract class TypedTableGrid<T extends ISerializable>
 
     private String currentGridDisplayTypeID;
 
+    private List<IColumnDefinitionUI<TableModelRowWithObject<T>>> visibleColDefinitions;
+
     protected TypedTableGrid(IViewContext<ICommonClientServiceAsync> viewContext, String browserId,
             boolean refreshAutomatically, IDisplayTypeIDGenerator displayTypeIDGenerator)
     {
@@ -253,11 +255,26 @@ public abstract class TypedTableGrid<T extends ISerializable>
         }
     }
 
+    @Override
+    protected void initializeModelCreation()
+    {
+        Set<String> visibleColumnIds = getIDsOfVisibleColumns();
+        List<IColumnDefinitionUI<TableModelRowWithObject<T>>> colDefinitions = createColDefinitions();
+        visibleColDefinitions = new ArrayList<IColumnDefinitionUI<TableModelRowWithObject<T>>>();
+        for (IColumnDefinitionUI<TableModelRowWithObject<T>> definition : colDefinitions)
+        {
+            if (visibleColumnIds.contains(definition.getIdentifier()))
+            {
+                visibleColDefinitions.add(definition);
+            }
+        }
+    }
+
     @Override
     protected BaseEntityModel<TableModelRowWithObject<T>> createModel(
             GridRowModel<TableModelRowWithObject<T>> entity)
     {
-        return new BaseEntityModel<TableModelRowWithObject<T>>(entity, createColDefinitions());
+        return new BaseEntityModel<TableModelRowWithObject<T>>(entity, visibleColDefinitions);
     }
 
     /**
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
index 66528d25c603fa4bd134f9bb70ec342c98883c42..b41124bd5dd4412583fa0a94c78ed022d0bccbae 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java
@@ -774,6 +774,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
         private List<M> createModels(final GridRowModels<T> gridRowModels)
         {
             final List<M> result = new ArrayList<M>();
+            initializeModelCreation();
             for (final GridRowModel<T> entity : gridRowModels)
             {
                 M model = createModel(entity);
@@ -790,6 +791,31 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
         }
     }
 
+    /**
+     * Initializes creation of model from received data. This is a hook method called before {
+     * {@link AbstractBrowserGrid#createModel(GridRowModel)} is invoked for all rows. This
+     * implementation does nothing. Subclasses usually override this method by creating an instance
+     * attribute which holds a list of visible column definitions. This speeds up invocation of
+     * {@link AbstractBrowserGrid#createModel(GridRowModel)}.
+     */
+    protected void initializeModelCreation()
+    {
+    }
+
+    protected Set<String> getIDsOfVisibleColumns()
+    {
+        Set<String> visibleColumnIds = new HashSet<String>();
+        for (int i = 0, n = fullColumnModel.getColumnCount(); i < n; i++)
+        {
+            ColumnConfig column = fullColumnModel.getColumn(i);
+            if (column.isHidden() == false)
+            {
+                visibleColumnIds.add(column.getId());
+            }
+        }
+        return visibleColumnIds;
+    }
+
     // wraps this browser into the interface appropriate for the toolbar. If this class would just
     // implement the interface it could be very confusing for the code reader.
     protected final IBrowserGridActionInvoker asActionInvoker()
@@ -1532,8 +1558,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod
         return new ColumnModel(columConfigs);
     }
 
-    // Default visibility so that friend classes can use -- should otherwise be considered private
-    ColumnModel getFullColumnModel()
+    protected ColumnModel getFullColumnModel()
     {
         return fullColumnModel;
     }
diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java
index c03f9389143718ff190c66ff3a965e049154528b..5308ec352c33a8d434d8ff921ea59085a6eb1a25 100644
--- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java
+++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/phosphonetx/client/web/client/application/ProteinByExperimentBrowserGrid.java
@@ -98,6 +98,8 @@ class ProteinByExperimentBrowserGrid extends AbstractSimpleBrowserGrid<ProteinIn
             }
         };
 
+    private List<IColumnDefinition<ProteinInfo>> visibleColumnDefinitions;
+
     static IDisposableComponent create(
             final IViewContext<IPhosphoNetXClientServiceAsync> viewContext,
             BasicEntityType experimentType, Experiment experiment)
@@ -250,11 +252,25 @@ class ProteinByExperimentBrowserGrid extends AbstractSimpleBrowserGrid<ProteinIn
     }
 
     @Override
-    protected BaseEntityModel<ProteinInfo> createModel(GridRowModel<ProteinInfo> entity)
+    protected void initializeModelCreation()
     {
+        Set<String> visibleColumnIds = getIDsOfVisibleColumns();
+        visibleColumnDefinitions = new ArrayList<IColumnDefinition<ProteinInfo>>();
         Set<IColumnDefinition<ProteinInfo>> columnDefs = createColumnsDefinition().getColumnDefs();
-        return new BaseEntityModel<ProteinInfo>(entity,
-                new ArrayList<IColumnDefinition<ProteinInfo>>(columnDefs), true);
+        for (IColumnDefinition<ProteinInfo> columnDefinition : columnDefs)
+        {
+            if (columnDefinition instanceof IColumnDefinitionUI == false
+                    || visibleColumnIds.contains(columnDefinition.getIdentifier()))
+            {
+                visibleColumnDefinitions.add(columnDefinition);
+            }
+        }
+    }
+
+    @Override
+    protected BaseEntityModel<ProteinInfo> createModel(GridRowModel<ProteinInfo> entity)
+    {
+        return new BaseEntityModel<ProteinInfo>(entity, visibleColumnDefinitions, true);
     }
 
     @Override