Hope this is helpful to someone trying to achieve the same result as I was in the future.
What I ended up doing is creating a service to inject a preload link element in the head of the document. And then called the services in components where I wanted to add the preloaded inside ngOnInit()
To be able to do this tho I have to pass the components renderer and head to the service as well as the asset for which I created an interface.
The service:
//services/preloader-service/preload.service.ts
import { Injectable, Inject, Renderer2, PLATFORM_ID } from '@angular/core';
import { isPlatformServer } from '@angular/common';
import { PreloadableAsset } from './preloadable-asset.type';
@Injectable({
providedIn: 'root',
})
export class PreloadService {
constructor(@Inject(PLATFORM_ID) private platformId: object) {}
makePreloadable(link: string, as: string, media?: string) {
if (as === 'image') {
const type = 'image/' + link.split('.').pop();
const asset: PreloadableAsset = {
as,
href: link,
type,
media,
};
return asset;
}
}
preloadAsset(renderer: Renderer2, head: HTMLHeadElement, asset: PreloadableAsset) {
if (isPlatformServer(this.platformId) && asset.href) {
const preloader = renderer.createElement('link');
renderer.setAttribute(preloader, 'rel', 'preload');
renderer.setAttribute(preloader, 'href', asset.href);
if (asset.as === 'image') {
renderer.setAttribute(preloader, 'as', asset.as);
if (asset.type) {
renderer.setAttribute(preloader, 'type', asset.type);
}
if (asset.media) {
renderer.setAttribute(preloader, 'media', asset.media);
}
}
renderer.appendChild(head, preloader);
}
}
}
The interface:
export interface PreloadableAsset {
as?: string;
type?: string;
href: string;
media?: string;
}