diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php
index a05d3a8..d54e952 100644
--- a/core/modules/image/src/Entity/ImageStyle.php
+++ b/core/modules/image/src/Entity/ImageStyle.php
@@ -307,9 +307,9 @@ public function createDerivative($original_uri, $derivative_uri) {
   /**
    * {@inheritdoc}
    */
-  public function transformDimensions(array &$dimensions) {
+  public function transformDimensions(array &$dimensions, $uri = NULL) {
     foreach ($this->getEffects() as $effect) {
-      $effect->transformDimensions($dimensions);
+      $effect->transformDimensions($dimensions, $uri);
     }
   }
 
diff --git a/core/modules/image/src/ImageEffectBase.php b/core/modules/image/src/ImageEffectBase.php
index d0ef256..d1bd7a1 100644
--- a/core/modules/image/src/ImageEffectBase.php
+++ b/core/modules/image/src/ImageEffectBase.php
@@ -70,10 +70,8 @@ public static function create(ContainerInterface $container, array $configuratio
   /**
    * {@inheritdoc}
    */
-  public function transformDimensions(array &$dimensions) {
-    // Most image effects will not change the dimensions. This base
-    // implementation represents this behavior. Override this method if your
-    // image effect does change the dimensions.
+  public function transformDimensions(array &$dimensions, $uri = NULL) {
+    $dimensions['width'] = $dimensions['height'] = NULL;
   }
 
   /**
diff --git a/core/modules/image/src/ImageEffectInterface.php b/core/modules/image/src/ImageEffectInterface.php
index 7d2c4ca..79b3806 100644
--- a/core/modules/image/src/ImageEffectInterface.php
+++ b/core/modules/image/src/ImageEffectInterface.php
@@ -36,15 +36,13 @@ public function applyEffect(ImageInterface $image);
 
   /**
    * Determines the dimensions of the styled image.
-   *
-   * @param array &$dimensions
-   *   Dimensions to be modified - an array with the following keys:
-   *   - width: the width in pixels, or NULL if unknown
-   *   - height: the height in pixels, or NULL if unknown
-   *   When either of the dimensions are NULL, the corresponding HTML attribute
-   *   will be omitted when an image style using this image effect is used.
+   * @param array $dimensions
+   *   Dimensions to be modified - an array with components width and height, in
+   *   pixels.
+   * @param string $uri
+   *   The path of the image file relative to the Drupal files directory.
    */
-  public function transformDimensions(array &$dimensions);
+  public function transformDimensions(array &$dimensions, $uri = NULL);
 
   /**
    * Returns the extension the derivative would have have after applying this
diff --git a/core/modules/image/src/ImageStyleInterface.php b/core/modules/image/src/ImageStyleInterface.php
index b28d199..e20621d 100644
--- a/core/modules/image/src/ImageStyleInterface.php
+++ b/core/modules/image/src/ImageStyleInterface.php
@@ -127,8 +127,10 @@ public function createDerivative($original_uri, $derivative_uri);
    * @param array $dimensions
    *   Associative array passed by reference. Implementations have to store the
    *   resulting width and height, in pixels.
+   * @param string $uri
+   *   The path of the image file relative to the Drupal files directory.
    */
-  public function transformDimensions(array &$dimensions);
+  public function transformDimensions(array &$dimensions, $uri = NULL);
 
   /**
    * Determines the extension of the derivative without generating it.
diff --git a/core/modules/image/src/Plugin/ImageEffect/DesaturateImageEffect.php b/core/modules/image/src/Plugin/ImageEffect/DesaturateImageEffect.php
index 008f6a8..9b275ab 100644
--- a/core/modules/image/src/Plugin/ImageEffect/DesaturateImageEffect.php
+++ b/core/modules/image/src/Plugin/ImageEffect/DesaturateImageEffect.php
@@ -24,6 +24,12 @@ class DesaturateImageEffect extends ImageEffectBase {
   /**
    * {@inheritdoc}
    */
+  public function transformDimensions(array &$dimensions, $uri = NULL) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function applyEffect(ImageInterface $image) {
     if (!$image->desaturate()) {
       $this->logger->error('Image desaturate failed using the %toolkit toolkit on %path (%mimetype, %dimensions)', array('%toolkit' => $image->getToolkitId(), '%path' => $image->getSource(), '%mimetype' => $image->getMimeType(), '%dimensions' => $image->getWidth() . 'x' . $image->getHeight()));
diff --git a/core/modules/image/src/Plugin/ImageEffect/ResizeImageEffect.php b/core/modules/image/src/Plugin/ImageEffect/ResizeImageEffect.php
index 37c2c93..1106f0c 100644
--- a/core/modules/image/src/Plugin/ImageEffect/ResizeImageEffect.php
+++ b/core/modules/image/src/Plugin/ImageEffect/ResizeImageEffect.php
@@ -36,7 +36,7 @@ public function applyEffect(ImageInterface $image) {
   /**
    * {@inheritdoc}
    */
-  public function transformDimensions(array &$dimensions) {
+  public function transformDimensions(array &$dimensions, $uri = NULL) {
     // The new image will have the exact dimensions defined for the effect.
     $dimensions['width'] = $this->configuration['width'];
     $dimensions['height'] = $this->configuration['height'];
diff --git a/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php b/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php
index 9964886..f9f157a 100644
--- a/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php
+++ b/core/modules/image/src/Plugin/ImageEffect/RotateImageEffect.php
@@ -42,7 +42,7 @@ public function applyEffect(ImageInterface $image) {
   /**
    * {@inheritdoc}
    */
-  public function transformDimensions(array &$dimensions) {
+  public function transformDimensions(array &$dimensions, $uri = NULL) {
     // If the rotate is not random and the angle is a multiple of 90 degrees,
     // then the new dimensions can be determined.
     if (!$this->configuration['random'] && ((int) ($this->configuration['degrees']) == $this->configuration['degrees']) && ($this->configuration['degrees'] % 90 == 0)) {
diff --git a/core/modules/image/src/Plugin/ImageEffect/ScaleImageEffect.php b/core/modules/image/src/Plugin/ImageEffect/ScaleImageEffect.php
index 0b9bece..6e230f1 100644
--- a/core/modules/image/src/Plugin/ImageEffect/ScaleImageEffect.php
+++ b/core/modules/image/src/Plugin/ImageEffect/ScaleImageEffect.php
@@ -36,7 +36,7 @@ public function applyEffect(ImageInterface $image) {
   /**
    * {@inheritdoc}
    */
-  public function transformDimensions(array &$dimensions) {
+  public function transformDimensions(array &$dimensions, $uri = NULL) {
     if ($dimensions['width'] && $dimensions['height']) {
       Image::scaleDimensions($dimensions, $this->configuration['width'], $this->configuration['height'], $this->configuration['upscale']);
     }
diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module
index 925fe3c..357fa4e 100644
--- a/core/modules/responsive_image/responsive_image.module
+++ b/core/modules/responsive_image/responsive_image.module
@@ -155,13 +155,48 @@ function template_preprocess_responsive_image(&$variables) {
     unset($variables['height']);
   }
 
-  $image = \Drupal::service('image.factory')->get($variables['uri']);
-  $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']);
+  $sources = array();
+
+  // Fallback image, output as source with media query.
+  $sources[] = array(
+    'src' => _responsive_image_image_style_url($variables['style_name'], $variables['uri']),
+    'dimensions' => responsive_image_get_image_dimensions($variables, $variables['uri']),
+  );
+  $responsive_image_mapping = ResponsiveImageMapping::load($variables['mapping_id']);
+
   // All breakpoints and multipliers.
   $breakpoints = \Drupal::service('breakpoint.manager')->getBreakpointsByGroup($responsive_image_style->getBreakpointGroup());
   foreach ($responsive_image_style->getKeyedImageStyleMappings() as $breakpoint_id => $multipliers) {
     if (isset($breakpoints[$breakpoint_id])) {
-      $variables['sources'][] = responsive_image_build_source_attributes($image, $variables, $breakpoints[$breakpoint_id], $multipliers);
+      $breakpoint = $breakpoints[$breakpoint_id];
+      $new_sources = array();
+      foreach ($multipliers as $multiplier => $image_style) {
+        $new_source = $variables;
+        $new_source['style_name'] = $image_style;
+        $new_source['#multiplier'] = $multiplier;
+        $new_sources[] = $new_source;
+      }
+
+      // Only one image, use src.
+      if (count($new_sources) == 1) {
+        $sources[] = array(
+          'src' => _responsive_image_image_style_url($new_sources[0]['style_name'], $new_sources[0]['uri']),
+          'dimensions' => responsive_image_get_image_dimensions($new_sources[0], $new_sources[0]['uri']),
+          'media' => $breakpoint->getMediaQuery(),
+        );
+      }
+      else {
+        // Multiple images, use srcset.
+        $srcset = array();
+        foreach ($new_sources as $new_source) {
+          $srcset[] = _responsive_image_image_style_url($new_source['style_name'], $new_source['uri']) . ' ' . $new_source['#multiplier'];
+        }
+        $sources[] = array(
+          'srcset' => implode(', ', $srcset),
+          'dimensions' => responsive_image_get_image_dimensions($new_sources[0], $new_sources[0]['uri']),
+          'media' => $breakpoint->getMediaQuery(),
+        );
+      }
     }
   }
   // Prepare the fallback image. Use srcset in the fallback image to avoid
