What is the difference between getValue() and referencedEntities() to fetch paragraphs? What is the difference between using getValue() and referencedEntities() in order to get the paragraph on a node?

See example below. Both examples are used in a node template such as node--page--full.html.twig and mymodule_preprocess_node() hook. 

Using getValue()

$paragraph = $node-&gt;field_paragraph-&gt;getValue();
foreach ( $paragraph as $pr ) {
  // Get the entity using Paragraph::load(entity_id).
  $pr_item = \Drupal\paragraphs\Entity\Paragraph::load($pr['target_id']);

  // Now use $pr_item to get any field.
  $pr_item_img = $pr_item-&gt;field_image;
}


Using referencedEntities()

$pr_field = $node-&gt;field_paragraph-&gt;referencedEntities();
foreach($pr_field as $pr) {
  $item_image = $pr-&gt;get('field_image');
}


I am mainly concerned with the following:


What is more performant?
What is the best practice since both work?
Is either method considered a magic method? I ask because you can use $node-&gt;field_paragraph as opposed to $node-&gt;get('field_paragraph')
Performance

EntityReferenceFieldItemList::referencedEntities performs better because it uses loadMultiple() instead of loading the entities separately.

Best practice

You use static code to load the entity which should be avoided when possible. You could make proper OOP code out of it, but it is also best practice to not reinvent the wheel.

Edit:
You've added the info this is in node preprocess. Then best practice would be to render the paragraph field in the node template {{ content.field_paragraph }}. Configure the field in UI, for example add a custom view mode. Theme the output in field and paragraph templates for this specific field or view mode.

Magic method

No, this doesn't involve a magic method,  the method is called directly. A magic method is involved in getting entity fields as if they were object properties, like the example you've mentioned $node-&gt;field_paragraph.

Translation

You need to translate the entities for both methods before you can output translated field values directly:

$paragraph = \Drupal::service('entity.repository')
  -&gt;getTranslationFromContext($paragraph, $langcode);


By the way core translates the entities later when building the rendered output using the entity reference field formatter. This works for core because it usually doesn't output field values directly, so this could be considered as bad practice as well, see for example this question from today How to display Paragraph bundles fields links inside a page.html.twig file that are within a paragraph bundle in Twig?.

Revisions

Paragraphs are stored in an EntityReferenceRevisions field. Your example code ignores the revision data and so you might load the wrong version. One more reason to use the methods provided by the field, referencedEntities() or $item-&gt;entity in case you need to load a single entity.