前端性能优化
程序员文章站
2022-05-14 13:08:54
...
在前端开发过程中,发现APP会有很多方面的性能需要注意,例如:
- APP卡顿
- 网络慢
- APP加载慢
以下是一些具体的实践经验。
性能优化分为两个方面:一个是加快静态资源的加载,一个是提高页面渲染的速度。
页面渲染性能优化
- 减少DOM层级,在写DOM的时候没必要的层级可以不要加。
- 不需要阴影的地方,不要加阴影。
- 使用chrome的performance分析,分析原因。
静态资源加载优化
资源压缩
页面的资源包括js、css、images等等,这些文件尽可能压缩
使用 tree-shaking、scope hoisting、code-splitting
- tree-shaking
移除无用代码,只加载实际使用了的代码。 - scope hoisting
作用域提升,允许工具检测哪些import
可以被提升或者可以转换成一个内联函数。 - Code-splitting
将代码分为按需加载的“块”。
缓存
HTTP缓存:如果有HTTP缓存,并且缓存没有失效,浏览器会直接使用缓存;反之,则向服务器请求数据。
强制缓存:
- Expires,这个字段表示缓存到期时间。如果在响应消息头中设置了这个字段,就告知了浏览器在没到这个时间之前不需要再次请求。
- Cache-Control,这个字段表示缓存的最大有效时间,在这个时间内客户端不需要向服务器发送请求。
对比缓存:
- Last-Modified:服务器告知客户端,资源最后一次被修改的时间。
- If-Modified-Since:再次发送请求时,请求头中带有该字段,服务器会将If-Modified-Since的值与Last-Modified字段进行对比,如果相等,则表示未修改,响应304;反之,则表示修改了,响应200状态码,返回数据。
推荐的用法:
- Etag:它存储的是文件的特殊标识(一般都是hash生成的),服务器存储着文件的Etag字段,可以在与每次客户端传送If-no-match的字段进行比较,如果相等,则表示未修改,响应304;反之,则表示已修改,响应200状态码,返回数据。
使用lazyload&preload
为了提高页面的加载速度,我们期望的是按需加载,也就是说只加载当前的页面,别的页面不会一起被加载进来,免得阻碍了当前页面的加载。这就是懒加载,也被称为延迟加载,延迟相关资源的加载。
当首页加载完毕后,预判用户行为,提前加载之后的页面,也会提高用户的体验。这就是预加载。
实践中的一些例子
APP卡顿的时候,多次点击触发事件的处理
当APP卡顿时,如果多次点击一个button,刚好这个button会打开下一页,那么就会看到打开了很多页的动画效果。为了防止这种情况,考虑了很多做法。
- debounce
加上一个Directive,监听click事件,在某个时间段内,多次点击,只触发一次操作。
import { Directive, EventEmitter, HostListener, OnInit, Output } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { debounceTime } from 'rxjs/operators';
@Directive({
selector: '[appDebounceClick]'
})
export class DebounceClickDirective implements OnInit {
@Output() debounceClick = new EventEmitter();
private clicks = new Subject();
constructor() {}
ngOnInit() {
this.clicks.pipe(debounceTime(4000)).subscribe(e => this.debounceClick.emit(e));
}
@HostListener('click', ['$event'])
clickEvent(event) {
event.preventDefault();
event.stopPropagation();
this.clicks.next(event);
}
}
component的html:
<button appDebounceClick (debounceClick)="log()">Debounced Click</button>
component的ts文件
public log() {
// do some thing
}
具体做法参考:
https://coryrylan.com/blog/creating-a-custom-debounce-click-directive-in-angular
- disable button
其实就是在button触发事件后,通过disable属性来控制接下来的事件是否生效,这个需要注意button disabled样式可能会发生变化,并且要在合适的时机来控制该button的disable。如果对于APP中全部button都做这个控制的话,可以抽一个Button component,并加上disable控制。 - disable event
目前的APP中,主要遇上的问题是多次点击button跳转页面时,会打开多个页面,又不想改变button的样式,所以在button触发的页面跳转时,加上一个flag,判断是否跳转,在跳转后的callback方法里重置该flag。
具体做法其实就是,创建一个service,里面有一个flag属性和跳转方法。跳转方法中,在页面跳转前,先判断一下该flag是否可以跳转,如果可以,进行跳转事件,并且在callback方法里面重置flag。因为这个是针对于某一个页面的跳转事件,所以这个service应该inject到每一个用到的page。
4.更好的办法,继续探索中。。。
上一篇: 网站性能优化
下一篇: 虚基类继承时虚函数的重写问题?