Loading screen not instant

  1. What do you want to achieve?
    I want to make a loading that’s instant, whenever someone plays needs to see the loading screen.

  2. What is the issue?
    I have some videos below so you can understand what I mean, I have no loading screen for 50-150ms and it isn’t the best.

  3. What solutions have you tried so far?
    I didn’t find any solution other than making the player spawn directly with an UI (image.Visible = true) but I don’t think it’s the best answer to my issue, i’m sure there’s a better way to do so. Just want to know what possibilities I have to fix this.

Sorry for messy code but here’s my full script:

-- Services
local players = game:GetService("Players")
local replicatedFirst = game:GetService("ReplicatedFirst")
local contentProvider = game:GetService("ContentProvider")
local soundService = game:GetService("SoundService")
local tweenService = game:GetService("TweenService")

-- Disable roblox loading screen
replicatedFirst:RemoveDefaultLoadingScreen()

-- Local services
local player = players.LocalPlayer
local playerGui = player.PlayerGui

-- Gui
local blackTransiFrame = playerGui:WaitForChild("BlackTransiFrame")

-- Main frame
local loadingScreen = script:WaitForChild("LoadingScreen"):Clone()
loadingScreen.Parent = playerGui:WaitForChild("BlackTransiFrame")

-- Sub frames
local loadingText = loadingScreen:WaitForChild("loadingText")
local loadingBar = loadingScreen:WaitForChild("LoadingFrame"):WaitForChild("LoadingBar")

local fullBlackFrame = blackTransiFrame:WaitForChild("Frame")

-- SFX load
local UISFX = soundService:WaitForChild("SFX"):WaitForChild("UI")
local successLobbySFX = UISFX:WaitForChild("SuccessLobby")

-- Every main assets
local assets = game:GetChildren()

-- Load them
for index, asset in pairs(assets) do
	loadingText.Text = "Loading ".. asset.Name.."..."
	contentProvider:PreloadAsync({asset})
	
	-- Info
	local progress = index / #assets
	
	-- Tween the bar
	local tween = tweenService:Create(
		loadingBar,
		TweenInfo.new(0.25, Enum.EasingStyle.Linear),
		{ Size = UDim2.new(progress, 0, 1, 0) }
	)
	tween:Play()
	
	-- On then put the bar to visible
	loadingBar.Visible = true
end

-- Loading completed
local tweenBarColor = tweenService:Create(loadingBar, 
	TweenInfo.new(1.2, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
	{BackgroundColor3 = Color3.fromHex("#35FF46")})

-- Tween bar
tweenBarColor:Play()

-- Changing text + play SFX
loadingText.Text = "Loading completed!"
loadingBar.Size = UDim2.new(1, 0, 1, 0)
successLobbySFX:Play()

-- Waiting end of the bar + Little delay before black frame
tweenBarColor.Completed:Wait()
task.wait(0.325)

-- Tween everything for a smooth ending with tween
local tweenBlackFrameIn = tweenService:Create(fullBlackFrame, 
	TweenInfo.new(0.7, Enum.EasingStyle.Quart, Enum.EasingDirection.Out),
	{BackgroundTransparency = 0})

tweenBlackFrameIn:Play()
tweenBlackFrameIn.Completed:Wait()

-- Delete the frame
task.wait(0.1)
loadingScreen:Destroy()

task.wait(0.375)

-- Has full view 
local tweenBackgroundOut = tweenService:Create(fullBlackFrame, 
	TweenInfo.new(1.75, Enum.EasingStyle.Quart, Enum.EasingDirection.Out),
	{BackgroundTransparency = 1}
)
tweenBackgroundOut:Play()

task.wait(2)

Here’s the video:

AFAIK, you should place your local code (in a normal Script with context set to Client not a LocalScript!) and the UI in ReplicatedFirst and then parent the UI to the PlayerGui in that code.

Because if your code isn’t in ReplicatedFirst, it won’t be replicates first (woah) and so it won’t run immediately.

And if the UI isn’t in ReplicatedFirst, it won’t be available immediately either.

Did you try publishing the game and seeing what it looks like when not in studio?

So even if my LocalScript is in the ReplicatedFirst (with the UI) I still need to use a regular script for the UI to show instantly? Could you explain the logic, I’m still down to try it though

When i’m not in studio it works really well but i’m scared that for lower end devices it does exactly like in roblox studio

Make sure to place the UI into ReplicatedFirst as well.

Normal LocalScripts don’t run outside client controlled containers, tho apparently they do run in ReplicatedFirst if the code did work for you. Didn’t know that lol. If the code does run then you don’t have to change it.

You need a local script inside ReplicatedFirst.
In that script you create a simple title screen, something that can be fast and not take a while to load.
In mine, its just a Frame, with a background color, and some Text, or a low res image.

Then once you have that up displayed, you can either…
display the acutal loading screen then call this script.Parent:RemoveDefaultLoadingScreen() from your local script in Replicated First
or Do the opposite, go ahead and call script.Parent:RemoveDefaultLoadingScreen() so the default roblox screen removes faster, then display your actual high quality loading.

The reason for making the low res screen is in case either you remove roblox default loading with script.Parent:RemoveDefaultLoadingScreen() or if enough of the game has loaded that the default loading screen is removed, and your actual loading screen has not loaded in its own resources yet. Then at least your low res screen will be displayed until your better one shows up.

This also lets you have the actual loading screen code somewhere other than ReplicatedFirst, since with your low res screen, you don’t have to try to shove the main loading screen onto the client before everything else.