I tried a different way to do this that I thought I could share.
Wrap
Using wrap instead of the 2 if statements:
var margin = 20
if global_position.x > viewport_size.x + margin:
global_position.x = -margin
if global_position.x < -margin:
global_position.x = viewport_size.x + margin
becomes
var margin := 20
global_position.x = wrap(global_position.x, -margin, viewport_size.x + margin)
Texture Width
Instead of hard coding a margin, I took the texture width to scale and decided a quarter of this size was appropriate for the offset to make the transition appear smooth. This seems to ensure that there is always part of the sprite visible on screen and is never fully off the screen:
@onready var sprite2d: Sprite2D = $Sprite2D
...
var offset = (sprite2d.texture.get_width() * sprite2d.scale.x) / 4
global_position.x = wrap(global_position.x, -offset, viewport_size.x + offset)