嗡汤圆的Angular2 单页应用一些优化总结

前言

初学Angular2后很容易被它简洁清晰的思路,方便的开发环境和开发套件所吸引。但是真正考虑生产开发的时候,总是有些不那么美好的东西。所以,在这里总结一下一些最初级、最简单粗暴的优化步骤。

启动时间优化

开启生产压缩与预编译

由于Angular2正处于发展,刚刚稳定下来的阶段,网上的一些教程,甚至包括官方的教程都有点跟不上脚步(比如官方的AOT预编译教程,貌似还有些错误)。好在开发套件angular-cli已经帮我们做好了。

ng build --prod --aot

即可。
--prod 代表生产环境编译,带有代码混淆与压缩功能。我这实际测试时候,默认编译包大小为3.5兆,生产包1.7兆。

--aot 代表预编译,会显著缩短客户端浏览器的启动到展示出真正页面的时间。

开启服务端GZIP压缩

Angular2最大的包就是vendor和main两个js文件,动辄上兆的大小在移动端仍然是不可接受的范围。但好在是文本,压缩比例一般较大,开启服务端或者反向代理的GZIP压缩功能后,可以将js文件的下载体积进一步减小。我的生产实践中原1.7兆的包进过GZIP默认配置的压缩后变为350K左右,已经完全可以接受了。

对静态文件允许客户端缓存

这个一般在SpringSecurity 或者Shiro保护的web项目中有一些坑,这些安全框架可能会在web头中加入no-cache标记,这样,每次打开页面均要从服务器再下载一遍js文件,浪费时间和流量。因此要记得在设置中关闭这些静态资源文件的no-cache标记。这样第二次打开页面,最多就是304 not modified,甚至是200(from cache)。页面显示时间可以压缩至Angular2启动的300ms。

Angular2内的优化

充分利用HTML5的Storage特性

Angular不像普通web页面,不管你是打开连接还是后退,Angular2页面均会重新走一遍页面生命周期的各个流程,重新绘制页面。
所以,若页面数据是从接口获取后,在渲染出来的话,在页面后退时候,也要经历一次空白页面到填充的过程,给用户的体验不太好。
因此优化步骤入下:

STEP1:缓存数据接口数据

这时,可以先利用Storage缓存的数据绘制页面,然后后台异步调用数据接口获取最新数据。

// 1. get from cache
pageItem = JSON.parse(localStorage.getItem('key'));
// 2. get from api
api.getData().then(res => {
    pageItem = res;
    // 3. save to cache
    localStorage.setItem('key',key,JSON.stringify(res));
})

此时有个缺点,从api获取数据后还会触发一次页面重绘,其实如果页面数据没有变化完全可以不必重绘页面。
改进如下

// 1. get from cache
pageItem = JSON.parse(localStorage.getItem('key'));
// 2. get from api
api.getData().then(res => {
    if(refreshCache(res,'key')) {
        pageItem = res;
    } else {
        // don't redraw page
    }
})

refreshCache(res:any, key:string):boolean {
    if(JSON.stirngify(res)===localStorage.getItem(key) {
        return false;
    } else {
        // update cache and return true;
        localStorage.setItem(key,JSON.stringify(res));
        return true;
    }
}

这样,仅当最新数据与缓存不符时才会触发页面重绘,同时更新本地缓存。

利用动画

Angular2的页面跳转时虽然不像普通web需要重新载入,单总归会有几百毫秒的延时,对于体验要求苛刻的用户可能会觉得这个应用有点“卡”。因此,在页面跳转时加入转场动画可以减轻这一感觉,给人感觉这个web应用使用流畅。

Angular2添加转场动画很简单,我们以模拟手机APP常用的转场为例(页面从右往左划入)。
首先定义一个动画参数,可以单独存在一个ts文件中。

// transition-right-2-left.ts
import {trigger, state, animate, style, transition, AnimationEntryMetadata} from '@angular/core';

export const slide2left: AnimationEntryMetadata = 
    trigger('routerTransition',[
        state('void',style({position:'absolute',width:'100%'})),
        state('*',style({position:'absolute',width:'100%'})),
        transition(':enter',[
            style({transform:'translateX(100%)'}),
            animate('200ms ease-out',style({transform:'translateX(0%)'})),
        ]),
        transition(':leave',[
            style({transform:'translateX(0%)'}),
            animate('200ms ease-out',style({transform:'translateX(-100%)'})),
        ])
    ]) 

在需要转场的页面component.ts文件中加入如下代码

// somepage.component.ts
import {slide2left} from '../animations/transition-right-2-left.ts';

@Component({
    selector:'xxx',
    templateUrl:'xxx.html',
    styleUrls:[],
    // 添加一下参数
    host:{'[@routerTransition]'},//trigger name
    animations:[slide2left]// metadata name
})

猜你喜欢

转载自blog.csdn.net/tzdwsy/article/details/64438886
今日推荐