`PreloadAsync` Extremely Slow Despite Using Chunking (Feedback Needed)

Hey everyone,

I’ve been working on a loading screen for my Roblox game and ran into a significant performance issue related to ContentProvider:PreloadAsync. I’m hoping to get some insight from others who may have dealt with similar issues or know how to optimize it better.

What I’m trying to do

I’ve built a stylized loading screen that preloads all game assets using PreloadAsync. To make the loading process feel more realistic and prevent blocking behavior, I implemented a chunking system. This divides all the game’s descendants into smaller batches, preloads them with some randomized delay, and updates the UI progress bar along the way.

Here’s a simplified snippet of the chunked loading logic:

local assets = game:GetDescendants()
local totalAssets = #assets

local chunkCount = nil
local chunkIndex = 0
local chunkCooldown = 0
local chunk = {}

for i, v in assets do
	if finishedLoading then break end

	if chunkCount == nil then
		chunkIndex = 0
		chunkCooldown = 0

		local size = math.random(1, 5)

		if size == 1 then
			chunkCount = math.random(25, 75)
			chunkCooldown = math.random(1.5, 3.5)
		elseif size == 2 then
			chunkCount = math.random(125, 200)
			chunkCooldown = math.random(2.5, 5)
		else
			chunkCount = math.random(5, 20)
			chunkCooldown = math.random(0.5, 1.5)
		end

		if i + chunkCount > totalAssets then
			chunkCount = totalAssets - i
		end		
	end

	chunkIndex += 1
	table.insert(chunk, v)

	if chunkIndex == chunkCount then
		chunkCount = nil
		print("Loading chunk...")
		contentProvider:PreloadAsync(chunk)
		print("Finished loading chunk.")
		table.clear(chunk)

		local progress = i / totalAssets
		tweenService:Create(progressBar, TweenInfo.new(0.2), {Size = UDim2.new(progress, 0, 1, 0)}):Play()

		if i ~= totalAssets - 1 then
			task.wait(chunkCooldown)
		end
	end
end

The Issue

Despite chunking, the PreloadAsync calls are still very slow, and only in live servers, not in studio. The print statements make it clear that each chunk is taking a disproportionately long time to load—even with small batches. This is drastically slowing down the loading process and impacting the player experience.

Questions

  • Is this normal behavior for PreloadAsync with a large number of assets?
  • Are there undocumented limitations or best practices I should know about?
  • Could there be specific asset types (e.g., audio, large meshes, etc.) that slow it down significantly?
  • Should I be more selective about what gets preloaded?

Any advice or feedback would be greatly appreciated!

Passing all descendants makes roblox walk huge hierarchies every call, and your extra task.wait(1.5-5) pauses add seconds on top

Preloading everything gives no benefit; the API is meant to prioritise a small set of assets, not force-load the whole map

Assets you should preload:

Decals
Textures
Image Labels
Image Buttons
Mesh Parts
Special Meshs
Union Operations
Sounds
Animations
Particle Emitters
Trails

Ensure you are running it from a local script in ReplicatedFirst as well.

To answer your questions directly:

Yes this is normal behavior, network time + repeated hierarchy walks

Theres no undocumented limits to my knowledge, just avoid huge tables, duplicates, and server-side calls

Things that slow it down heavily: large audio, high-res textures, and complex meshes

100%, only preload what’s necessary

I’ll try this and get back to you!

1 Like

Didn’t seem to work. my scripter added print statements and the images are taking 15 MINUTES to load, which is causing it @xnSly

Run PreloadAsync in a LocalScript under ReplicatedFirst serverside calls are much slower,
only preload the specific asset IDs/Instances you actually need
(decals, textures, sounds, meshes) avoid game:GetDescendants()
and remove the random task.wait() delays, they add several seconds per chunk :123:

It’s a LocalScript in Replicated First, but i’ll forward this to my scripter