diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
index acc17ba..2a160da 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -206,4 +206,44 @@ protected function invokeFieldMethod($method, ContentEntityInterface $entity) {
     }
   }
 
+  /**
+   * Checks whether the field values changed compared to the original entity.
+   *
+   * @todo It would probably be better to have a compare() or an equals()
+   * method at both of the TypedDataInterface and FieldItemListInterface
+   * methods.
+   *
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   Field definition of field to compare for changes.
+   * @param \Drupal\Core\Entity\ContentEntityInterface $entity
+   *   Entity to check for field changes.
+   * @param \Drupal\Core\Entity\ContentEntityInterface $original
+   *   Original entity to compare against.
+   *
+   * @return bool
+   *   True if the field value changed from the original entity.
+   */
+  protected function hasFieldValueChanged(FieldDefinitionInterface $field_definition, ContentEntityInterface $entity, ContentEntityInterface $original) {
+    $field_name = $field_definition->getName();
+    $default_langcode = $entity->getUntranslated()->language()->getId();
+    $translation_langcodes = array_keys($entity->getTranslationLanguages());
+    $langcodes = $field_definition->isTranslatable() ? $translation_langcodes : array($default_langcode);
+
+    foreach ($langcodes as $langcode) {
+      // If the original entity doesn't have this translation, we need to save.
+      if (!$original->hasTranslation($langcode)) {
+        return TRUE;
+      }
+
+      $items = $entity->getTranslation($langcode)->get($field_name);
+      $originalItems = $original->getTranslation($langcode)->get($field_name);
+      // If the field items are not equal, we need to save.
+      if (!$items->equals($originalItems)) {
+        return TRUE;
+      }
+    }
+
+    return FALSE;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index 22d2f92..30dd4a7 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -22,6 +22,7 @@
 use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\field\FieldStorageConfigInterface;
@@ -1317,11 +1318,21 @@ protected function saveToDedicatedTables(ContentEntityInterface $entity, $update
       $vid = $id;
     }
 
+    $original = !empty($entity->original) ? $entity->original: NULL;
+
     foreach ($this->entityManager->getFieldDefinitions($entity_type, $bundle) as $field_name => $field_definition) {
       $storage_definition = $field_definition->getFieldStorageDefinition();
       if (!$table_mapping->requiresDedicatedTableStorage($storage_definition)) {
         continue;
       }
+
+      // Check if the given entity is a new revision or not. In case of a new
+      // revision creation, we cannot skip any field else the new revision
+      // would be empty.
+      if ($original && $vid == $original->getRevisionId() && !$this->hasFieldValueChanged($field_definition, $entity, $original)) {
+        continue;
+      }
+
       $table_name = $table_mapping->getDedicatedDataTableName($storage_definition);
       $revision_name = $table_mapping->getDedicatedRevisionTableName($storage_definition);
 
diff --git a/core/lib/Drupal/Core/Field/FieldItemList.php b/core/lib/Drupal/Core/Field/FieldItemList.php
index 930b4e1..7e127dc 100644
--- a/core/lib/Drupal/Core/Field/FieldItemList.php
+++ b/core/lib/Drupal/Core/Field/FieldItemList.php
@@ -370,4 +370,37 @@ protected function defaultValueWidget(FormStateInterface $form_state) {
     return $form_state->get('default_value_widget');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function equals(FieldItemListInterface $field_item_to_compare) {
+    $columns = $this->getFieldDefinition()->getFieldStorageDefinition()->getColumns();
+    $this->filterEmptyItems();
+    $field_item_to_compare->filterEmptyItems();
+    $count1 = count($this);
+    $count2 = count($field_item_to_compare);
+    if ($count1 === 0 && $count2 === 0) {
+      // Both are empty we can safely assume that it did not change.
+      return TRUE;
+    }
+    if ($count1 !== $count2) {
+      // One of them is empty but not the other one so the value changed.
+      return FALSE;
+    }
+    // We have to clean things up a bit before comparing because order of
+    // properties sadly may vary.
+    $callback = function (&$value) use ($columns) {
+      if (is_array($value)) {
+        $value = array_intersect_key($value, $columns);
+        ksort($value);
+      }
+    };
+    $value1 = $this->getValue();
+    $value2 = $field_item_to_compare->getValue();
+    array_walk($value1, $callback);
+    array_walk($value2, $callback);
+
+    return $value1 === $value2;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/FieldItemListInterface.php b/core/lib/Drupal/Core/Field/FieldItemListInterface.php
index aeb6005..38ffdf3 100644
--- a/core/lib/Drupal/Core/Field/FieldItemListInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldItemListInterface.php
@@ -258,4 +258,14 @@ public function defaultValuesFormSubmit(array $element, array &$form, FormStateI
    */
   public static function processDefaultValue($default_value, FieldableEntityInterface $entity, FieldDefinitionInterface $definition);
 
+  /**
+   * Determines equality to another object implementing FieldItemListInterface.
+   *
+   * @param \Drupal\Core\Field\FieldItemListInterface $field_item_to_compare
+   *
+   * @return bool
+   *   TRUE if the field items are equal, FALSE if not.
+   */
+  public function equals(FieldItemListInterface $field_item_to_compare);
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Field/FieldItemListTest.php b/core/tests/Drupal/Tests/Core/Field/FieldItemListTest.php
new file mode 100644
index 0000000..84024b8
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Field/FieldItemListTest.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * @file Contains \Drupal\Tests\Core\Field\FieldItemListTest.
+ */
+
+namespace Drupal\Tests\Core\Field;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Field\FieldItemInterface;
+use Drupal\Core\Field\FieldItemList;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Field\FieldItemList
+ * @group Field
+ */
+class FieldItemListTest extends UnitTestCase {
+
+  /**
+   * @covers ::equals
+   *
+   * @dataProvider providerTestEquals
+   */
+  public function testEquals($expected, FieldItemInterface $a = NULL, FieldItemInterface $b = NULL) {
+
+    // Mock the field type manager and place it in the container.
+    $field_type_manager = $this->getMock('Drupal\Core\Field\FieldTypePluginManagerInterface');
+    $container = new ContainerBuilder();
+    $container->set('plugin.manager.field.field_type', $field_type_manager);
+    \Drupal::setContainer($container);
+
+    $fsd = $this->getMock('Drupal\Core\Field\FieldStorageDefinitionInterface');
+    $fsd->expects($this->any())
+      ->method('getColumns')
+      ->willReturn([0 => '0', 1 => '1']);
+    $fd = $this->getMock('Drupal\Core\Field\FieldDefinitionInterface');
+    $fd->expects($this->any())
+      ->method('getFieldStorageDefinition')
+      ->willReturn($fsd);
+
+    $field_list_a = new FieldItemList($fd);
+    $field_list_b = new FieldItemList($fd);
+
+    // Set up the mocking necessary for creating field items.
+    $at = 0;
+    if ($a instanceof FieldItemInterface) {
+      $field_type_manager->expects($this->at($at))
+        ->method('createFieldItem')
+        ->willReturn($a);
+      $at++;
+    }
+    if ($b instanceof FieldItemInterface) {
+      $field_type_manager->expects($this->at($at))
+        ->method('createFieldItem')
+        ->willReturn($b);
+    }
+
+    // Set the field item values.
+    if ($a instanceof FieldItemInterface) {
+      $field_list_a->setValue($a);
+    }
+    if ($b instanceof FieldItemInterface) {
+      $field_list_b->setValue($b);
+    }
+
+    $this->assertEquals($expected, $field_list_a->equals($field_list_b));
+  }
+
+  /**
+   * Data provider for testEquals.
+   */
+  public function providerTestEquals() {
+    // Tests field item lists with no values.
+    $datasets[] = [TRUE];
+
+    /** @var \Drupal\Core\Field\FieldItemBase  $fv_a */
+    $fv_a = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
+    $fv_a->setValue([1]);
+    // Tests field item lists where one has a value and one does not.
+    $datasets[] = [FALSE, $fv_a];
+
+    // Tests field item lists where both have the same value.
+    $datasets[] = [TRUE, $fv_a, $fv_a];
+
+    /** @var \Drupal\Core\Field\FieldItemBase  $fv */
+    $fv_b = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
+    $fv_b->setValue([2]);
+    // Tests field item lists where both have the different values.
+    $datasets[] = [FALSE, $fv_a, $fv_b];
+
+    /** @var \Drupal\Core\Field\FieldItemBase  $fv */
+    $fv_c = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
+    $fv_c->setValue(['0' => 1, '1' => 2]);
+    $fv_d = $this->getMockForAbstractClass('Drupal\Core\Field\FieldItemBase', [], '', FALSE);
+    $fv_d->setValue(['1' => 2, '0' => 1]);
+
+    // Tests field item lists where both have the differently ordered values.
+    $datasets[] = [TRUE, $fv_c, $fv_d];
+
+    return $datasets;
+  }
+}
