Is there a difference between bytes and virtual bytes (vbytes)? In an Optech newsletter, size is referred to using vbytes. Is there a difference between vbytes and bytes? If so, what is the difference?
Yes, they are referring to two different metrics: size and virtual size (vsize).

The size in [bytes] of a transaction refers to the raw byte length of its serialized format. It is used to measure the data footprint of transactions when relayed on the network or stored on disk.

The vsize in [vbytes] refers to a transaction's weighted size under segwit's rules. It is used to compare how much blockweight needs to be allocated to confirm a transaction.


Block weight limit
Bitcoin blocks are limited in their transaction capacity. Before Segregated Witness (segwit) was activated, blocks were limited to a blocksize of 1,000,000 bytes. Under that paradigm, the size of a transaction corresponded to the byte count of its serialized format.
The activation of the segwit softfork replaced the blocksize limit with a blockweight limit of 4,000,000 [weight units (wu)]. The new protocol rule defines the weight of a transaction as the sum of the witness bytes counted at a factor of one and non-witness bytes counted at a factor of four.
weight [wu] = 4 [wu/B] × non-witness length [B] + 1 [wu/B] × witness length [B]

Since non-segwit transactions don't have any witness data, this results in equivalent rules for non-segwit blocks before and after the rule change:
1 B / 1,000,000 B = 4 wu / 4,000,000 wu

One byte is the same portion of the previous blocksize limit as four weight units of the new blockweight limit. Transactions without witnesses, non-segwit transactions, take exactly the same portion of the blockweight as they took of the blocksize prior to segwit activation. This allowed segwit to be introduced as a forward compatible soft fork.
Segwit Discount
For segwit transactions, which do include witness data, the resulting transaction weight is strictly smaller than 4 × size due to the witness bytes contributing at a lower factor. This results in a lower relative portion of the blockweight to include a segwit transactions than an equivalent non-segwit transaction. The adoption of the segwit output format results in an effective capacity increase. Segwit blocks may exceed raw byte sizes of 1,000,000 bytes, with e.g. the biggest block to date achieving a raw byte size 2,377,364 bytes.
Feerates and their units
Before segwit activated, users measured transaction sizes in [bytes] and feerates in [satoshis per byte]. Since segwit activated, the protocol measures transactions by weight in [weight units]. At the protocol level, this shifts the range of feerate values by a factor of four.
Segwit introduces the measure virtual size (vsize) in [virtual bytes (vbytes)] to ease comparison of feerates before and after segwit activation. The vsize is calculated by dividing the transaction weight by four: vsize [vB] = weight [wu] / 4.
The range of values of fee per vsize thus matches the range of the pre-segwit fee per size. To this day (Oct 2020), it remains popular to track feerates in [satoshis per vbyte].
If you are looking for an approachable example, check out this detailed comparison with concrete values:
How do virtual size, stripped size and raw size compare between legacy address formats and native segwit?