Is It Better to Cache Tweens or Create New Ones Every Time?

I’m wondering what the best practice is for TweenService in this case.

Is it worth caching and reusing tweens for the same object every time it’s shown/hidden, like I’m doing below? Or is it generally better to create a new tween whenever the UI is opened?

Right now I’m creating the tweens once, storing them in a cache, and reusing them on every Show() / Hide() call. This avoids creating new tween instances repeatedly, but I’m not sure if that’s actually the recommended approach or if there are any downsides I’m overlooking.

Here’s my current implementation:

local UIAnimator = {}

local TweenService = game:GetService("TweenService")

local Camera = workspace.CurrentCamera

-- << CONFIG >> --
local DEFAULT_FOV = 70
local ZOOM_FOV = 55

local tweenInfos = {
	PopupShow = TweenInfo.new(
		0.3,
		Enum.EasingStyle.Back,
		Enum.EasingDirection.Out
	),

	PopupHide = TweenInfo.new(
		0.18,
		Enum.EasingStyle.Quad,
		Enum.EasingDirection.In
	),

	ZoomIn = TweenInfo.new(
		0.3,
		Enum.EasingStyle.Quad,
		Enum.EasingDirection.Out
	),

	ZoomOut = TweenInfo.new(
		0.18,
		Enum.EasingStyle.Quad,
		Enum.EasingDirection.In
	),
}

local cameraTweens = {
	zoomIn = TweenService:Create(
		Camera,
		tweenInfos.ZoomIn,
		{ FieldOfView = ZOOM_FOV }
	),

	zoomOut = TweenService:Create(
		Camera,
		tweenInfos.ZoomOut,
		{ FieldOfView = DEFAULT_FOV }
	)
}

local cache = {}

local function getData(guiObject)
	local data = cache[guiObject]
	if data then
		return data
	end

	local basePosition = guiObject.Position
	local hiddenPosition = basePosition + UDim2.fromScale(0, 1)

	data = {
		basePos = basePosition,
		hiddenPos = hiddenPosition,
	}

	data.TweenShow = TweenService:Create(guiObject, tweenInfos.PopupShow, {
		Position = basePosition,
	})

	data.TweenHide = TweenService:Create(guiObject, tweenInfos.PopupHide, {
		Position = hiddenPosition
	})

	data.TweenHide.Completed:Connect(function(playbackState)
		if playbackState ~= Enum.PlaybackState.Completed then
			return
		end

		guiObject.Visible = false
		guiObject.Position = data.basePos
	end)

	cache[guiObject] = data

	return data
end

function UIAnimator.Show(guiObject: GuiObject)
	if not guiObject:IsA("GuiObject") then return end

	local data = getData(guiObject)

	guiObject.Position = data.hiddenPos
	guiObject.Visible = true

	data.TweenShow:Play()
	cameraTweens.zoomIn:Play()
end

function UIAnimator.Hide(guiObject: GuiObject)
	if not guiObject:IsA("GuiObject") then return end

	local data = getData(guiObject)

	data.TweenHide:Play()
	cameraTweens.zoomOut:Play()
end

return UIAnimator

Would you cache tweens like this, or would you create them on demand instead? I’m mainly interested in what’s considered best practice in terms of performance, memory usage, and maintainability.

caching obviously would go better for optimization

but it doesn’t make much difference during actual gameplay unless you got like thousands of them working at once

2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.