我放棄 Axios,改用 Alova
https://javascript.plainenglish.io/its-2023-drop-axios-and-use-alova-instead-e688a4f51e6c
Axios 是一個基於 Promise 的 HTTP 客戶端,每週 npm 下載量超過 4000 萬。如果回到 10 年前,promise 式的請求工具是一個偉大的創新。它解決了繁瑣的請求問題。
但隨着時間的推移,Axios 在開發效率和性能上開始落後。特別是現在面對越來越複雜的需求,我們需要的是更加創新和領先的請求工具,而 promise 式的請求工具只能稱之爲傳統。
接下來,我會揭露 Axios 在某些方面的不足,並推薦一個比 Axios 更現代、更創新的請求工具,也就是上面的輕量級請求策略庫。
一、Promise 式請求工具(Axios)的弱點
1.1 與 React、Vue 等框架分離
現在前端幾乎離不開 React、Vue 等前端 UI 框架。axios 無法深度綁定這些框架的狀態,需要開發者自行維護,導致開發效率低下。
1.2 性能方面沒有
現在是 2023 年,應用已經比 10 年前的應用複雜了好幾個數量級,對請求的要求也越來越高,以保證頁面的性能要求。axios 在這方面什麼都不做,比如頻繁重複請求,同時發起多個相同的請求等。
1.3 體積臃腫
根據 bundle phobia,axios 在壓縮狀態下的體積是 11+kb,見下圖
1.4 響應數據的 Ts 類型定義混亂
在使用 axios 的時候,你可能經常會這樣寫:
const inst = axios.create({
baseURL: 'https://example.com/'
})
inst.interceptors.response.use(response => {
if (response.status === 200) {
return response.data
}
throw new Error(response.status)
})
interface Resp {
id: number
}
inst.get<Resp>('/xxx').then(result => {
data.data
})
不知道 Axios 是故意的還是忽略了。在上面發起的 GET 請求中,響應數據結果的類型一直是 axios.AxiosResponse,但是我們在響應攔截器中返回了 response.data。這導致陷入混亂的響應數據類型。
2、Alova 是如何解決以上問題的?
2.1 與 UI 框架深度集成,自動管理請求相關數據
假設我們需要發起一個基本的數據獲取請求,以 Vue 爲例,直接對比代碼。
// axios
<template>
<div v-if="loading">Loading...</div>
<div v-else-if="error">
{{ error.message }}
</div>
<div v-else>{{ data }}</div>
</template>
<script setup>
import axios from 'axios';
import { ref, onMounted } from 'vue';
const loading = ref(false);
const error = ref(null);
const data = ref(null);
const requestData = () => {
loading.value = true;
axios.get('http://xxx/index').then(result => {
data.value = result;
}).catch(e => {
error.value = e;
}).finally(() => {
loading.value = false;
});
}
onMounted(requestData);
</script>
// alova
<template>
<div v-if="loading">Loading...</div>
<div v-else-if="error">
{{ error.message }}
</div>
<div v-else>{{ data }}</div>
</template>
<script setup>
import { createAlova, useRequest } from 'alova';
const pageData = createAlova({ baseURL: 'http://xxx' }).Get('/index');
const { loading, data, error } = useRequest(pageData);
</script>
在 axios 中,你需要創建相應的請求狀態並自行維護,而 Alova 爲你接手了這項工作。
2.2 開箱即用的高性能特性
傳統的 Promise 風格的請求工具主要定位是通過 Promise 簡化請求,提升性能可能是他們考慮最少的。
但是,請求策略庫 Alova 強調了這一點。在 Alova 中,默認情況下啓用內存。緩存和請求共享,這兩個可以極大的提升請求性能,提升用戶體驗,減輕服務器壓力,我們一一來看。
內存緩存
內存模式是在響應請求後,將響應數據保存在本地內存中。下次再發起同樣的請求時,將使用緩存的數據,而不是再次發送請求。
想象一下,當你在實現一個列表頁面時,點擊列表項就可以進入詳情頁面查看數據。你會認爲用戶可能會經常點擊查看列表中的詳細信息。在詳情數據沒有變化的情況下,每次進入詳情頁請求一次,每次都需要用戶等待加載,太浪費了。在 Alova,你可以默認享受這樣的待遇。
要求分享
您可能遇到過這種情況。當一個請求發送但沒有得到響應時,再次發起同一個請求,造成請求浪費,或者重複提交的問題,比如下面三種場景:
-
當一個組件被創建時,它會獲得初始化數據。當一個頁面同時渲染多個組件時,會同時發送多個相同的請求。
-
提交按鈕未禁用且用戶多次單擊提交按鈕。
-
預加載完成前進入預加載頁面時,會多次發起同一個請求。
共享請求就是用來解決這些問題的。它是通過多路複用請求來實現的。由於這種情況不能直觀展示,就不展示了。有興趣的小夥伴可以自行體驗。
重量輕
壓縮狀態下的 Alova 只有 4kb+,只有 Axios 的 30%+,看下面截圖
2.3 更直觀的響應數據 TS 類型
在 axios 中,要定義響應數據的類型是令人困惑的。如果你是 Typescript 的重度用戶,alova 可以爲你提供完整的字體體驗。當你在請求處定義響應數據的類型時,你可以在多個地方享受它,它會讓你感覺很清晰,我們來看看。
interface Resp {
id: number
}
const pageData = createAlova({ baseURL: 'http://xxx' }).Get<Resp>('/index');
const {
data,
loading, error, onSuccess, send
} = useRequest(pageData);
onSuccess(event => {
console.log(event.data);
});
const handleClick = async () => {
const data = await send();
}
至此,相對於傳統的 Promise 風格的請求庫,你可能對 alova 的強大有了初步的瞭解。
3. Alova 的其他特點
3.1 類似 axios 的 API 設計,更易上手熟悉
Alova 的請求信息結構與 Axios 幾乎相同。讓我們比較一下他們的 GET 和 POST 請求。
// axios
axios.get('/index', {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
params: {
userId: 1
}
});
// alova
const todoListGetter = alovaInstance.Get('/index', {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
params: {
userId: 1
}
});
// axios
axios.post('/login', {
username: 'xxx',
password: 'ppp'
}, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
params: {
userId: 1
}
});
// alova
const loginPoster = alovaInstance.Post('/login', {
username: 'xxx',
password: 'ppp'
}, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
params: {
userId: 1
}
});
3.2 高性能尋呼請求策略
自動維護分頁相關數據和狀態,提供通用的分頁數據操作能力。據官方介紹,可提升列表頁流暢度 300%,編碼難度降低 50%。
下面是官方提供的例子,感興趣的同學可以去看看。
3.3 無感數據交互的請求策略
據我瞭解,它使用以下技術:
-
持久化請求隊列,保證請求的安全性和序列化
-
請求重試策略機制,保證請求的順利完成
-
虛擬響應數據(一個創新概念)用作無響應數據的佔位符,以便在響應後可以將其定位並替換爲實際數據。
3.4 數據預取
數據是通過拉取數據進行預加載,緩存在本地。這部分數據用到的時候,可以打緩存,直接顯示數據。這種方式也大大提高了用戶體驗。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/jV74vzhpRMfwX6y7hp5Vqg