首頁  >  文章  >  web前端  >  優化技巧! !前端菜鳥讓介面提速60%

優化技巧! !前端菜鳥讓介面提速60%

coldplay.xixi
coldplay.xixi轉載
2020-11-11 17:28:011923瀏覽

javascript專欄介紹前端菜鳥讓介面提速60%的技巧。

優化技巧! !前端菜鳥讓介面提速60%

背景

好久沒寫文章了,沉寂了大半年

持續性萎靡不振,間歇性癲癇發作

天天來大姨爹,在迷茫、焦慮中度過每一天

不得不承認,其實自己就是個廢物

作為一名低階前端工程師

#最近處理了一個十多年的祖傳老接口

它繼承了一切至尊級複雜度邏輯

#傳說中調用一次就能讓cpu負載飆升90%的日天服務

專治各種不服與阿茲海默症

我們欣賞一下這個介面的耗時

平均呼叫時間在3s以上

導致頁面出現嚴重的轉菊花

經過各種深度剖析與專業人士答疑

最後得出結論是:放棄醫療魯迅在《狂人日記》裡曾說過:「

能打敗我的,只有女人和酒精,而不是bug

#每當身處黑暗之時

這句話總能讓我看到光

所以這次要硬起來

我決定做一個node代理層

    用下面三個方法優化:
  • #按需載入-> graphQL
  • #資料快取-> redis
  • 輪詢更新-> schedule

#程式碼位址:github

##按需載入-> graphQL

天秀老接口存在一個問題,我們每次請求1000條數據,返回的數組中,每一條數據都有上百個字段,其實我們前端只用到其中的10個字段而已。

如何從一百多個字段中,抽取任意n個字段,這就用到graphQL。

graphQL按需載入資料只需要三個步驟:
  • 定義資料池root
  • 描述資料集中資料結構schema
  • #自訂查詢資料query

定義資料池

我們針對屌絲追求女神的場景,定義一個資料池,如下:

// 数据池var root = {    girls: [{        id: 1,        name: '女神一',        iphone: 12345678910,        weixin: 'xixixixi',        height: 175,        school: '剑桥大学',        wheel: [{ name: '备胎1号', money: '24万元' }, { name: '备胎2号', money: '26万元' }]
    },
    {        id: 2,        name: '女神二',        iphone: 12345678910,        weixin: 'hahahahah',        height: 168,        school: '哈佛大学',        wheel: [{ name: '备胎3号', money: '80万元' }, { name: '备胎4号', money: '200万元' }]
    }]
}复制代码
裡面有兩個女神的所有訊息,包括女神的名字、手機、微信、身高、學校、備胎集合等資訊。

接下來我們就要對這些資料結構進行描述。

描述資料池中資料結構

const { buildSchema } = require('graphql');// 描述数据结构 schemavar schema = buildSchema(`
    type Wheel {
        name: String,
        money: String
    }
    type Info {
        id: Int
        name: String
        iphone: Int
        weixin: String
        height: Int
        school: String
        wheel: [Wheel]
    }
    type Query {
        girls: [Info]
    }
`);复制代码
上面這段程式碼就是女神資訊的schema。

首先我們用type Query定義了一個對女神資訊的查詢,裡麵包含了很多女孩girls的資訊Info,這些資訊是一堆數組,所以是[Info]

我們在type Info

中描述了一個女孩的所有資訊的維度,包括了名字(name)、手機(iphone)、微信(weixin)、身高(height)、學校(school)、備胎集合(wheel)

#定義查詢規則

#得到女神的資訊描述(schema)後,就可以自訂獲取女神的各種資訊組合了。

例如我想和女神認識,只需要拿到她的名字(name)和微訊號(weixin)。查詢規則代碼如下:

const { graphql } = require('graphql');// 定义查询内容const query = `
    { 
        girls {
            name
            weixin
        }
    }
`;// 查询数据const result = await graphql(schema, query, root)复制代码
篩選結果如下:

#又比如我想進一步和女神發展,我需要拿到她備胎信息,查詢一下她備胎們(wheel)的家產(money)分別是多少,分析一下自己能不能取得優先擇偶權。查詢規則程式碼如下:

const { graphql } = require('graphql');// 定义查询内容const query = `
    { 
        girls {
            name
            wheel {
            	money
            }
        }
    }
`;// 查询数据const result = await graphql(schema, query, root)复制代码
篩選結果如下:

我們透過女神的例子,展現瞭如何透過graphQL按需載入資料。

映射到我們業務特定場景中,天秀介面返回的每個資料都包含100個字段,我們配置schema,取得其中的10個字段,這樣就避免了剩下90個不必要字段的傳輸。

graphQL還有另一個好處就是可以靈活配置,這個接口需要10個字段,另一個接口要5個字段,第n個接口需要另外x個字段

按照傳統的做法我們要做出n個介面才能滿足,現在只需要一個介面配置不同schema就能滿足所有情況了。

感悟

在生活中,咱們舔狗真的很缺少graphQL按需加載的思維

渣男渣女,各取所需

你的真情在名媛面前不值一提

我們要學會投其所好

上就亮車鑰匙,沒有車就秀才藝

今晚我有祖傳的染色體想與您分享一下

行就行,不行就換下一個

#直奔主題,簡單粗暴

##快取-> redis

第二個最佳化手段,使用redis快取

天秀老接口内部调用了另外三个老接口,而且是串行调用,极其耗时耗资源,秀到你头皮发麻

我们用redis来缓存天秀接口的聚合数据,下次再调用天秀接口,直接从缓存中获取数据即可,避免高耗时的复杂调用,简化后代码如下:

const redis = require("redis");const { promisify } = require("util");// 链接redis服务const client = redis.createClient(6379, '127.0.0.1');// promise化redis方法,以便用async/awaitconst getAsync = promisify(client.get).bind(client);const setAsync = promisify(client.set).bind(client);async function list() {	// 先获取缓存中数据,没有缓存就去拉取天秀接口
	let result = await getAsync("缓存");    if (!result) {    	  // 拉接口
    	  const data = await 天秀接口();
          result = data;          // 设置缓存数据
          await setAsync("缓存", data)
    }   	return result;
}

list(); 

复制代码

先通过getAsync来读取redis缓存中的数据,如果有数据,直接返回,绕过接口调用,如果没有数据,就会调用天秀接口,然后setAsync更新到缓存中,以便下次调用。因为redis存储的是字符串,所以在设置缓存的时候,需要加上JSON.stringify(data),为了便于大家理解,我就不加了,会把具体细节代码放在github中。

将数据放在redis缓存里有几个好处

可以实现多接口复用、多机共享缓存

这就是传说中的云备胎

追求一个女神的成功率是1%

同时追求100个女神,那你获取到一个女神的概率就是100%

鲁迅《狂人日记》里曾说过:“舔一个是舔狗,舔一百个你就是战狼

你是想当舔狗还是当战狼?

来吧,缓存用起来,redis用起来

轮询更新 -> schedule

最后一个优化手段:轮询更新 -> schedule

女神的备胎用久了,会定时换一批备胎,让新鲜血液进来,发现新的快乐

缓存也一样,需要定时更新,保持与数据源的一致性,代码如下:

const schedule = require('node-schedule');// 每个小时更新一次缓存schedule.scheduleJob('* * 0 * * *', async () => {    const data = await 天秀接口();    // 设置redis缓存数据
    await setAsync("缓存", data)
});复制代码

天秀接口不是一个强实时性接口,数据源一周可能才会变一次

所以我们根据实际情况用轮询来设置更新缓存频率

我们用node-schedule这个库来轮询更新缓存,* * 0 * * *这个的意思就是设置每个小时的第0分钟就开始执行缓存更新逻辑,将获取到的数据更新到缓存中,这样其他接口和机器在调用缓存的时候,就能获取到最新数据,这就是共享缓存和轮询更新的好处。

早年我在当舔狗的时候,就将轮询机制发挥到淋漓尽致

每天向白名单里的女神,定时轮询发消息

无限循环云跪舔三件套:

  • “啊宝贝,最近有没有想我”
  • “啊宝贝早安安”
  • “宝贝晚安,么么哒”

虽然女神依然看不上我

但仍然时刻准备着为女神服务

结尾

经过以上三个方法优化后

接口请求耗时从3s降到了860ms

这些代码都是从业务中简化后的逻辑

真实的业务场景远比这要复杂:分段式数据存储、主从同步 读写分离、高并发同步策略等等

每一个模块都晦涩难懂

就好像每一个女神都高不可攀

屌丝战胜了所有bug,唯独战胜不了她的心

受伤了只能在深夜里独自买醉

但每当梦到女神打开我做的页面

被极致流畅的体验惊艳到

在精神高潮中享受灵魂升华

那一刻

我觉得我又行了

(完)

相关免费学习推荐:JavaScript(视频)

以上是優化技巧! !前端菜鳥讓介面提速60%的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除