diff --git a/core/modules/views/lib/Drupal/views/Form/ViewsForm.php b/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
index cc01f8d..5c52880 100644
--- a/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
+++ b/core/modules/views/lib/Drupal/views/Form/ViewsForm.php
@@ -113,7 +113,7 @@ public function getFormID() {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, array &$form_state, ViewExecutable $view = NULL, $output = NULL) {
+  public function buildForm(array $form, array &$form_state, ViewExecutable $view = NULL, $output = array()) {
     $form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 'views_form_views_form';
     $form_state['step_controller']['views_form_views_form'] = 'Drupal\views\Form\ViewsFormMainForm';
 
diff --git a/core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php b/core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php
index 98cdc4f..60af825 100644
--- a/core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php
+++ b/core/modules/views/lib/Drupal/views/Form/ViewsFormMainForm.php
@@ -21,7 +21,7 @@ public function getFormID() {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, array &$form_state, ViewExecutable $view = NULL, $output = NULL) {
+  public function buildForm(array $form, array &$form_state, ViewExecutable $view = NULL, $output = array()) {
     $form['#prefix'] = '<div class="views-form">';
     $form['#suffix'] = '</div>';
     $form['#theme'] = 'form';
@@ -29,12 +29,10 @@ public function buildForm(array $form, array &$form_state, ViewExecutable $view
 
     // Add the output markup to the form array so that it's included when the form
     // array is passed to the theme function.
-    $form['output'] = array(
-      '#markup' => $output,
-      // This way any additional form elements will go before the view
-      // (below the exposed widgets).
-      '#weight' => 50,
-    );
+    $form['output'] = $output;
+    // This way any additional form elements will go before the view
+    // (below the exposed widgets).
+    $form['output']['#weight'] = 50;
 
     $form['actions'] = array(
       '#type' => 'actions',
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
index bc99b02..6a9be60 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/DisplayPluginBase.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Language\Language;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Theme\Registry;
+use Drupal\views\Form\ViewsForm;
 use Drupal\views\Plugin\views\area\AreaPluginBase;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\PluginBase;
@@ -2133,8 +2134,79 @@ public function render() {
     $element = array(
       '#theme' => $this->themeFunctions(),
       '#view' => $this->view,
+      '#attached' => &$this->view->element['#attached'],
+      '#pre_render' => array(array(get_class($this), 'elementPreRender')),
     );
-    $element['#attached'] = &$this->view->element['#attached'];
+
+    return $element;
+  }
+
+  /**
+   * Pre render callback for view display rendering.
+   *
+   * @see self::render()
+   *
+   * @param array $element
+   *
+   * @return array
+   */
+  public static function elementPreRender($element) {
+    $view = $element['#view'];
+    $empty = empty($view->result);
+
+    $element['#rows'] = (!$empty || $view->style_plugin->evenEmpty()) ? $view->style_plugin->render($view->result) : array();
+
+    // Force a render array so CSS/JS can be added.
+    if (!is_array($element['#rows'])) {
+      $element['#rows'] = array('#markup' => $element['#rows']);
+    }
+
+    $element['#header'] = $view->display_handler->renderArea('header', $empty);
+    $element['#footer'] = $view->display_handler->renderArea('footer', $empty);
+    $element['#empty'] = $empty ? $view->display_handler->renderArea('empty', $empty) : array();
+    $element['#exposed'] = !empty($view->exposed_widgets) ? $view->exposed_widgets : array();
+    $element['#more'] = $view->display_handler->renderMoreLink();
+    $element['#feed_icon'] = !empty($view->feed_icon) ? $view->feed_icon : array();
+
+    if ($view->display_handler->renderPager()) {
+      $exposed_input = isset($view->exposed_raw_input) ? $view->exposed_raw_input : NULL;
+      $element['#pager'] = $view->renderPager($exposed_input);
+    }
+
+    if (!empty($view->attachment_before)) {
+      $element['#attachment_before'] = $view->attachment_before;
+    }
+    if (!empty($view->attachment_after)) {
+      $element['#attachment_after'] = $view->attachment_after;
+    }
+
+    // If form fields were found in the view, reformat the view output as a form.
+    if ($view->hasFormElements()) {
+      // Only render row output if there are rows. Otherwise, render the empty
+      // region.
+      if (!empty($element['#rows'])) {
+        $output = $element['#rows'];
+      }
+      else {
+        $output = $element['#empty'];
+      }
+
+      $container = \Drupal::getContainer();
+      $form_object = new ViewsForm($container->get('controller_resolver'), $container->get('url_generator'), $container->get('request'), $view->storage->id(), $view->current_display);
+      $form = \Drupal::formBuilder()->getForm($form_object, $view, $output);
+      // The form is requesting that all non-essential views elements be hidden,
+      // usually because the rendered step is not a view result.
+      if ($form['show_view_elements']['#value'] == FALSE) {
+        $element['#header'] = array();
+        $element['#exposed'] = array();
+        $element['#pager'] = array();
+        $element['#footer'] = array();
+        $element['#more'] = array();
+        $element['#feed_icon'] = array();
+      }
+
+      $element['#rows'] = $form;
+    }
 
     return $element;
   }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
index ed7a571..7a4c9db 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/display/Feed.php
@@ -79,7 +79,7 @@ public function execute() {
 
     $response = $this->view->getResponse();
 
-    $response->setContent($output);
+    $response->setContent(drupal_render($output));
 
     return $response;
   }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php
index 0a6f8cb..db26dbb 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/Rss.php
@@ -41,14 +41,10 @@ public function attachTo($display_id, $path, $title) {
     $url = url($this->view->getUrl(NULL, $path), $url_options);
     if ($display->hasPath()) {
       if (empty($this->preview)) {
-        $build['#attached']['drupal_add_feed'][] = array($url, $title);
-        drupal_render($build);
+        drupal_add_feed($url, $title);
       }
     }
     else {
-      if (empty($this->view->feed_icon)) {
-        $this->view->feed_icon = '';
-      }
       $feed_icon = array(
         '#theme' => 'feed_icon',
         '#url' => $url,
@@ -60,7 +56,7 @@ public function attachTo($display_id, $path, $title) {
         'title' => $title,
         'href' => $url,
       );
-      $this->view->feed_icon .= drupal_render($feed_icon);
+      $this->view->feed_icon = $feed_icon;
     }
   }
 
@@ -141,7 +137,7 @@ public function render() {
       '#rows' => $rows,
     );
     unset($this->view->row_index);
-    return drupal_render($build);
+    return $build;
   }
 
 }
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php
index 0426e68..108473c 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/style/StylePluginBase.php
@@ -470,9 +470,7 @@ public function renderGroupingSets($sets, $level = 0) {
         if ($this->usesRowPlugin()) {
           foreach ($set['rows'] as $index => $row) {
             $this->view->row_index = $index;
-            $render = $this->view->rowPlugin->render($row);
-            // Row render arrays cannot be contained by style render arrays.
-            $set['rows'][$index] = drupal_render($render);
+            $set['rows'][$index] = $this->view->rowPlugin->render($row);
           }
         }
 
diff --git a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php
index 02dd245..93e062c 100644
--- a/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php
+++ b/core/modules/views/tests/modules/views_test_data/lib/Drupal/views_test_data/Plugin/views/style/StyleTest.php
@@ -96,14 +96,14 @@ public function getOutput() {
    * Overrides Drupal\views\Plugin\views\style\StylePluginBase::render()
    */
   public function render() {
-    $output = '';
     if (!$this->usesRowPlugin()) {
       $output = $this->getOutput();
     }
     else {
+      $output = array();
       foreach ($this->view->result as $index => $row) {
         $this->view->row_index = $index;
-        $output .= $this->view->rowPlugin->render($row) . "\n";
+        $output[$index] = $this->view->rowPlugin->render($row) . "\n";
       }
     }
 
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 922a8d9..5975432 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -126,7 +126,21 @@ function views_theme($existing, $type, $theme, $path) {
     // For displays, we pass in a dummy array as the first parameter, since
     // $view is an object but the core contextual_preprocess() function only
     // attaches contextual links when the primary theme argument is an array.
-    'display' => array('view_array' => array(), 'view' => NULL),
+    'display' => array(
+      'view_array' => array(),
+      'view' => NULL,
+      'rows' => array(),
+      'header' => array(),
+      'footer' => array(),
+      'empty' => array(),
+      'exposed' => array(),
+      'more' => array(),
+      'feed_icon' => array(),
+      'pager' => array(),
+      'title' => '',
+      'attachment_before' => array(),
+      'attachment_after' => array(),
+    ),
     'style' => array('view' => NULL, 'options' => NULL, 'rows' => NULL, 'title' => NULL),
     'row' => array('view' => NULL, 'options' => NULL, 'row' => NULL, 'field_alias' => NULL),
     'exposed_form' => array('view' => NULL, 'options' => NULL),
@@ -903,11 +917,12 @@ function views_pre_render_views_form_views_form($element) {
   }
 
   // Apply substitutions to the rendered output.
-  $element['output']['#markup'] = str_replace($search, $replace, $element['output']['#markup']);
+  $element['output'] = array('#markup' => str_replace($search, $replace, drupal_render($element['output'])));
 
   // Sort, render and add remaining form fields.
   $children = element_children($element, TRUE);
   $element['#children'] = drupal_render_children($element, $children);
+
   return $element;
 }
 
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index eaf3d86..7ec86e7 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -9,7 +9,6 @@
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Template\Attribute;
-use Drupal\views\Form\ViewsForm;
 use Drupal\views\ViewExecutable;
 
 /**
@@ -23,20 +22,13 @@
  */
 function template_preprocess_views_view(&$variables) {
   $view = $variables['view'];
+  $id = $view->storage->id();
 
-  $variables['rows'] = (!empty($view->result) || $view->style_plugin->evenEmpty()) ? $view->style_plugin->render($view->result) : array();
-  // Force a render array so CSS/JS can be added.
-  if (!is_array($variables['rows'])) {
-    $variables['rows'] = array('#markup' => $variables['rows']);
-  }
-
-  $variables['css_name'] = drupal_clean_css_identifier($view->storage->id());
-  $variables['id'] = $view->storage->id();
+  $variables['css_name'] = drupal_clean_css_identifier($id);
+  $variables['id'] = $id;
   $variables['display_id'] = $view->current_display;
 
   // Basic classes.
-  $variables['css_class'] = '';
-
   $variables['attributes']['class'] = array();
   $variables['attributes']['class'][] = 'view';
   $variables['attributes']['class'][] = 'view-' . drupal_clean_css_identifier($variables['id']);
@@ -49,39 +41,6 @@ function template_preprocess_views_view(&$variables) {
     $variables['attributes']['class'][] = $variables['css_class'];
   }
 
-  $empty = empty($view->result);
-  $variables['header'] = $view->display_handler->renderArea('header', $empty);
-  $variables['footer'] = $view->display_handler->renderArea('footer', $empty);
-  $variables['empty'] = $empty ? $view->display_handler->renderArea('empty', $empty) : FALSE;
-
-  $variables['exposed']    = !empty($view->exposed_widgets) ? $view->exposed_widgets : '';
-  $variables['more']       = $view->display_handler->renderMoreLink();
-  $variables['feed_icon']  = !empty($view->feed_icon) ? $view->feed_icon : '';
-
-  $variables['pager']      = '';
-
-  // @todo: Figure out whether this belongs into views_ui_preprocess_views_view.
-  // Render title for the admin preview.
-  $variables['title'] = !empty($view->views_ui_context) ? filter_xss_admin($view->getTitle()) : '';
-
-  if ($view->display_handler->renderPager()) {
-    $exposed_input = isset($view->exposed_raw_input) ? $view->exposed_raw_input : NULL;
-    $variables['pager'] = $view->renderPager($exposed_input);
-  }
-
-  if (!empty($view->attachment_before)) {
-    $variables['attachment_before'] = $view->attachment_before;
-  }
-  else {
-    $variables['attachment_before'] = array();
-  }
-  if (!empty($view->attachment_after)) {
-    $variables['attachment_after'] = $view->attachment_after;
-  }
-  else {
-    $variables['attachment_after'] = array();
-  }
-
   // Add contextual links to the view. We need to attach them to the dummy
   // $view_array variable, since contextual_preprocess() requires that they be
   // attached to an array (not an object) in order to process them. For our
@@ -105,36 +64,6 @@ function template_preprocess_views_view(&$variables) {
     $variables['dom_id'] = $view->dom_id;
     $variables['attributes']['class'][] = 'view-dom-id-' . $variables['dom_id'];
   }
-
-  // If form fields were found in the view, reformat the view output as a form.
-  if ($view->hasFormElements()) {
-    // Copy the rows so as not to modify them by reference when rendering.
-    $rows = $variables['rows'];
-    // Only render row output if there are rows. Otherwise, render the empty
-    // region.
-    if (!empty($rows)) {
-      $output = drupal_render($rows);
-    }
-    else {
-      $empty = $variables['empty'];
-      $output = drupal_render($empty);
-    }
-
-    $container = \Drupal::getContainer();
-    $form_object = new ViewsForm($container->get('controller_resolver'), $container->get('url_generator'), $container->get('request'), $view->storage->id(), $view->current_display);
-    $form = \Drupal::formBuilder()->getForm($form_object, $view, $output);
-    // The form is requesting that all non-essential views elements be hidden,
-    // usually because the rendered step is not a view result.
-    if ($form['show_view_elements']['#value'] == FALSE) {
-      $variables['header'] = '';
-      $variables['exposed'] = '';
-      $variables['pager'] = '';
-      $variables['footer'] = '';
-      $variables['more'] = '';
-      $variables['feed_icon'] = '';
-    }
-    $variables['rows'] = $form;
-  }
 }
 
 /**
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
index f959d0d..43bf409 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
@@ -566,7 +566,6 @@ public function renderPreview($display_id, $args = array()) {
     if (empty($errors)) {
       $this->ajax = TRUE;
       $this->executable->live_preview = TRUE;
-      $this->views_ui_context = TRUE;
 
       // AJAX happens via HTTP POST but everything expects exposed data to
       // be in GET. Copy stuff but remove ajax-framework specific keys.
diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module
index 7f140d3..2574bad 100644
--- a/core/modules/views_ui/views_ui.module
+++ b/core/modules/views_ui/views_ui.module
@@ -12,6 +12,7 @@
 use Drupal\views\Analyzer;
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\ReplaceCommand;
+use Drupal\Component\Utility\Xss;
 
 /**
  * Implements hook_help().
@@ -166,6 +167,12 @@ function views_ui_permission() {
  */
 function views_ui_preprocess_views_view(&$variables) {
   $view = $variables['view'];
+
+  // Render title for the admin preview.
+  if (!empty($view->live_preview)) {
+    $variables['title'] = Xss::filterAdmin($view->getTitle());
+  }
+
   if (!empty($view->live_preview) && \Drupal::moduleHandler()->moduleExists('contextual')) {
     $view->setShowAdminLinks(FALSE);
     foreach (array('title', 'header', 'exposed', 'rows', 'pager', 'more', 'footer', 'empty', 'attachment_after', 'attachment_before') as $section) {
