美文网首页
前端性能优化

前端性能优化

作者: 前端进城打工仔 | 来源:发表于2018-12-02 16:13 被阅读0次

    在前端开发过程中,发现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会打开下一页,那么就会看到打开了很多页的动画效果。为了防止这种情况,考虑了很多做法。

    1. 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

    1. disable button
      其实就是在button触发事件后,通过disable属性来控制接下来的事件是否生效,这个需要注意button disabled样式可能会发生变化,并且要在合适的时机来控制该button的disable。如果对于APP中全部button都做这个控制的话,可以抽一个Button component,并加上disable控制。
    2. disable event
      目前的APP中,主要遇上的问题是多次点击button跳转页面时,会打开多个页面,又不想改变button的样式,所以在button触发的页面跳转时,加上一个flag,判断是否跳转,在跳转后的callback方法里重置该flag。
      具体做法其实就是,创建一个service,里面有一个flag属性和跳转方法。跳转方法中,在页面跳转前,先判断一下该flag是否可以跳转,如果可以,进行跳转事件,并且在callback方法里面重置flag。因为这个是针对于某一个页面的跳转事件,所以这个service应该inject到每一个用到的page。
      4.更好的办法,继续探索中。。。

    参考
    前端性能优化清单
    谈谈关于前端的缓存的问题
    浏览器缓存

    相关文章

      网友评论

          本文标题:前端性能优化

          本文链接:https://www.haomeiwen.com/subject/ylumyftx.html