图片往往是网页加载最慢的一个环节,使用预加载技术能大大提高用户观感。
预加载的原理很简单,img的src先设置成一个初始图片,然后js创建一个Image对象,浏览器会去主动下载这个对象的src,然后在将img的src改成这个src。Image有两个事件,一个是load,一个是error,我们接下来要利用这两个事件。
首先,我这里用的是angular指令,之所以选择指令,因为img的属性过多,使用component要一个个设置这些属性挺麻烦,先上代码:@Directive({
selector:"[preload]"
})
export class PreloadDirective implements OnInit{
ngOnInit(): void {
let ele = this.el.nativeElement;
let src = this.dhSrc;
if (src){
if (src.startsWith("http://") || src.startsWith("https://")){
src = src.substring(src.indexOf("/"));
src = `${location.protocol}${src}`;
}
}else {
src = DEFAULT_IMG;
}
let image = new Image();
image.src = src;
image.addEventListener("load",() => {
Observable.interval(3000)
.subscribe(() => {
this.renderer.setElementAttribute(ele,"src",src);
})
});
image.addEventListener("error",() => {
this.renderer.setElementAttribute(ele,"src",DEFAULT_IMG);
});
this.renderer.setElementAttribute(ele,"src",DEFAULT_IMG);
}
constructor(private el: ElementRef, private renderer: Renderer) {
}
@Input("mySrc")
dhSrc:string;
}
这里做到的不仅仅是预加载,还改变了src的protocol,我们往往有很多图来自外站,假如你的站点用了https,而外站图片用得是http,这样就可能有安全隐患。我加了一个interval是为了模拟环境看到效果,大家如果直接用我的代码请将这个删掉。
使用方式: