Search Docs
Loading...
Skip to content

Improve Performance

Optimize CE.SDK integration for faster load times, efficient memory usage, and smooth runtime performance.

CE.SDK ships a fully featured creative engine. Tuning how you load assets, manage memory, and configure exports keeps editing responsive on lower-end devices and keeps exports reliable on the entire fleet.

This guide covers source sets for large assets, memory monitoring with the editor APIs, export size and quality tuning, and the engine initialization pattern.

7 mins
estimated time
GitHub

Managing Large Assets#

High-resolution images and videos consume significant memory. Use source sets to give the engine multiple resolution variants so it can pick the smallest one that still looks good at the current display size.

Use Source Sets#

A source set is a list of Source entries with different resolutions for the same image or video. The engine picks the variant whose dimensions best match the current viewport and reaches for the higher-resolution entries only when needed for export.

let block = try engine.block.create(.graphic)
try engine.block.setShape(block, shape: engine.block.createShape(.rect))
let imageFill = try engine.block.createFill(.image)
try engine.block.setSourceSet(imageFill, property: "fill/image/sourceSet", sourceSet: [
.init(
uri: URL(string: "https://img.ly/static/ubq_samples/sample_1_512x341.jpg")!,
width: 512,
height: 341,
),
.init(
uri: URL(string: "https://img.ly/static/ubq_samples/sample_1_1024x683.jpg")!,
width: 1024,
height: 683,
),
.init(
uri: URL(string: "https://img.ly/static/ubq_samples/sample_1_2048x1366.jpg")!,
width: 2048,
height: 1366,
),
])
try engine.block.setFill(block, fill: imageFill)
try engine.block.appendChild(to: page, child: block)

This reduces memory pressure during editing while preserving export quality. See Source Sets for the full API including video source sets and asset-source integration.

Additional Optimization Tips#

  • Remove unused blocks from the scene when no longer needed
  • Release the Engine reference when the editing session ends so ARC can reclaim its resources
  • Use efficient image formats (WebP, HEIF, optimized JPEG) for source assets

Memory Management#

Use the editor’s memory APIs to observe how much the engine currently holds and how much headroom remains. Track these values across long sessions to detect leaks or decide when to free unused assets.

let usedMemory = try engine.editor.getUsedMemory()
let availableMemory = try? engine.editor.getAvailableMemory()
if let availableMemory {
let total = usedMemory + availableMemory
let usagePercentage = Double(usedMemory) / Double(total) * 100
print("Memory usage: \(usagePercentage)%")
}

Two notes about the Swift APIs:

  • getUsedMemory() and getAvailableMemory() both return byte counts as Int64.
  • getAvailableMemory() is unavailable on the iOS Simulator and throws there. Wrap the call in try? so the same code path works in unit tests and on real devices.

Export Optimization#

Tune export resolution and quality to balance fidelity against time and memory. The settings below apply to image exports; video exports take their own dedicated options.

Optimize Export Settings#

ExportOptions controls compression and downscaling. Lowering targetWidth / targetHeight and jpegQuality produces smaller files faster, at the cost of fidelity.

let options = ExportOptions(
jpegQuality: 0.8,
targetWidth: 1280,
targetHeight: 720,
)
let blob = try await engine.block.export(page, mimeType: .jpeg, options: options)
PropertyTypePurpose
targetWidth / targetHeightFloatOptional output dimensions in pixels. The block is rendered large enough to fill the target while keeping its aspect ratio. Leave at 0 to use the block’s intrinsic size.
jpegQualityFloatJPEG quality in the range (0, 1]. Lower values trade quality for smaller files. Defaults to 0.9.
pngCompressionLevelIntPNG compression 0–9. Higher values produce smaller files but take longer to encode. Defaults to 5.
webpQualityFloatWebP quality in the range (0, 1]. Defaults to 1.0.

Export Size Limits#

Different devices support different maximum export sizes. Call getMaxExportSize() to read the device’s upper bound in pixels and validate page dimensions before kicking off a large export.

let maxExportSize = try engine.editor.getMaxExportSize()
let designUnit = try engine.scene.getDesignUnit()
let widthMode = try engine.block.getWidthMode(page)
let heightMode = try engine.block.getHeightMode(page)
if designUnit == .px, widthMode == .absolute, heightMode == .absolute {
let pageWidth = try engine.block.getWidth(page)
let pageHeight = try engine.block.getHeight(page)
let withinLimit = Int(pageWidth.rounded(.up)) <= maxExportSize
&& Int(pageHeight.rounded(.up)) <= maxExportSize
if !withinLimit {
print("Page dimensions exceed the device export limit")
}
}

getWidth(_:) and getHeight(_:) return values in design units, so the comparison only makes sense when the scene’s design unit is .px AND the block’s width and height modes are .absolute. With .percent or .auto modes, the returned value is relative to the parent or derived from content, not a pixel count.

The returned value is a hard upper bound — exports can still fail for memory or other reasons. When the limit is unknown, the engine returns Int32.max. See Size Limits for the full pattern including maxImageSize tuning and recovery on export failure.

Engine Lifecycle and Asset Loading#

Create the Engine once per editing session with try await Engine(license:) on @MainActor, then hold a strong reference for the lifetime of that session. ARC frees the engine’s GPU resources, textures, and native buffers when the last reference goes away, so releasing the editor screen is enough to reclaim memory.

Before loading any scene, point the engine at the asset base URL and register the default asset sources:

try engine.editor.setSettingString(
"basePath",
value: "https://cdn.img.ly/packages/imgly/cesdk-engine/1.76.0/assets",
)
try await engine.addDefaultAssetSources()

setSettingString("basePath", value:) tells the engine where to fetch default assets, fonts, and shaders. addDefaultAssetSources() registers the bundled images, audio, video, typefaces, and shapes as searchable asset sources so the UI and the engine can resolve asset IDs at runtime.

For production deployments, host these assets on your own infrastructure to improve reliability and remove the dependency on an external CDN, then point basePath at the asset location you control. See Architecture for the high-level component diagram and basePath rationale.

Troubleshooting#

Memory warnings or crashes#

Monitor memory with getUsedMemory() and getAvailableMemory() and react when usage climbs. Common remediations: remove unused blocks, lower the maxImageSize setting, or release the Engine reference and recreate it for a fresh editing session.

Export hangs or fails#

Validate page dimensions against getMaxExportSize() before exporting and lower targetWidth / targetHeight for large designs. For persistent failures, reduce maxImageSize so newly loaded textures stay within memory budgets.

Slow asset loading#

Use a CDN-hosted basePath or pre-cache asset files alongside your app bundle. Source sets help here too — initial editing loads only the low-resolution entries.

API Reference#

MethodDescription
Engine(context:audioContext:license:userID:)Initialize a new engine instance
engine.editor.setSettingString("basePath", value:)Configure where engine assets are loaded from
engine.editor.getUsedMemory()Get current engine memory usage in bytes
engine.editor.getAvailableMemory()Get remaining available memory in bytes (throws on iOS Simulator)
engine.editor.getMaxExportSize()Get the maximum export edge length in pixels
engine.block.setSourceSet(_:property:sourceSet:)Provide multiple resolutions of an image or video
engine.block.export(_:mimeType:options:)Export a block with configurable size and quality

Next Steps#

  • Architecture — Understand CE.SDK structure and components
  • Export Overview — Learn about export formats and options
  • Size Limits — Configure limits on exported file dimensions and data size