-
Notifications
You must be signed in to change notification settings - Fork 25
Open
Description
前端如何区分弱网加载不同资源
在前端区分弱网并加载不同资源,可从以下几个方面实现:
1. 网络状态检测
- navigator.connection API:这是一个相对新的API,可获取网络连接信息。
if ('connection' in navigator) {
const connection = navigator.connection;
connection.addEventListener('change', () => {
if (connection.effectiveType === '4g') {
// 高速网络,加载高清资源
loadHighQualityResources();
} else if (connection.effectiveType === '3g') {
// 中等网络,加载中等质量资源
loadMediumQualityResources();
} else if (connection.effectiveType === '2g') {
// 弱网,加载低质量资源
loadLowQualityResources();
}
});
}- 通过心跳检测:定期向服务器发送请求,根据响应时间判断网络状况。
function checkNetwork() {
const startTime = new Date().getTime();
fetch('/ping')
.then(response => {
const endTime = new Date().getTime();
const latency = endTime - startTime;
if (latency > 1000) {
// 网络延迟较高,可能是弱网
loadLowQualityResources();
} else {
// 网络较好,加载高质量资源
loadHighQualityResources();
}
})
.catch(() => {
// 请求失败,可能是弱网或无网络
loadLowQualityResources();
});
}
setInterval(checkNetwork, 5000);2. 资源加载策略
- 图片资源:可利用
<picture>标签结合srcset属性,根据网络状况加载不同分辨率图片。
<picture>
<source media="(max-width: 600px) and (connection: slow-2g)" srcset="low-res-mobile.jpg">
<source media="(connection: slow-2g)" srcset="low-res.jpg">
<source media="(connection: 2g)" srcset="medium-res.jpg">
<img src="high-res.jpg" alt="image">
</picture>- 视频资源:使用
<video>标签的srcset属性类似方法,或借助视频播放器的自适应流技术(如HLS、MPEG - DASH),播放器会根据网络实时调整视频质量。
<video controls>
<source src="low - quality.mp4" media="(connection: slow - 2g)">
<source src="medium - quality.mp4" media="(connection: 2g)">
<source src="high - quality.mp4">
</video>- 脚本和样式表:根据网络状况,动态加载不同版本的脚本或样式表。
function loadScripts() {
if (isWeakNetwork) {
const script = document.createElement('script');
script.src = 'light - script.js';
document.head.appendChild(script);
} else {
const script = document.createElement('script');
script.src = 'full - script.js';
document.head.appendChild(script);
}
}用户网络状态是不固定的,出现误判怎么优化
当考虑到用户网络状态不固定且可能出现误判时,可从以下几个方面进行优化:
1. 多维度检测
- 结合多种检测方法:不要仅依赖单一的网络检测方式。例如,同时使用
navigator.connectionAPI 和心跳检测。navigator.connection能实时获取网络连接类型,但在某些环境可能不够准确;心跳检测虽有延迟,但可从实际网络请求响应时间补充判断。
let networkStatus = 'unknown';
if ('connection' in navigator) {
const connection = navigator.connection;
connection.addEventListener('change', () => {
networkStatus = connection.effectiveType;
if (networkStatus === '2g' || networkStatus ==='slow - 2g') {
checkHeartbeat();
}
});
}
function checkHeartbeat() {
const startTime = new Date().getTime();
fetch('/ping')
.then(response => {
const endTime = new Date().getTime();
const latency = endTime - startTime;
if (latency > 1000) {
// 确认是弱网
handleWeakNetwork();
} else {
// 网络可能较好,重新评估
handleGoodNetwork();
}
})
.catch(() => {
// 网络不稳定或弱网
handleWeakNetwork();
});
}- 参考设备信息:不同设备的网络性能也有差异。比如移动设备在信号不好时更容易出现弱网。可通过
navigator.userAgent获取设备信息辅助判断。
const userAgent = navigator.userAgent.toLowerCase();
const isMobile = /mobile|android|iphone|ipad|ipod/.test(userAgent);
if (isMobile && (networkStatus === '2g' || networkStatus ==='slow - 2g')) {
// 对移动设备的弱网处理更谨慎
handleWeakNetworkMoreCarefully();
}2. 动态调整与平滑过渡
- 实时监测与调整:持续监测网络状态变化,当网络状态发生改变时,及时调整资源加载策略。例如,从弱网变为强网时,立即停止加载低质量资源,转而加载高质量资源。
if ('connection' in navigator) {
const connection = navigator.connection;
connection.addEventListener('change', () => {
if (connection.effectiveType === '4g') {
if (isLoadingLowQuality) {
cancelLowQualityLoading();
loadHighQualityResources();
}
} else if (connection.effectiveType === '2g' || connection.effectiveType ==='slow - 2g') {
if (isLoadingHighQuality) {
cancelHighQualityLoading();
loadLowQualityResources();
}
}
});
}- 平滑过渡:在资源切换时,避免突兀。对于图片,可以使用淡入淡出效果;对于视频,在切换质量时,设置短暂的缓冲提示,告知用户正在调整。
<img id="myImage" src="low - res.jpg" alt="image">
<script>
function switchImageQuality() {
const img = document.getElementById('myImage');
img.style.opacity = '0';
setTimeout(() => {
img.src = 'high - res.jpg';
img.style.opacity = '1';
}, 300);
}
</script>3. 用户反馈机制
- 提供反馈入口:在应用中设置反馈按钮,让用户能主动告知网络状态与加载情况不符。例如,用户觉得网络很好,但却加载了低质量资源,可通过反馈入口告知开发者。
<button id="networkFeedbackButton">反馈网络问题</button>
<script>
const feedbackButton = document.getElementById('networkFeedbackButton');
feedbackButton.addEventListener('click', () => {
const userFeedback = prompt('请描述网络状态与加载资源不符的情况');
// 将反馈信息发送给服务器
fetch('/feedback', {
method: 'POST',
headers: {
'Content - Type': 'application/json'
},
body: JSON.stringify({ userFeedback })
});
});
</script>- 根据反馈优化算法:收集用户反馈数据,分析误判场景,针对性地调整网络检测和资源加载策略的算法,提高判断准确性。
4. 智能预加载与缓冲
- 智能预加载:根据用户行为和页面结构,提前预加载可能需要的资源。例如,用户在浏览文章时,提前预加载下一篇文章可能用到的图片和脚本,并且根据当前网络状态预加载合适质量的资源。
function preloadNextPageResources() {
if (networkStatus === '4g') {
preloadHighQualityResourcesForNextPage();
} else if (networkStatus === '2g' || networkStatus ==='slow - 2g') {
preloadLowQualityResourcesForNextPage();
}
}- 自适应缓冲:对于视频等资源,根据网络波动动态调整缓冲区大小。在网络不稳定时,适当增加缓冲区,防止播放卡顿。可通过视频播放器的 API 实现,如 HTML5 视频的
buffering事件。
<video id="myVideo" controls>
<source src="video.mp4" type="video/mp4">
</video>
<script>
const video = document.getElementById('myVideo');
video.addEventListener('buffering', () => {
if (networkStatus === '2g' || networkStatus ==='slow - 2g') {
// 弱网时增加缓冲区
video.buffered.max();
}
});
</script>Metadata
Metadata
Assignees
Labels
No labels