최적화 팁! ! 프런트엔드 초보자가 인터페이스 속도를 60% 향상
javascript 칼럼에서는 프런트엔드 초보자가 인터페이스 속도를 60% 향상하기 위해 사용하는 기술을 소개합니다.
Background
오랫동안 글을 쓰지 않고 반년 넘게 침묵을 지켰습니다
계속되는 불쾌감, 간헐적인 간질 발작
매일 삼촌을 방문하고, 매일 시간을 보냅니다. 혼란스럽고 불안한 하루
인정해야겠습니다 사실 저는 아깝습니다
로우레벨 프론트엔드 엔지니어로서
최근에 10년 넘게 전해 내려오는 고대 인터페이스를 다루었습니다 년
최고의 복잡도 논리를 모두 물려받았습니다
한 번의 호출로 CPU 부하가 90% 치솟을 수 있다고 합니다
다양한 불만과 알츠하이머병 치료에 특화
이 인터페이스가 얼마나 시간이 많이 걸리는지 감상해 봅시다 이다
평균 통화 시간이 3초 이상
심각한 페이지 리디렉션을 초래함
다양한 끝에 이런 심층적인 분석과 전문가와의 Q&A
최종 결론은: 진료 포기
루 Xun은 "광인의 일기"에서 다음과 같이 말했습니다. "나를 이길 수 있는 유일한 것은 벌레가 아니라 여자와 술입니다
”能打败我的,只有女人和酒精,而不是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
-
온디맨드 로딩 -> graphQL
데이터 캐싱-> redis
폴링 업데이트-> code>
코드 주소: github
요청 시 로드-> graphQL
Tianxiu의 이전 인터페이스에 문제가 있습니다. 1000개의 데이터를 요청하면 반환된 배열의 각 데이터에는 수백 개의 필드가 있습니다. 실제로 프런트 엔드에서는 그 중 10개만 사용합니다.
100개가 넘는 필드에서 n개의 필드를 추출하는 방법은 graphQL을 사용합니다.
GraphQL에서는 요청 시 데이터를 로드하는 데 세 단계만 필요합니다.
- 데이터 풀 루트 정의
- 데이터 풀의 데이터 구조 스키마 설명
- 쿼리 사용자 정의 데이터 쿼리
데이터 풀 정의
디아오시가 여신을 쫓는 장면에 대한 데이터 풀을 다음과 같이 정의합니다.const { graphql } = require('graphql');// 定义查询内容const query = `
{
girls {
name
weixin
}
}
`;// 查询数据const result = await graphql(schema, query, root)复制代码
로그인 후 복사
It 여신의 이름, 휴대폰, 위챗, 키, 학교, 스페어 타이어 수집 및 기타 정보를 포함하여 두 여신의 모든 정보가 포함되어 있습니다. 다음으로 이러한 데이터 구조에 대해 설명하겠습니다.
const { graphql } = require('graphql');// 定义查询内容const query = ` { girls { name weixin } } `;// 查询数据const result = await graphql(schema, query, root)复制代码
데이터 풀의 데이터 구조를 설명하세요const { graphql } = require('graphql');// 定义查询内容const query = `
{
girls {
name
wheel {
money
}
}
}
`;// 查询数据const result = await graphql(schema, query, root)复制代码
로그인 후 복사
const { graphql } = require('graphql');// 定义查询内容const query = ` { girls { name wheel { money } } } `;// 查询数据const result = await graphql(schema, query, root)复制代码
위 코드는 여신 정보의 스키마입니다.
먼저 type Query
를 사용하여 소녀에 대한 많은 정보가 포함된 여신 정보에 대한 쿼리를 정의합니다. Info
이 정보는 배열이므로 다음과 같습니다. [Info]
type Info
에는 이름, 휴대폰(iphone), WeChat(weixin), 키, 학교 등 소녀에 대한 모든 정보의 차원을 설명합니다. , 스페어 타이어 세트(휠)
쿼리 규칙 정의
여신의 정보 설명(스키마)을 얻은 후, 여신이 얻은 다양한 정보의 조합을 맞춤 설정할 수 있습니다.
예를 들어 여신을 알고 싶다면 이름과 웨이신만 알면 됩니다. 쿼리 규칙 코드는 다음과 같습니다.
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(); 复制代码
필터링 결과는 다음과 같습니다.
🎜🎜또 다른 예를 들어, 여신과 더욱 발전하려면 여신의 스페어 휠 정보를 가져와 부를 쿼리해야 합니다( 돈)의 예비바퀴(바퀴)가 얼마인지, 짝을 선택할 수 있는 첫 번째 권리를 얻을 수 있는지 분석해 보세요. 쿼리 규칙 코드는 다음과 같습니다. 🎜const schedule = require('node-schedule');// 每个小时更新一次缓存schedule.scheduleJob('* * 0 * * *', async () => { const data = await 天秀接口(); // 设置redis缓存数据 await setAsync("缓存", data) });复制代码
天秀老接口内部调用了另外三个老接口,而且是串行调用,极其耗时耗资源,秀到你头皮发麻
我们用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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











컴퓨터를 조립할 때 설치 과정은 간단하지만 배선에 문제가 발생하는 경우가 종종 있습니다. 컴퓨터가 켜지면 F1 오류 "CPUFanError"가 발생하며 이로 인해 CPU 쿨러가 지능적으로 속도를 조정할 수 없게 됩니다. 컴퓨터 마더보드의 CPU_FAN, SYS_FAN, CHA_FAN, CPU_OPT 인터페이스에 대한 상식을 공유해 보겠습니다. 컴퓨터 마더보드의 CPU_FAN, SYS_FAN, CHA_FAN 및 CPU_OPT 인터페이스에 대한 대중적인 과학 1. CPU_FANCPU_FAN은 CPU 라디에이터 전용 인터페이스이며 12V에서 작동합니다.

현대적이고 효율적인 프로그래밍 언어인 Go 언어에는 개발자가 유지 관리 가능한 고품질 코드를 작성하는 데 도움이 될 수 있는 풍부한 프로그래밍 패러다임과 디자인 패턴이 있습니다. 이 기사에서는 Go 언어의 일반적인 프로그래밍 패러다임과 디자인 패턴을 소개하고 구체적인 코드 예제를 제공합니다. 1. 객체지향 프로그래밍 Go 언어에서는 구조와 메소드를 사용하여 객체지향 프로그래밍을 구현할 수 있습니다. 구조를 정의하고 구조에 대한 바인딩 방법을 통해 데이터 캡슐화 및 동작 바인딩의 객체 지향 기능을 구현할 수 있습니다. 패키지메니

PHP 인터페이스 소개 및 정의 방법 PHP는 웹 개발에 널리 사용되는 오픈 소스 스크립팅 언어입니다. 유연하고 간단하며 강력합니다. PHP에서 인터페이스는 여러 클래스 간의 공통 메서드를 정의하여 다형성을 달성하고 코드를 보다 유연하고 재사용 가능하게 만드는 도구입니다. 이 기사에서는 PHP 인터페이스의 개념과 이를 정의하는 방법을 소개하고 사용법을 보여주는 특정 코드 예제를 제공합니다. 1. PHP 인터페이스 개념 인터페이스는 클래스 애플리케이션을 정의하는 객체 지향 프로그래밍에서 중요한 역할을 합니다.

오류의 원인은 Python입니다. Tornado에서 NotImplementedError()가 발생하는 이유는 추상 메서드나 인터페이스가 구현되지 않았기 때문일 수 있습니다. 이러한 메서드나 인터페이스는 상위 클래스에서 선언되지만 하위 클래스에서는 구현되지 않습니다. 서브클래스가 제대로 작동하려면 이러한 메서드나 인터페이스를 구현해야 합니다. 이 문제를 해결하는 방법은 부모 클래스에서 선언한 추상 메서드나 인터페이스를 자식 클래스에 구현하는 것입니다. 다른 클래스에서 상속하기 위해 클래스를 사용하는 경우 이 오류가 표시되면 상위 클래스에 선언된 모든 추상 메서드를 하위 클래스에 구현해야 합니다. 인터페이스를 사용하고 있는데 이 오류가 표시되면 인터페이스를 구현하는 클래스의 인터페이스에 선언된 모든 메서드를 구현해야 합니다. 어느 것이 확실하지 않은 경우

인터페이스와 추상 클래스는 분리 및 확장성을 위해 디자인 패턴에 사용됩니다. 인터페이스는 메서드 시그니처를 정의하고 추상 클래스는 부분 구현을 제공하며 하위 클래스는 구현되지 않은 메서드를 구현해야 합니다. 전략 패턴에서는 인터페이스를 사용하여 알고리즘을 정의하고 추상 클래스 또는 구상 클래스를 통해 구현을 제공하므로 알고리즘을 동적으로 전환할 수 있습니다. 관찰자 패턴에서 인터페이스는 관찰자 동작을 정의하는 데 사용되며 추상 또는 구체적인 클래스는 알림을 구독하고 게시하는 데 사용됩니다. 어댑터 패턴에서 인터페이스는 기존 클래스를 조정하는 데 사용됩니다. 추상 클래스 또는 구체적인 클래스는 호환되는 인터페이스를 구현하여 원본 코드와 상호 작용할 수 있습니다.

Huawei가 출시한 새로운 운영 체제인 Hongmeng 시스템은 업계에 큰 반향을 불러일으켰습니다. 미국의 금지 조치 이후 화웨이가 시도한 새로운 시도인 훙멍(Hongmeng) 시스템은 큰 기대와 기대를 모으고 있다. 최근에는 운이 좋게도 Hongmeng 시스템이 탑재된 Huawei 휴대폰을 구입하게 되었습니다. 일정 기간의 사용과 실제 테스트를 거쳐 Hongmeng 시스템의 일부 기능 테스트와 사용 경험을 공유하겠습니다. 먼저 Hongmeng 시스템의 인터페이스와 기능을 살펴보겠습니다. Hongmeng 시스템은 전체적으로 Huawei 고유의 디자인 스타일을 채택하여 작동이 간단하고 명확하며 원활합니다. 데스크탑에서는 다양한

Java를 사용하면 인터페이스 및 추상 클래스 내에서 내부 클래스를 정의할 수 있으므로 코드 재사용 및 모듈화에 대한 유연성이 제공됩니다. 인터페이스의 내부 클래스는 특정 기능을 구현할 수 있고, 추상 클래스의 내부 클래스는 일반 기능을 정의할 수 있으며, 서브클래스는 구체적인 구현을 제공합니다.

인터페이스: 구현이 없는 계약 인터페이스는 Java에서 일련의 메소드 서명을 정의하지만 구체적인 구현을 제공하지는 않습니다. 이는 인터페이스를 구현하는 클래스가 지정된 메서드를 구현하도록 강제하는 계약 역할을 합니다. 인터페이스의 메서드는 추상 메서드이며 메서드 본문이 없습니다. 코드 예: publicinterfaceAnimal{voideat();voidsleep();} 추상 클래스: 부분적으로 구현된 블루프린트 추상 클래스는 하위 클래스에서 상속할 수 있는 부분 구현을 제공하는 상위 클래스입니다. 인터페이스와 달리 추상 클래스에는 구체적인 구현과 추상 메서드가 포함될 수 있습니다. 추상 메소드는 abstract 키워드로 선언되며 서브클래스에 의해 재정의되어야 합니다. 코드 예: publicabstractcla
