相关阅读:
萌新快速成长之路
如何编写软件设计文档
JAVA编程思想(一)通过依赖注入增加扩展性
JAVA编程思想(二)如何面向接口编程
JAVA编程思想(三)去掉别扭的if,自注册策略模式优雅满足开闭原则
JAVA编程思想(四)Builder模式经典范式以及和工厂模式如何选?
Java编程思想(七)使用组合和继承的场景
JAVA基础(一)简单、透彻理解内部类和静态内部类
JAVA基础(二)内存优化-使用Java引用做缓存
JAVA基础(三)ClassLoader实现热加载
JAVA基础(四)枚举(enum)和常量定义,工厂类使用对比
JAVA基础(五)函数式接口-复用,解耦之利刃
Seata源码(一)初始化
Seata源码(二)事务基础对象
Seata源码(三)事务处理类结构和流程
Seata源码(四)全局锁GlobalLock
Seata源码(五)Seata数据库操作
Seata源码(六)Seata的undo日志操作
Seata源码(七)Seata事务故障处理
Seata源码(八)Seata事务生命周期hook
Seata源码(九)TCC核心类和处理逻辑
Seata源码(十)RM接收到请求后的调用过程
Seata源码(十一)TC接收到请求后的处理过程\
一、Angular性能优化点
Angular优化只是前端优化的一个子集,本篇仅涉及Angular相关的优化。
1. 合理划分特性模块
在一些项目中所有组件都放到一个模块中,特别是很多组件的初始化逻辑放在组件构造器或者ngOnInit方法中,这样会导致首次加载很慢,而将组件按照相关性划分到不同的特性模块,并使用懒加载方式加载,就能减少首次初始化的时间,提高性能。
2. 选择合适的生命周期钩子
有的时候,我们习惯性的将一些公共方法放到构造器或者ngOnInit方法中,例如给API中心上报组件调用信息,这样也会导致看上去页面首开性能很差,因此,对于不影响界面展现的方法应放到ngAfterViewInit方法中。
3. 按需调用组件初始化方法
当组件包含子组件时,我们会在ngOnInit中调用组件初始化的方法,哪怕这个组件在初次展现时并不可见,例如多个tab页,每个tab页是一个独立的子功能。如果子组件影响了性能,应在子组件可见时再调用初始化方法,而不是放在ngOnInit中。
4. 合并多个服务请求
chrom浏览器对一个域名一次并发的请求数最大是6个,如果超过6个就会排队等待,所以对于超过6个请求的可以考虑合并,合并包括图片合并、js,css文件合并,后端服务合并。一般来说现有的前端框架在打包时已经将js,css文件合并,图片合并和后端服务合并需要自行实现。
二、Angular集成GraphQL
前面提到提高性能的其中一个方法是合并多个服务请求,对此可以要求后端GG重新封装一个聚合服务,通常这也没什么问题,而查询需求可能合并千变万化,当服务很多时总是要求后端GG封装新的聚合服务就不是那么顺利了,为了减少前后端的耦合,可以集成GraphQL来解决这个问题,GraphQL可以在一次查询中同时请求多个后端服务,将多个服务的查询结果聚合后返回。
三、集成样例
这个例子的后端服务参考:Web应用全栈之旅-Spring篇(四)集成GraphQL。
1. 安装apollo-angular
ng add apollo-angular
2. 安装graphql apollo-client相关的的模块
npm install apollo-client apollo-cache-inmemory apollo-angular-link-http apollo-angular graphql-tag graphql --save
3. 修改连接地址
修改graphql.module.ts中的 uri。
const uri = 'http://localhost:7000/graphql'; // <-- add the URL of the GraphQL server here
export function createApollo(httpLink: HttpLink) {
return {
link: httpLink.create({uri}),
cache: new InMemoryCache(),
};
}
4. 查询例子(不带变量)
代码如下:
query() {
let query = gql`
query {
findBook(id:1) {
name
publisher
author{
id
}
}
findDogByName(name:"xiaofei") {
name
age
gender
}
}
`;
this.apollo
.watchQuery({
query: query,
})
.valueChanges.subscribe((result:any)=>{
console.log(result)
});
}
可以看到在一个请求中调用了后端的两个服务。
请求包如下:
{
"operationName": null,
"variables": {},
"query": "{\n findBook(id: 1) {\n name\n publisher\n author {\n id\n __typename\n }\n __typename\n }\n findDogByName(name: \"xiaofei\") {\n name\n age\n gender\n __typename\n }\n}\n"
}
可以看到operationName为null,variables中没有变量传入。
应答包如下:
{
"data": {
"findBook": {
"name": "Java 8实战",
"publisher": "电子工业出版社",
"author": {
"id": 1,
"__typename": "Author"
},
"__typename": "Book"
},
"findDogByName": {
"name": "xiaofei",
"age": 3,
"gender": "male",
"__typename": "Dog"
}
}
}
5. 查询例子(带变量)
代码如下:
query1() {
let query = gql`
query myoperation($id:Int, $name:String!) {
findBook(id:$id) {
name
publisher
author{
id
}
}
findDogByName(name:$name) {
name
age
gender
}
}
`;
this.apollo
.watchQuery({
query: query,
variables: {
id: 1,
name: "xiaofei",
},
})
.valueChanges.subscribe((result:any)=>{
console.log(result)
});
其中myoperation是operationName,可自行定义,目的是为了传入变量。
请求包:
{
"operationName": "myoperation",
"variables": {
"id": 1,
"name": "xiaofei"
},
"query": "query myoperation($id: Int, $name: String!) {\n findBook(id: $id) {\n name\n publisher\n author {\n id\n __typename\n }\n __typename\n }\n findDogByName(name: $name) {\n name\n age\n gender\n __typename\n }\n}\n"
}
可以看到operationName和variables都有值了。
end.
apollographql官网地址: www.apollographql.com/docs/angula…