I am posting this question in response to one of [the answers](https://stackoverflow.com/a/34169894/2976878) on my previous question here: [Multiple CALayer masks causing performance issues](https://stackoverflow.com/questions/34167360/multiple-calayer-masks-causing-performance-issues)

So, now that I am attempting to go down the pre-rendered animation approach, I am still unable to get a smooth animation. Not only that, but when run on an actual device, the app crashes periodically due to memory issues.

You can see the animation running here: <http://cl.ly/e3Qu> (It may not look so bad from the video, but focus on the edge of animation, and it performs worse on an actual device.)

Here is my code:

```
static CGFloat const animationDuration = 1.5;
static CGFloat const calculationRate = (1.0/40.0); // 40fps max.
static CGFloat const calculationCycles = animationDuration/calculationRate;

@implementation splashView {

    CADisplayLink* l;

    CGImageRef backgroundImg;

    UIColor* color;

    NSMutableArray* animationImages;

    NSTimeInterval currentTime;
}

-(void) beginAnimating {
    static dispatch_once_t d;
    dispatch_once(&d, ^{

        CGFloat totalDistance = 0;
        CGFloat screenProgress = 0;
        CGFloat deltaScreenProgress = 0;

        totalDistance = screenHeight()+screenWidth();

        color = [[lzyColors colors] randomColor];

        backgroundImg = textBG(color, screenSize()).CGImage;

        animationImages = [NSMutableArray array];

        NSLog(@"start");

        UIGraphicsBeginImageContextWithOptions(screenSize(), YES, 0);

        CGContextRef c = UIGraphicsGetCurrentContext();

        for (int i = 0; i <= (calculationCycles+1); i++) {

            UIImage* img = lzyCGImageFromDrawing(^{

                CGFloat height = screenHeight();
                CGFloat width = screenWidth();

                CGMutablePathRef p = CGPathCreateMutable();

                CGPoint startingPoint = [self pointBForProgress:screenProgress];

                CGPathMoveToPoint(p, nil, startingPoint.x, startingPoint.y);
                lzyCGPathAddLineToPath(p, [self pointAForProgress:screenProgress]);
                if ((width < screenProgress) && (screenProgress-deltaScreenProgress) < width) {
                    lzyCGPathAddLineToPath(p, (CGPoint){width, 0});
                }
                if (deltaScreenProgress != 0) lzyCGPathAddLineToPath(p, [self pointAForProgress:screenProgress-deltaScreenProgress-1]);
                if (deltaScreenProgress != 0) lzyCGPathAddLineToPath(p, [self pointBForProgress:screenProgress-deltaScreenProgress-1]);
                if ((height < screenProgress) && (screenProgress-deltaScreenProgress) < height) {
                    lzyCGPathAddLineToPath(p, (CGPoint){0, height});
                }
                CGPathCloseSubpath(p);

                CGContextAddPath(c, p);
                CGContextClip(c);
                CGPathRelease(p);

                CGContextSetFillColorWithColor(c, color.CGColor);
                CGContextFillRect(c, self.bounds);

                CGContextDrawImage(c, self.bounds, backgroundImg);

            });

            [animationImages addObject:img];

            deltaScreenProgress = screenProgress;
            screenProgress = (i*totalDistance)/calculationCycles;
            deltaScreenProgress = screenProgress-deltaScreenProgress;
        }

        NSLog(@"stop");

        currentTime = 0;

        l = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire)];
        [l addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

    });

}

-(void) displayLinkDidFire {

    NSTimeInterval deltaTime = l.duration;
    currentTime += deltaTime;

    if (currentTime <= animationDuration) {

        CGFloat prg = (currentTime/animationDuration);
        NSInteger image = roundf(([animationImages count]-1)*prg);

        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        self.layer.contents = (__bridge id _Nullable)(((UIImage*)[animationImages objectAtIndex:image]).CGImage);
        [CATransaction commit];
    } else {

        [CATransaction begin];
        [CATransaction setDisableActions:YES];
        self.layer.contents = (__bridge id _Nullable)(((UIImage*)[animationImages lastObject]).CGImage);
        [CATransaction commit];
        [l invalidate];
        animationImages = nil;
    }

}

-(CGPoint) pointAForProgress:(CGFloat)progressVar {
    CGFloat width = screenWidth();
    return (CGPoint){(progressVar<width)?progressVar:width+1, (progressVar>width)?progressVar-width:-1};
}

-(CGPoint) pointBForProgress:(CGFloat)progressVar {
    CGFloat height = screenHeight();
    return (CGPoint){(progressVar>height)?(progressVar-height):-1, (progressVar<height)?progressVar:height+1};
}

@end

```

The `textBG()` function just does some fairly simple Core Graphics drawing to get the background image.

I can only assume I'm doing something fundamentally wrong here, but I can't think of what it is.

Any suggestions on how to improve performance and reduce memory consumption (without degrading the quality of the animation)?