Blog>
Snippets

Pre-Rendering Angular Animations for Performance

Improve performance by pre-rendering animations off-screen before attaching them to the view, using Angular's renderer2 to manage DOM manipulations.
import { Component, Renderer2, ElementRef, OnInit } from '@angular/core';

@Component({
  selector: 'app-pre-render-animation',
  template: '<div #animationContainer></div>',
})
export class PreRenderAnimationComponent implements OnInit {
  private offScreenContainer: HTMLElement;

  constructor(private renderer: Renderer2, private el: ElementRef) {}

  ngOnInit() {
    this.createOffScreenContainer();
  }

  createOffScreenContainer() {
    this.offScreenContainer = this.renderer.createElement('div');
    this.renderer.setStyle(this.offScreenContainer, 'width', '0');
    this.renderer.setStyle(this.offScreenContainer, 'height', '0');
    this.renderer.setStyle(this.offScreenContainer, 'overflow', 'hidden');
    this.renderer.appendChild(document.body, this.offScreenContainer);
  }
}
The component creates an off-screen container using Renderer2's createElement method. Styles are set to keep it hidden from view, ensuring that content can be rendered off-screen without affecting the layout or visibility of the page.
private prepareAnimation() {
  // Assume we have an animationFactory that generates a predefined animation
  const animation = this.animationFactory.create(this.offScreenContainer);

  // Pre-render the animation off-screen
  animation.play();

  // After the animation is pre-rendered, it can be paused until it needs to be shown
  animation.pause();
}
A method that prepares the animation by creating it in the off-screen container and then pausing it. By pre-rendering and pausing, the component makes the animation ready to run with minimal start-up delay when required.
public showAnimation() {
  // Attach the off-screen container to the actual view container
  const viewContainer = this.el.nativeElement.querySelector('#animationContainer');
  this.renderer.appendChild(viewContainer, this.offScreenContainer.firstChild);

  // Play the animation now that it is in view
  const animation = this.animationFactory.get(this.offScreenContainer.firstChild);
  animation.play();
}
This method transfers the now pre-rendered animation from the off-screen container to the on-screen container and then plays the animation. The transition is seamless due to the pre-rendering work done earlier.
ngOnDestroy() {
  // Clean up the off-screen container to avoid memory leaks
  this.renderer.removeChild(document.body, this.offScreenContainer);
}
Cleans up the off-screen container when the component is destroyed, which is a best practice to avoid potential memory leaks in the application.