diff --git a/core/includes/entity.api.php b/core/includes/entity.api.php
index cee3a43..7b42253 100644
--- a/core/includes/entity.api.php
+++ b/core/includes/entity.api.php
@@ -180,8 +180,11 @@ function hook_entity_query_alter(\Drupal\Core\Entity\Query\QueryInterface $query
 /**
  * Act on entities being assembled before rendering.
  *
- * @param Drupal\Core\Entity\EntityInterface $entity
+ * @param \Drupal\Core\Entity\EntityInterface $entity
  *   The entity object.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   entity components.
  * @param $view_mode
  *   The view mode the entity is rendered in.
  * @param $langcode
@@ -196,12 +199,16 @@ function hook_entity_query_alter(\Drupal\Core\Entity\Query\QueryInterface $query
  * @see hook_node_view()
  * @see hook_user_view()
  */
-function hook_entity_view(Drupal\Core\Entity\EntityInterface $entity, $view_mode, $langcode) {
-  $entity->content['my_additional_field'] = array(
-    '#markup' => $additional_field,
-    '#weight' => 10,
-    '#theme' => 'mymodule_my_additional_field',
-  );
+function hook_entity_view(\Drupal\Core\Entity\EntityInterface $entity, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display, $view_mode, $langcode) {
+  // Only do the extra work if the component is configured to be displayed.
+  // This assumes a 'mymodule_addition' extra field has been defined for the
+  // entity bundle in hook_field_extra_fields().
+  if ($display->getComponent('mymodule_addition')) {
+    $entity->content['mymodule_addition'] = array(
+      '#markup' => mymodule_addition($entity),
+      '#theme' => 'mymodule_my_additional_field',
+    );
+  }
 }
 
 /**
@@ -221,6 +228,9 @@ function hook_entity_view(Drupal\Core\Entity\EntityInterface $entity, $view_mode
  *   A renderable array representing the entity content.
  * @param Drupal\Core\Entity\EntityInterface $entity
  *   The entity object being rendered.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   entity components.
  *
  * @see hook_entity_view()
  * @see hook_comment_view_alter()
@@ -228,7 +238,7 @@ function hook_entity_view(Drupal\Core\Entity\EntityInterface $entity, $view_mode
  * @see hook_taxonomy_term_view_alter()
  * @see hook_user_view_alter()
  */
-function hook_entity_view_alter(&$build, Drupal\Core\Entity\EntityInterface $entity) {
+function hook_entity_view_alter(&$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display) {
   if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
     // Change its weight.
     $build['an_additional_field']['#weight'] = -10;
@@ -245,17 +255,33 @@ function hook_entity_view_alter(&$build, Drupal\Core\Entity\EntityInterface $ent
  * view. Only use this if attaching the data during the entity loading phase
  * is not appropriate, for example when attaching other 'entity' style objects.
  *
- * @param array $entities
- *   The entities keyed by entity ID.
  * @param string $entity_type
  *   The type of entities being viewed (i.e. node, user, comment).
+ * @param array $entities
+ *   The entities keyed by entity ID.
+ * @param array $display
+ *   The array of entity_display objects holding the display options configured
+ *   for the entity components, keyed by bundle name.
+ * @param string $view_mode
+ *   The view mode.
  */
-function hook_entity_prepare_view($entities, $entity_type) {
+function hook_entity_prepare_view($entity_type, array $entities, array $displays, $view_mode) {
   // Load a specific node into the user object for later theming.
   if (!empty($entities) && $entity_type == 'user') {
-    $nodes = mymodule_get_user_nodes(array_keys($entities));
-    foreach ($entities as $uid => $entity) {
-      $entity->user_node = $nodes[$uid];
+    // Only do the extra work if the component is configured to be
+    // displayed. This assumes a 'mymodule_addition' extra field has been
+    // defined for the entity bundle in hook_field_extra_fields().
+    $ids = array();
+    foreach ($entities as $id => $entity) {
+      if ($displays[$entity->bundle()]->getComponent('mymodule_addition')) {
+        $ids[] = $id;
+      }
+    }
+    if ($ids) {
+      $nodes = mymodule_get_user_nodes($ids);
+      foreach ($ids as $id) {
+        $entities[$id]->user_node = $nodes[$id];
+      }
     }
   }
 }
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index ea17846..4e43540 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -663,29 +663,6 @@ function entity_get_render_display(EntityInterface $entity, $view_mode) {
 }
 
 /**
- * Adjusts weights and visibility of components in displayed entities.
- *
- * This is used as a #pre_render callback.
- */
-function _entity_view_pre_render($elements) {
-  $display = $elements['#entity_display'];
-
-  $extra_fields = field_info_extra_fields($display->targetEntityType, $display->bundle, 'display');
-  foreach (array_keys($extra_fields) as $name) {
-    if (isset($elements[$name]) && (!isset($elements[$name]['#access']) || $elements[$name]['#access'])) {
-      if ($options = $display->getComponent($name)) {
-        $elements[$name]['#weight'] = $options['weight'];
-      }
-      else {
-        $elements[$name]['#access'] = FALSE;
-      }
-    }
-  }
-
-  return $elements;
-}
-
-/**
  * Returns the entity query object for this entity type.
  *
  * @param $entity_type
diff --git a/core/lib/Drupal/Core/Entity/EntityRenderController.php b/core/lib/Drupal/Core/Entity/EntityRenderController.php
index f942ae0..2253c92 100644
--- a/core/lib/Drupal/Core/Entity/EntityRenderController.php
+++ b/core/lib/Drupal/Core/Entity/EntityRenderController.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\Core\Entity;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Base class for entity view controllers.
@@ -26,54 +27,16 @@ public function __construct($entity_type) {
   /**
    * Implements Drupal\Core\Entity\EntityRenderControllerInterface::buildContent().
    */
-  public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
-    // Allow modules to change the view mode.
-    $context = array('langcode' => $langcode);
-
-    $view_modes = array();
-    $displays = array();
+  public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
+    field_attach_prepare_view($this->entityType, $entities, $displays, $langcode);
+    module_invoke_all('entity_prepare_view', $this->entityType, $entities, $displays, $view_mode);
 
     foreach ($entities as $entity) {
       // Remove previously built content, if exists.
-      $entity->content = array();
-
-      drupal_alter('entity_view_mode', $view_mode, $entity, $context);
-      $entity->content['#view_mode'] = $view_mode;
-      $view_modes[$view_mode][$entity->id()] = $entity;
-
-      $bundle = $entity->bundle();
-
-      // Load the corresponding display settings if not stored yet.
-      if (!isset($displays[$view_mode][$bundle])) {
-        // Get the display object to use for rendering the entity..
-        $display = entity_get_render_display($entity, $view_mode);
-
-        // Let modules alter the display.
-        // Note: if config entities get a static cache at some point, the
-        // objects should be cloned before running drupal_alter().
-        $display_context = array(
-          'entity_type' => $this->entityType,
-          'bundle' => $bundle,
-          'view_mode' => $view_mode,
-        );
-        drupal_alter('entity_display', $display, $display_context);
-
-        $displays[$view_mode][$bundle] = $display;
-      }
-
-      // Assigning weights to 'extra fields' is done in a pre_render callback.
-      $entity->content['#pre_render'] = array('_entity_view_pre_render');
-      $entity->content['#entity_display'] = $displays[$view_mode][$bundle];
-    }
-
-    // Prepare and build field content, grouped by view mode.
-    foreach ($view_modes as $view_mode => $view_mode_entities) {
-      field_attach_prepare_view($this->entityType, $view_mode_entities, $displays[$view_mode], $langcode);
-      module_invoke_all('entity_prepare_view', $view_mode_entities, $this->entityType);
-
-      foreach ($view_mode_entities as $entity) {
-        $entity->content += field_attach_view($this->entityType, $entity, $displays[$view_mode][$entity->bundle()], $langcode);
-      }
+      $entity->content = array(
+        '#view_mode' => $view_mode,
+      );
+      $entity->content += field_attach_view($this->entityType, $entity, $displays[$entity->bundle()], $langcode);
     }
   }
 
@@ -105,15 +68,18 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco
    *
    * @param array $build
    *   The render array that is being created.
-   * @param Drupal\Core\Entity\EntityInterface $entity
+   * @param \Drupal\Core\Entity\EntityInterface $entity
    *   The entity to be prepared.
+   * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+   *   The entity_display object holding the display options configured for
+   *   the entity components.
    * @param string $view_mode
    *   The view mode that should be used to prepare the entity.
    * @param string $langcode
    *   (optional) For which language the entity should be prepared, defaults to
    *   the current content language.
    */
-  protected function alterBuild(array &$build, EntityInterface $entity, $view_mode, $langcode = NULL) { }
+  protected function alterBuild(array &$build, EntityInterface $entity, EntityDisplay $display, $view_mode, $langcode = NULL) { }
 
   /**
    * Implements Drupal\Core\Entity\EntityRenderControllerInterface::view().
@@ -130,26 +96,68 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
     if (!isset($langcode)) {
       $langcode = language(LANGUAGE_TYPE_CONTENT)->langcode;
     }
-    $this->buildContent($entities, $view_mode, $langcode);
+
+    // Build the view modes and display objects.
+    $view_modes = array();
+    $displays = array();
+    $context = array('langcode' => $langcode);
+    foreach ($entities as $entity) {
+      $bundle = $entity->bundle();
+
+      // Allow modules to change the view mode.
+      $entity_view_mode = $view_mode;
+      drupal_alter('entity_view_mode', $entity_view_mode, $entity, $context);
+      // Store entities for rendering by view_mode.
+      $view_modes[$entity_view_mode][$entity->id()] = $entity;
+
+      // Load the corresponding display settings if not stored yet.
+      if (!isset($displays[$entity_view_mode][$bundle])) {
+        // Get the display object for this bundle and view mode.
+        $display = entity_get_render_display($entity, $entity_view_mode);
+
+        // Let modules alter the display.
+        $display_context = array(
+          'entity_type' => $this->entityType,
+          'bundle' => $bundle,
+          'view_mode' => $entity_view_mode,
+        );
+        drupal_alter('entity_display', $display, $display_context);
+
+        $displays[$entity_view_mode][$bundle] = $display;
+      }
+    }
+
+    foreach ($view_modes as $mode => $view_mode_entities) {
+      $this->buildContent($view_mode_entities, $displays[$mode], $mode, $langcode);
+    }
 
     $view_hook = "{$this->entityType}_view";
     $build = array('#sorted' => TRUE);
     $weight = 0;
     foreach ($entities as $key => $entity) {
       $entity_view_mode = isset($entity->content['#view_mode']) ? $entity->content['#view_mode'] : $view_mode;
-      module_invoke_all($view_hook, $entity, $entity_view_mode, $langcode);
-      module_invoke_all('entity_view', $entity, $entity_view_mode, $langcode);
+      $display = $displays[$entity_view_mode][$entity->bundle()];
+      module_invoke_all($view_hook, $entity, $display, $entity_view_mode, $langcode);
+      module_invoke_all('entity_view', $entity, $display, $entity_view_mode, $langcode);
 
       $build[$key] = $entity->content;
       // We don't need duplicate rendering info in $entity->content.
       unset($entity->content);
 
       $build[$key] += $this->getBuildDefaults($entity, $entity_view_mode, $langcode);
-      $this->alterBuild($build[$key], $entity, $entity_view_mode, $langcode);
+      $this->alterBuild($build[$key], $entity, $display, $entity_view_mode, $langcode);
+
+      // Assign the weights configured in the display.
+      foreach ($display->getComponents() as $name => $options) {
+        if (isset($build[$key][$name])) {
+          $build[$key][$name]['#weight'] = $options['weight'];
+        }
+      }
+
       $build[$key]['#weight'] = $weight++;
 
-      // Allow modules to modify the structured entity.
-      drupal_alter(array($view_hook, 'entity_view'), $build[$key], $entity);
+      // Allow modules to modify the render array.
+      drupal_alter(array($view_hook, 'entity_view'), $build[$key], $entity, $display);
     }
 
     return $build;
diff --git a/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php b/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
index c24ffaa..8ab236d 100644
--- a/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityRenderControllerInterface.php
@@ -11,13 +11,17 @@
  * Defines a common interface for entity view controller classes.
  */
 interface EntityRenderControllerInterface {
+
   /**
    * Build the structured $content property on the entity.
    *
    * @param array $entities
    *   The entities, implementing EntityInterface, whose content is being built.
+   * @param array $displays
+   *   The array of entity_display objects holding the display options
+   *   configured for the entity components, keyed by bundle name.
    * @param string $view_mode
-   *   (optional) The view mode that should be used to build the entity.
+   *   The view mode in which the entity is being viewed.
    * @param string $langcode
    *   (optional) For which language the entity should be build, defaults to
    *   the current content language.
@@ -25,7 +29,7 @@
    * @return array
    *   The content array.
    */
-  public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL);
+  public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL);
 
   /**
    * Returns the render array for the provided entity.
diff --git a/core/modules/book/book.module b/core/modules/book/book.module
index e5e49b3..321fd96 100644
--- a/core/modules/book/book.module
+++ b/core/modules/book/book.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 use Drupal\Core\Template\Attribute;
 
 /**
@@ -870,7 +871,7 @@ function book_node_load($nodes, $types) {
 /**
  * Implements hook_node_view().
  */
-function book_node_view(Node $node, $view_mode) {
+function book_node_view(Node $node, EntityDisplay $display, $view_mode) {
   if ($view_mode == 'full') {
     if (!empty($node->book['bid']) && empty($node->in_preview)) {
       $node->content['book_navigation'] = array(
diff --git a/core/modules/comment/comment.api.php b/core/modules/comment/comment.api.php
index 95c3e1d..0a67837 100644
--- a/core/modules/comment/comment.api.php
+++ b/core/modules/comment/comment.api.php
@@ -64,8 +64,11 @@ function hook_comment_load(Drupal\comment\Comment $comments) {
 /**
  * Act on a comment that is being assembled before rendering.
  *
- * @param Drupal\comment\Comment $comment
+ * @param \Drupal\comment\Plugin\Core\Entity\Comment $comment $comment
  *   Passes in the comment the action is being performed on.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   comment components.
  * @param $view_mode
  *   View mode, e.g. 'full', 'teaser'...
  * @param $langcode
@@ -73,9 +76,16 @@ function hook_comment_load(Drupal\comment\Comment $comments) {
  *
  * @see hook_entity_view()
  */
-function hook_comment_view(Drupal\comment\Comment $comment, $view_mode, $langcode) {
-  // how old is the comment
-  $comment->time_ago = time() - $comment->changed;
+function hook_comment_view(\Drupal\comment\Plugin\Core\Entity\Comment $comment, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display, $view_mode, $langcode) {
+  // Only do the extra work if the component is configured to be displayed.
+  // This assumes a 'mymodule_addition' extra field has been defined for the
+  // node type in hook_field_extra_fields().
+  if ($display->getComponent('mymodule_addition')) {
+    $comment->content['mymodule_addition'] = array(
+      '#markup' => mymodule_addition($comment),
+      '#theme' => 'mymodule_my_additional_field',
+    );
+  }
 }
 
 /**
@@ -93,13 +103,16 @@ function hook_comment_view(Drupal\comment\Comment $comment, $view_mode, $langcod
  *
  * @param $build
  *   A renderable array representing the comment.
- * @param Drupal\comment\Comment $comment
+ * @param \Drupal\comment\Plugin\Core\Entity\Comment $comment
  *   The comment being rendered.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   comment components.
  *
  * @see comment_view()
  * @see hook_entity_view_alter()
  */
-function hook_comment_view_alter(&$build, Drupal\comment\Comment $comment) {
+function hook_comment_view_alter(&$build, \Drupal\comment\Plugin\Core\Entity\Comment $comment, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display) {
   // Check for the existence of a field added by another module.
   if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
     // Change its weight.
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index b73857c..adef64c 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -10,6 +10,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 use Drupal\file\Plugin\Core\Entity\File;
 use Drupal\Core\Entity\EntityInterface;
 use Symfony\Component\HttpFoundation\Request;
@@ -611,7 +612,7 @@ function theme_comment_block() {
 /**
  * Implements hook_node_view().
  */
-function comment_node_view(Node $node, $view_mode) {
+function comment_node_view(Node $node, EntityDisplay $display, $view_mode) {
   $links = array();
 
   if ($node->comment != COMMENT_NODE_HIDDEN) {
diff --git a/core/modules/comment/lib/Drupal/comment/CommentRenderController.php b/core/modules/comment/lib/Drupal/comment/CommentRenderController.php
index 6a57517..07391f9 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentRenderController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentRenderController.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityRenderController;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Render controller for comments.
@@ -21,7 +22,7 @@ class CommentRenderController extends EntityRenderController {
    * In addition to modifying the content key on entities, this implementation
    * will also set the node key which all comments carry.
    */
-  public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
+  public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
     $return = array();
     if (empty($entities)) {
       return $return;
@@ -30,7 +31,7 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
     // Attach user account.
     user_attach_accounts($entities);
 
-    parent::buildContent($entities, $view_mode, $langcode);
+    parent::buildContent($entities, $displays, $view_mode, $langcode);
 
     // Load all nodes of all comments at once.
     $nids = array();
@@ -67,8 +68,8 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
   /**
    * Overrides Drupal\Core\Entity\EntityRenderController::alterBuild().
    */
-  protected function alterBuild(array &$build, EntityInterface $comment, $view_mode, $langcode = NULL) {
-    parent::alterBuild($build, $comment, $view_mode, $langcode);
+  protected function alterBuild(array &$build, EntityInterface $comment, EntityDisplay $display, $view_mode, $langcode = NULL) {
+    parent::alterBuild($build, $comment, $display, $view_mode, $langcode);
     if (empty($comment->in_preview)) {
       $prefix = '';
       $is_threaded = isset($comment->divs)
@@ -95,4 +96,5 @@ protected function alterBuild(array &$build, EntityInterface $comment, $view_mod
       }
     }
   }
+
 }
diff --git a/core/modules/contact/lib/Drupal/contact/MessageRenderController.php b/core/modules/contact/lib/Drupal/contact/MessageRenderController.php
index 7a1db0d..b3a8a31 100644
--- a/core/modules/contact/lib/Drupal/contact/MessageRenderController.php
+++ b/core/modules/contact/lib/Drupal/contact/MessageRenderController.php
@@ -18,19 +18,17 @@ class MessageRenderController extends EntityRenderController {
   /**
    * Overrides Drupal\Core\Entity\EntityRenderController::buildContent().
    */
-  public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
-    parent::buildContent($entities, $view_mode, $langcode);
+  public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
+    parent::buildContent($entities, $displays, $view_mode, $langcode);
 
     foreach ($entities as $entity) {
       // Add the message extra field, if enabled.
-      $entity_view_mode = $entity->content['#view_mode'];
-      $fields = field_extra_fields_get_display($entity, $entity_view_mode);
-      if (!empty($entity->message) && !empty($fields['message']['visible'])) {
+      $display = $displays[$entity->bundle()];
+      if (!empty($entity->message) && $display->getComponent('message')) {
         $entity->content['message'] = array(
           '#type' => 'item',
           '#title' => t('Message'),
           '#markup' => check_plain($entity->message),
-          '#weight' => $fields['message']['weight'],
         );
       }
     }
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 01b0122..c1cd589 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -724,33 +724,6 @@ function field_view_mode_settings($entity_type, $bundle) {
 }
 
 /**
- * Returns the display options to use for pseudo-fields in a given view mode.
- *
- * @todo Remove when all steps in the view callstack receive the
- * entity_display.
- *
- * @param $entity
- *   The entity.
- * @param $view_mode
- *   The view mode.
- *
- * @return
- *   The display options to be used when viewing the entity's pseudo-fields in
- *   the view mode.
- */
-function field_extra_fields_get_display($entity, $view_mode) {
-  $entity_display = entity_get_render_display($entity, $view_mode);
-  $extra_fields = field_info_extra_fields($entity->entityType(), $entity->bundle(), 'display');
-
-  $options = array();
-  foreach ($extra_fields as $name => $value) {
-    $options[$name] = $entity_display->getComponent($name);
-  }
-
-  return $options;
-}
-
-/**
  * Pre-render callback: Adjusts weights and visibility of non-field elements.
  */
 function _field_extra_fields_pre_render($elements) {
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
index 2666409..02a0260 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterBase.php
@@ -39,13 +39,6 @@
   protected $settings;
 
   /**
-   * The formatter weight.
-   *
-   * @var int
-   */
-  protected $weight;
-
-  /**
    * The label display setting.
    *
    * @var string
@@ -71,20 +64,17 @@
    *   The field instance to which the formatter is associated.
    * @param array $settings
    *   The formatter settings.
-   * @param int $weight
-   *   The formatter weight.
    * @param string $label
    *   The formatter label display setting.
    * @param string $view_mode
    *   The view mode.
    */
-  public function __construct($plugin_id, DiscoveryInterface $discovery, $instance, array $settings, $weight, $label, $view_mode) {
+  public function __construct($plugin_id, DiscoveryInterface $discovery, $instance, array $settings, $label, $view_mode) {
     parent::__construct(array(), $plugin_id, $discovery);
 
     $this->instance = $instance;
     $this->field = field_info_field($instance['field_name']);
     $this->settings = $settings;
-    $this->weight = $weight;
     $this->label = $label;
     $this->viewMode = $view_mode;
   }
@@ -103,7 +93,6 @@ public function view(EntityInterface $entity, $langcode, array $items) {
       $entity_type = $entity->entityType();
       $info = array(
         '#theme' => 'field',
-        '#weight' => $this->weight,
         '#title' => $instance['label'],
         '#access' => field_access('view', $field, $entity_type, $entity),
         '#label_display' => $this->label,
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php
index 8abf0f1..bb7d066 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterFactory.php
@@ -19,6 +19,6 @@ class FormatterFactory extends DefaultFactory {
    */
   public function createInstance($plugin_id, array $configuration) {
     $plugin_class = $this->getPluginClass($plugin_id);
-    return new $plugin_class($plugin_id, $this->discovery, $configuration['instance'], $configuration['settings'], $configuration['weight'], $configuration['label'], $configuration['view_mode']);
+    return new $plugin_class($plugin_id, $this->discovery, $configuration['instance'], $configuration['settings'], $configuration['label'], $configuration['view_mode']);
   }
 }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
index 939df9c..d5f5891 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Formatter/FormatterPluginManager.php
@@ -62,8 +62,6 @@ public function __construct() {
    *       requested formatter is not available.
    *     - settings: (array) Settings specific to the formatter. Each setting
    *       defaults to the default value specified in the formatter definition.
-   *     - weight: (float) The weight to assign to the renderable element.
-   *       Defaults to 0.
    *
    * @return \Drupal\field\Plugin\Type\Formatter\FormatterInterface
    *   A formatter object.
@@ -113,7 +111,6 @@ public function prepareConfiguration($field_type, array $configuration) {
     $configuration += array(
       'label' => 'above',
       'settings' => array(),
-      'weight' => 0,
     );
     // If no formatter is specified, use the default formatter.
     if (!isset($configuration['type'])) {
diff --git a/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php b/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php
index 4f2c4f5..96fd63f 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/field/formatter/LegacyFormatter.php
@@ -38,7 +38,6 @@ public function settingsForm(array $form, array &$form_state) {
     $instance['display'][$this->viewMode] = array(
       'type' => $this->getPluginId(),
       'settings' => $this->getSettings(),
-      'weight' => $this->weight,
       'label' => $this->label,
     );
 
@@ -62,7 +61,6 @@ public function settingsSummary() {
     $instance['display'][$this->viewMode] = array(
       'type' => $this->getPluginId(),
       'settings' => $this->getSettings(),
-      'weight' => $this->weight,
       'label' => $this->label,
     );
 
@@ -88,7 +86,6 @@ public function prepareView(array $entities, $langcode, array &$items) {
       $display = array(
         'type' => $this->getPluginId(),
         'settings' => $this->getSettings(),
-        'weight' => $this->weight,
         'label' => $this->label,
       );
       $displays = array();
@@ -111,7 +108,6 @@ public function viewElements(EntityInterface $entity, $langcode, array $items) {
       $display = array(
         'type' => $this->getPluginId(),
         'settings' => $this->getSettings(),
-        'weight' => $this->weight,
         'label' => $this->label,
       );
 
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index f5eb8be..3177662 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 use Drupal\taxonomy\Plugin\Core\Entity\Term;
 
 /**
@@ -253,7 +254,7 @@ function _forum_node_check_node_type(Node $node) {
 /**
  * Implements hook_node_view().
  */
-function forum_node_view(Node $node, $view_mode) {
+function forum_node_view(Node $node, EntityDisplay $display, $view_mode) {
   $vid = config('forum.settings')->get('vocabulary');
   $vocabulary = taxonomy_vocabulary_load($vid);
   if (_forum_node_check_node_type($node)) {
diff --git a/core/modules/node/lib/Drupal/node/NodeRenderController.php b/core/modules/node/lib/Drupal/node/NodeRenderController.php
index 606722a..e829e40 100644
--- a/core/modules/node/lib/Drupal/node/NodeRenderController.php
+++ b/core/modules/node/lib/Drupal/node/NodeRenderController.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityRenderController;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Render controller for nodes.
@@ -18,7 +19,7 @@ class NodeRenderController extends EntityRenderController {
   /**
    * Overrides Drupal\Core\Entity\EntityRenderController::buildContent().
    */
-  public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
+  public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
     $return = array();
     if (empty($entities)) {
       return $return;
@@ -27,15 +28,16 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
     // Attach user account.
     user_attach_accounts($entities);
 
-    parent::buildContent($entities, $view_mode, $langcode);
+    parent::buildContent($entities, $displays, $view_mode, $langcode);
 
     foreach ($entities as $key => $entity) {
-      $entity_view_mode = $entity->content['#view_mode'];
+      $bundle = $entity->bundle();
+      $display = $displays[$bundle];
 
       // The 'view' hook can be implemented to overwrite the default function
       // to display nodes.
-      if (node_hook($entity->bundle(), 'view')) {
-        $entity = node_invoke($entity, 'view', $entity_view_mode, $langcode);
+      if (node_hook($bundle, 'view')) {
+        $entity = node_invoke($entity, 'view', $display, $view_mode, $langcode);
       }
 
       $entity->content['links'] = array(
@@ -47,7 +49,7 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
       // Always display a read more link on teasers because we have no way
       // to know when a teaser view is different than a full view.
       $links = array();
-      if ($entity_view_mode == 'teaser') {
+      if ($view_mode == 'teaser') {
         $node_title_stripped = strip_tags($entity->label());
         $links['node-readmore'] = array(
           'title' => t('Read more<span class="element-invisible"> about @title</span>', array(
@@ -69,22 +71,23 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
       );
 
       // Add Language field text element to node render array.
-      $entity->content['language'] = array(
-        '#type' => 'item',
-        '#title' => t('Language'),
-        '#markup' => language_name($langcode),
-        '#weight' => 0,
-        '#prefix' => '<div id="field-language-display">',
-        '#suffix' => '</div>'
-      );
+      if ($display->getComponent('language')) {
+        $entity->content['language'] = array(
+          '#type' => 'item',
+          '#title' => t('Language'),
+          '#markup' => language_name($langcode),
+          '#prefix' => '<div id="field-language-display">',
+          '#suffix' => '</div>'
+        );
+      }
     }
   }
 
   /**
    * Overrides Drupal\Core\Entity\EntityRenderController::alterBuild().
    */
-  protected function alterBuild(array &$build, EntityInterface $entity, $view_mode, $langcode = NULL) {
-    parent::alterBuild($build, $entity, $view_mode, $langcode);
+  protected function alterBuild(array &$build, EntityInterface $entity, EntityDisplay $display, $view_mode, $langcode = NULL) {
+    parent::alterBuild($build, $entity, $display, $view_mode, $langcode);
     // Add contextual links for this node, except when the node is already being
     // displayed on its own page. Modules may alter this behavior (for example,
     // to restrict contextual links to certain view modes) by implementing
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeBuildContentTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeBuildContentTest.php
index ac56041..17833d9 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeBuildContentTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeBuildContentTest.php
@@ -30,8 +30,7 @@ function testNodeRebuildContent() {
     $node->content['test_content_property'] = array(
       '#value' => $this->randomString(),
     );
-    $nodes = array($node);
-    $content = entity_render_controller('node')->buildContent($nodes);
+    $content = node_view($node);
 
     // If the property doesn't exist it means the node->content was rebuilt.
     $this->assertFalse(isset($content['test_content_property']), 'Node content was emptied prior to being built.');
diff --git a/core/modules/node/node.api.php b/core/modules/node/node.api.php
index c139952..0959e76 100644
--- a/core/modules/node/node.api.php
+++ b/core/modules/node/node.api.php
@@ -831,11 +831,14 @@ function hook_node_submit(Drupal\node\Node $node, $form, &$form_state) {
  * the RSS item generated for this node.
  * For details on how this is used, see node_feed().
  *
- * @param Drupal\node\Node $node
+ * @param \Drupal\node\Plugin\Core\Entity\Node $node
  *   The node that is being assembled for rendering.
- * @param $view_mode
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   node components.
+ * @param string $view_mode
  *   The $view_mode parameter from node_view().
- * @param $langcode
+ * @param string $langcode
  *   The language code used for rendering.
  *
  * @see forum_node_view()
@@ -844,12 +847,16 @@ function hook_node_submit(Drupal\node\Node $node, $form, &$form_state) {
  *
  * @ingroup node_api_hooks
  */
-function hook_node_view(Drupal\node\Node $node, $view_mode, $langcode) {
-  $node->content['my_additional_field'] = array(
-    '#markup' => $additional_field,
-    '#weight' => 10,
-    '#theme' => 'mymodule_my_additional_field',
-  );
+function hook_node_view(\Drupal\node\Plugin\Core\Entity\Node $node, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display, $view_mode, $langcode) {
+  // Only do the extra work if the component is configured to be displayed.
+  // This assumes a 'mymodule_addition' extra field has been defined for the
+  // node type in hook_field_extra_fields().
+  if ($display->getComponent('mymodule_addition')) {
+    $node->content['mymodule_addition'] = array(
+      '#markup' => mymodule_addition($node),
+      '#theme' => 'mymodule_my_additional_field',
+    );
+  }
 }
 
 /**
@@ -867,15 +874,18 @@ function hook_node_view(Drupal\node\Node $node, $view_mode, $langcode) {
  *
  * @param $build
  *   A renderable array representing the node content.
- * @param Drupal\node\Node $node
+ * @param \Drupal\node\Plugin\Core\Entity\Node $node
  *   The node being rendered.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   node components.
  *
  * @see node_view()
  * @see hook_entity_view_alter()
  *
  * @ingroup node_api_hooks
  */
-function hook_node_view_alter(&$build, Drupal\node\Node $node) {
+function hook_node_view_alter(&$build, \Drupal\node\Plugin\Core\Entity\Node $node, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display) {
   if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
     // Change its weight.
     $build['an_additional_field']['#weight'] = -10;
@@ -1279,8 +1289,11 @@ function hook_validate(Drupal\node\Node $node, $form, &$form_state) {
  * that the node type module can define a custom method for display, or add to
  * the default display.
  *
- * @param Drupal\node\Node $node
+ * @param \Drupal\node\Plugin\Core\Entity\Node $node
  *   The node to be displayed, as returned by node_load().
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   node components.
  * @param $view_mode
  *   View mode, e.g. 'full', 'teaser', ...
  *
@@ -1297,7 +1310,7 @@ function hook_validate(Drupal\node\Node $node, $form, &$form_state) {
  *
  * @ingroup node_api_hooks
  */
-function hook_view(Drupal\node\Node $node, $view_mode) {
+function hook_view(\Drupal\node\Plugin\Core\Entity\Node $node, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display, $view_mode) {
   if ($view_mode == 'full' && node_is_page($node)) {
     $breadcrumb = array();
     $breadcrumb[] = l(t('Home'), NULL);
@@ -1306,10 +1319,15 @@ function hook_view(Drupal\node\Node $node, $view_mode) {
     drupal_set_breadcrumb($breadcrumb);
   }
 
-  $node->content['myfield'] = array(
-    '#markup' => theme('mymodule_myfield', $node->myfield),
-    '#weight' => 1,
-  );
+  // Only do the extra work if the component is configured to be displayed.
+  // This assumes a 'mymodule_addition' extra field has been defined for the
+  // node type in hook_field_extra_fields().
+  if ($display->getComponent('mymodule_addition')) {
+    $node->content['mymodule_addition'] = array(
+      '#markup' => mymodule_addition($node),
+      '#theme' => 'mymodule_my_additional_field',
+    );
+  }
 
   return $node;
 }
diff --git a/core/modules/node/tests/modules/node_test/node_test.module b/core/modules/node/tests/modules/node_test/node_test.module
index 5e0a7ac..36b59c9 100644
--- a/core/modules/node/tests/modules/node_test/node_test.module
+++ b/core/modules/node/tests/modules/node_test/node_test.module
@@ -9,6 +9,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Implements hook_node_load().
@@ -29,7 +30,7 @@ function node_test_node_load($nodes, $types) {
 /**
  * Implements hook_node_view().
  */
-function node_test_node_view(Node $node, $view_mode) {
+function node_test_node_view(Node $node, EntityDisplay $display, $view_mode) {
   if ($view_mode == 'rss') {
     // Add RSS elements and namespaces when building the RSS feed.
     $node->rss_elements[] = array(
diff --git a/core/modules/poll/poll.module b/core/modules/poll/poll.module
index 0a81e9e..220f3a9 100644
--- a/core/modules/poll/poll.module
+++ b/core/modules/poll/poll.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Implements hook_help().
@@ -681,14 +682,13 @@ function poll_block_latest_poll_view(Node $node) {
  *
  * @see poll_view_results()
  */
-function poll_view($node, $view_mode) {
-  global $user;
-  $output = '';
-
+function poll_view($node, EntityDisplay $display, $view_mode) {
   if (!empty($node->allowvotes) && empty($node->show_results)) {
-    $node->content['poll_view_voting'] = drupal_get_form('poll_view_voting', $node);
+    if ($display->getComponent('poll_view_voting')) {
+      $node->content['poll_view_voting'] = drupal_get_form('poll_view_voting', $node);
+    }
   }
-  else {
+  elseif ($display->getComponent('poll_view_results')) {
     $node->content['poll_view_results'] = array('#markup' => poll_view_results($node, $view_mode));
   }
   return $node;
diff --git a/core/modules/statistics/statistics.module b/core/modules/statistics/statistics.module
index a359981..4077b27 100644
--- a/core/modules/statistics/statistics.module
+++ b/core/modules/statistics/statistics.module
@@ -6,6 +6,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Implements hook_help().
@@ -101,7 +102,7 @@ function statistics_permission() {
 /**
  * Implements hook_node_view().
  */
-function statistics_node_view(Node $node, $view_mode) {
+function statistics_node_view(Node $node, EntityDisplay $display, $view_mode) {
   if (!empty($node->nid) && $view_mode == 'full' && node_is_page($node) && empty($node->in_preview)) {
     $node->content['#attached']['library'][] = array('statistics', 'drupal.statistics');
     $settings = array('data' => array('nid' => $node->nid), 'url' => url(drupal_get_path('module', 'statistics') . '/statistics.php'));
diff --git a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
index b2e3adb..2c6c00a 100644
--- a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
+++ b/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
@@ -8,6 +8,7 @@
  */
 
 use Drupal\taxonomy\Plugin\Core\Entity\Term;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Implements hook_taxonomy_term_load().
@@ -61,7 +62,7 @@ function taxonomy_test_taxonomy_term_delete(Term $term) {
 /**
  * Implements hook_taxonomy_term_view().
  */
-function taxonomy_test_taxonomy_term_view($term, $view_mode, $langcode) {
+function taxonomy_test_taxonomy_term_view(Term $term, EntityDisplay $display, $view_mode, $langcode) {
   if ($view_mode == 'full') {
     $term->content['taxonomy_test_term_view_check'] = array(
       '#prefix' => '<div>',
@@ -75,7 +76,7 @@ function taxonomy_test_taxonomy_term_view($term, $view_mode, $langcode) {
 /**
  * Implements hook_entity_view().
  */
-function taxonomy_test_entity_view($entity, $view_mode, $langcode) {
+function taxonomy_test_entity_view($entity, EntityDisplay $display, $view_mode, $langcode) {
   if ($entity->entityType() == 'taxonomy_term' && $view_mode == 'full') {
     $entity->content['taxonomy_test_entity_view_check'] = array(
       '#prefix' => '<div>',
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
index ac44448..ce8cb03 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/TermRenderController.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityRenderController;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Render controller for taxonomy terms.
@@ -18,17 +19,15 @@ class TermRenderController extends EntityRenderController {
   /**
    * Overrides Drupal\Core\Entity\EntityRenderController::buildContent().
    */
-  public function buildContent(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
-    parent::buildContent($entities, $view_mode, $langcode);
+  public function buildContent(array $entities, array $displays, $view_mode, $langcode = NULL) {
+    parent::buildContent($entities, $displays, $view_mode, $langcode);
 
     foreach ($entities as $entity) {
       // Add the description if enabled.
-      $entity_view_mode = $entity->content['#view_mode'];
-      $display = field_extra_fields_get_display($entity, $entity_view_mode);
-      if (!empty($entity->description) && !empty($display['description'])) {
+      $display = $displays[$entity->bundle()];
+      if (!empty($entity->description) && $display->getComponent('description')) {
         $entity->content['description'] = array(
           '#markup' => check_markup($entity->description, $entity->format, '', TRUE),
-          '#weight' => $display['description']['weight'],
           '#prefix' => '<div class="taxonomy-term-description">',
           '#suffix' => '</div>',
         );
@@ -36,6 +35,9 @@ public function buildContent(array $entities = array(), $view_mode = 'full', $la
     }
   }
 
+  /**
+   * Overrides \Drupal\Core\Entity\EntityRenderController::getBuildDefaults().
+   */
   protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langcode) {
     $return = parent::getBuildDefaults($entity, $view_mode, $langcode);
 
@@ -46,8 +48,12 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode, $langco
     return $return;
   }
 
-  protected function alterBuild(array &$build, EntityInterface $entity, $view_mode, $langcode = NULL) {
-    parent::alterBuild($build, $entity, $view_mode, $langcode);
+  /**
+   * Overrides \Drupal\Core\Entity\EntityRenderController::alterBuild().
+   */
+  protected function alterBuild(array &$build, EntityInterface $entity, EntityDisplay $display, $view_mode, $langcode = NULL) {
+    parent::alterBuild($build, $entity, $display, $view_mode, $langcode);
     $build['#attached']['css'][] = drupal_get_path('module', 'taxonomy') . '/taxonomy.css';
   }
+
 }
diff --git a/core/modules/taxonomy/taxonomy.api.php b/core/modules/taxonomy/taxonomy.api.php
index d4d2675..956b8b4 100644
--- a/core/modules/taxonomy/taxonomy.api.php
+++ b/core/modules/taxonomy/taxonomy.api.php
@@ -231,8 +231,11 @@ function hook_taxonomy_term_delete(Drupal\taxonomy\Term $term) {
  * structure of $term->content is a renderable array as expected by
  * drupal_render().
  *
- * @param $term
+ * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
  *   The term that is being assembled for rendering.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   term components.
  * @param $view_mode
  *   The $view_mode parameter from taxonomy_term_view().
  * @param $langcode
@@ -240,12 +243,16 @@ function hook_taxonomy_term_delete(Drupal\taxonomy\Term $term) {
  *
  * @see hook_entity_view()
  */
-function hook_taxonomy_term_view($term, $view_mode, $langcode) {
-  $term->content['my_additional_field'] = array(
-    '#markup' => $additional_field,
-    '#weight' => 10,
-    '#theme' => 'mymodule_my_additional_field',
-  );
+function hook_taxonomy_term_view(\Drupal\taxonomy\Plugin\Core\Entity\Term $term, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display, $view_mode, $langcode) {
+  // Only do the extra work if the component is configured to be displayed.
+  // This assumes a 'mymodule_addition' extra field has been defined for the
+  // vocabulary in hook_field_extra_fields().
+  if ($display->getComponent('mymodule_addition')) {
+    $term->content['mymodule_addition'] = array(
+      '#markup' => mymodule_addition($term),
+      '#theme' => 'mymodule_my_additional_field',
+    );
+  }
 }
 
 /**
@@ -263,12 +270,15 @@ function hook_taxonomy_term_view($term, $view_mode, $langcode) {
  *
  * @param $build
  *   A renderable array representing the taxonomy term content.
- * @param Drupal\taxonomy\Term $term
+ * @param \Drupal\taxonomy\Plugin\Core\Entity\Term $term
  *   The taxonomy term being rendered.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   term components.
  *
  * @see hook_entity_view_alter()
  */
-function hook_taxonomy_term_view_alter(&$build, Drupal\taxonomy\Term $term) {
+function hook_taxonomy_term_view_alter(&$build, \Drupal\taxonomy\Plugin\Core\Entity\Term $term, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display) {
   if ($build['#view_mode'] == 'full' && isset($build['an_additional_field'])) {
     // Change its weight.
     $build['an_additional_field']['#weight'] = -10;
diff --git a/core/modules/translation/translation.module b/core/modules/translation/translation.module
index 69d01c3..d770846 100644
--- a/core/modules/translation/translation.module
+++ b/core/modules/translation/translation.module
@@ -20,6 +20,7 @@
  */
 
 use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 
 /**
  * Implements hook_help().
@@ -248,7 +249,7 @@ function translation_form_node_form_alter(&$form, &$form_state) {
  * translation set. If no language provider is enabled, "fall back" to simple
  * links built through the result of translation_node_get_translations().
  */
-function translation_node_view(Node $node, $view_mode) {
+function translation_node_view(Node $node, EntityDisplay $display, $view_mode) {
   // If the site has no translations or is not multilingual we have no content
   // translation links to display.
   if (isset($node->tnid) && language_multilingual() && $translations = translation_node_get_translations($node->tnid)) {
diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php
index b5bbbf7..c303a98 100644
--- a/core/modules/user/user.api.php
+++ b/core/modules/user/user.api.php
@@ -333,8 +333,11 @@ function hook_user_logout($account) {
  * The module should format its custom additions for display and add them to the
  * $account->content array.
  *
- * @param $account
+ * @param \Drupal\user\Plugin\Core\Entity\User $account
  *   The user object on which the operation is being performed.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   user components.
  * @param $view_mode
  *   View mode, e.g. 'full'.
  * @param $langcode
@@ -343,21 +346,16 @@ function hook_user_logout($account) {
  * @see hook_user_view_alter()
  * @see hook_entity_view()
  */
-function hook_user_view($account, $view_mode, $langcode) {
-  if (!isset($account->content['summary'])) {
-    $account->content['summary'] = array();
+function hook_user_view(\Drupal\user\Plugin\Core\Entity\User $account, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display, $view_mode, $langcode) {
+  // Only do the extra work if the component is configured to be displayed.
+  // This assumes a 'mymodule_addition' extra field has been defined for the
+  // user entity type in hook_field_extra_fields().
+  if ($display->getComponent('mymodule_addition')) {
+    $account->content['mymodule_addition'] = array(
+      '#markup' => mymodule_addition($account),
+      '#theme' => 'mymodule_my_additional_field',
+    );
   }
-  $account->content['summary'] += array(
-    '#type' => 'user_profile_category',
-    '#title' => t('History'),
-    '#attributes' => array('class' => array('user-member')),
-    '#weight' => 5,
-  );
-  $account->content['summary']['member_for'] = array(
-    '#type' => 'user_profile_item',
-    '#title' => t('Member for'),
-    '#markup' => format_interval(REQUEST_TIME - $account->created),
-  );
 }
 
 /**
@@ -375,13 +373,16 @@ function hook_user_view($account, $view_mode, $langcode) {
  *
  * @param $build
  *   A renderable array representing the user.
- * @param Drupal\user\User $account
+ * @param \Drupal\user\Plugin\Core\Entity\User $account
  *   The user account being rendered.
+ * @param \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display
+ *   The entity_display object holding the display options configured for the
+ *   user components.
  *
  * @see user_view()
  * @see hook_entity_view_alter()
  */
-function hook_user_view_alter(&$build, Drupal\user\User $account) {
+function hook_user_view_alter(&$build, \Drupal\user\Plugin\Core\Entity\User $account, \Drupal\entity\Plugin\Core\Entity\EntityDisplay $display) {
   // Check for the existence of a field added by another module.
   if (isset($build['an_additional_field'])) {
     // Change its weight.
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index aa5d085..4ac6c4a 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -2,7 +2,10 @@
 
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\comment\Plugin\Core\Entity\Comment;
+use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 use Drupal\file\Plugin\Core\Entity\File;
+use Drupal\user\Plugin\Core\Entity\User;
 use Drupal\Core\Template\Attribute;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
@@ -151,7 +154,8 @@ function user_label($entity_type, $entity) {
 /**
  * Populates $entity->account for each prepared entity.
  *
- * Called by hook_entity_prepare_view() implementations.
+ * Called by Drupal\Core\Entity\EntityRenderControllerInterface::buildContent()
+ * implementations.
  *
  * @param array $entities
  *   The entities keyed by entity ID.
@@ -583,13 +587,14 @@ function user_search_execute($keys = NULL, $conditions = NULL) {
 /**
  * Implements hook_user_view().
  */
-function user_user_view($account) {
-  $account->content['member_for'] = array(
-    '#type' => 'item',
-    '#title' => t('Member for'),
-    '#markup' => format_interval(REQUEST_TIME - $account->created),
-    '#weight' => 5,
-  );
+function user_user_view(User $account, EntityDisplay $display) {
+  if ($display->getComponent('member_for')) {
+    $account->content['member_for'] = array(
+      '#type' => 'item',
+      '#title' => t('Member for'),
+      '#markup' => format_interval(REQUEST_TIME - $account->created),
+    );
+  }
 }
 
 /**
@@ -2556,7 +2561,7 @@ function user_build_filter_query(SelectInterface $query) {
 /**
  * Implements hook_comment_view().
  */
-function user_comment_view($comment) {
+function user_comment_view(Comment $comment, EntityDisplay $display) {
   if (config('user.settings')->get('signatures') && !empty($comment->signature)) {
     // @todo This alters and replaces the original object value, so a
     //   hypothetical process of loading, viewing, and saving will hijack the
