Confused if changing colors can cause lag in games

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    Im a bit confused if changing colors can cause lag in games
  2. What is the issue? Include screenshots / videos if possible!
    right now I have this code that displays things on a surface gui. such as a ray casting camera. and whenever it changes the frame, aka colors. my FPS drops to 25.
  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?
    I’ve tried using viewports however it lags ALOT.
-- code isn't mine btw 
----Made by StoneDivinity----
--(Model can be ungrouped)
local RS = game:GetService("RunService")
local GUI = script.Parent
local Frame = GUI:WaitForChild("Frame")
local CamPart = script.Parent.Parent.Parent.Parent.Cam:FindFirstChild("Engine")
local FovX = 30 --horizontal field of view
local FovY = 30 --vertical field of view
local ResX = 0
local ResY = 0
local CamOn = false
local Range = 2000 --View Range
local FPS = 12.5 --Frames per second
local lasttick = 0

local function Render()
	if CamOn == true and tick()-lasttick > 1/FPS then
		local unitX = FovX/ResX
		local unitY = FovY/ResX
		local anchorX = FovX/2
		local anchorY = FovY/2
		for y=1,ResY do
			for x=1,ResX do
				local currentpixel = Frame["X"..x.."Y"..y]
				local AngleX = math.rad(anchorX-(x-0.5)*unitX)
				local AngleY = math.rad(anchorY-(y-0.5)*unitY)
				local newray = Ray.new(CamPart.Position, (CamPart.CFrame*CFrame.Angles(0,AngleX,0)*CFrame.Angles(AngleY,0,0)).lookVector*Range) 
				local hitpart = game.Workspace:FindPartOnRay(newray, CamPart)	
				currentpixel.BackgroundColor3 = hitpart and hitpart.Color or Color3.new(0.150103, 0.503456, 0.799893)
			end
		end
		lasttick = tick()
	end
end

local function NewResolution(resX,resY)
	CamOn = false
	Frame:ClearAllChildren()
	local pixelsmade = 0
	for y=1,resY do
		for x=1,resX do
			local sizeX = 1/resX
			local sizeY = 1/resY
			local pixel = Instance.new("TextLabel")
			pixel.BackgroundColor3 = Color3.new(0.99762, 1, 0.954437)
			pixel.BorderSizePixel = 0
			pixel.Size = UDim2.new(sizeX,0,sizeY,0)
			pixel.Position = UDim2.new(sizeX*(x-1),0,sizeY*(y-1),0)
			pixel.Text = ""
			pixel.Name = "X"..x.."Y"..y
			pixel.Parent = Frame
		end	
	end
	ResX = resX
	ResY = resY
	CamOn = true
end

RS.Heartbeat:Connect(Render)

NewResolution(35,35) --Change resolution here

Heartbeat loops run every frame, is that necessary? You have a lot of operations being ran in that short time window.