ResizeObserver 作用是什么
ResizeObserver 的作用是监测元素的尺寸变化。这是一种强大的 Web API,允许开发者在元素的尺寸发生改变时(无论是因为元素内容的变化、窗口大小的调整还是其他原因导致的尺寸改变),执行一些操作或布局更新。在过去,开发者通常需要依赖定时器或者窗口的 resize 事件来间接监测元素尺寸的变化,这种方法不仅不够精确,而且效率低下。ResizeObserver 提供了一种更为直接和高效的方式来响应尺寸变化。
如何使用 ResizeObserver
使用 ResizeObserver 很简单,你只需要创建一个 ResizeObserver 实例,并为它提供一个回调函数。在回调函数中,你可以基于元素尺寸的变化来执行相应的操作。然后,使用 observe 方法来指定需要被观察尺寸变化的元素。
示例代码
下面的示例代码展示了如何使用 ResizeObserver 来监测一个元素的尺寸变化,并在尺寸变化时输出新的尺寸信息:
// 监测的目标元素
const targetElement = document.querySelector(".resizable");
// 创建 ResizeObserver 实例
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
// entry.target 是被观察的元素
// entry.contentRect 包含了元素的尺寸信息
console.log("Element size changed:", entry.target);
console.log(`New width: ${entry.contentRect.width}`);
console.log(`New height: ${entry.contentRect.height}`);
}
});
// 开始观察目标元素
resizeObserver.observe(targetElement);
应用场景
ResizeObserver 的常见应用场景包括:
-
响应式布局:当容器的尺寸改变时,动态调整内容或布局,提供更好的响应式设计。
-
图表和可视化:在图表或数据可视化的容器大小改变时,重新绘制图表来适应新的尺寸。
-
动态元素(如弹出窗口和下拉菜单) :监测并根据内容大小自动调整元素的尺寸。
统计全站每一个静态资源加载耗时, 该如何做
要统计全站每一个静态资源(如图片、JS 脚本、CSS 样式表等)的加载耗时,你可以借助浏览器的 Performance API,特别是利用 PerformanceResourceTiming 接口来获取资源加载的详细时间信息。以下是一个基本的步骤指导和示例代码,展示如何实现这一功能:
步骤
- 使用
PerformanceObserver: 创建一个PerformanceObserver实例来监听资源加载事件,能够实时收集性能数据,而且对性能影响较小。 - 过滤静态资源类型: 通过检查
initiatorType属性,筛选出静态资源(例如img、script、css等)的加载事件。 - 计算和展示耗时: 对每个静态资源的加载耗时进行计算并展示。资源的耗时可以通过
duration属性直接获取。
示例代码
以下是一个简单的 JavaScript 代码示例,展示了如何使用 PerformanceObserver 来统计全站静态资源的加载耗时:
// 创建性能观察者实例来监听资源加载事件
const observer = new PerformanceObserver((list) => {
const entries = list.getEntries();
for (const entry of entries) {
// 过滤静态资源类型
if (["img", "script", "css", "link"].includes(entry.initiatorType)) {
console.log(`资源 ${entry.name} 类型 ${entry.initiatorType} 耗时:${entry.duration.toFixed(2)} 毫秒`);
}
}
});
// 开始观察 Resource Timing 类型的性能条目
observer.observe({ entryTypes: ["resource"] });
注意事项
-
性能数据的准确性: 确保性能数据的准确性和实时性,你应该在页面加载的早期就开始监听资源加载事件,例如在
<head>标签中就引入或嵌入这段脚本。 -
跨域资源的时间信息: 如果你需要获取跨域资源的详细时间信息(如第三方字体或脚本),那么这些资源的服务器需要在响应头中包含
Timing-Allow-Origin头。 -
大量数据的处理: 如果页面包含大量静态资源,考虑如何存储、传输和分析这些数据,避免对性能和用户体验造成影响。
websocket 断联之后如何重连,且保证断联期间数据不丢失
1. 监听连接状态
首先,你需要监听 WebSocket 连接的各种事件,以便知道何时发生了断连,并根据这些事件来触发重连逻辑。
onclose: 当 WebSocket 连接关闭时,触发重连逻辑。onerror: 出现错误时,也可视为一个触发重连的信号。onopen: 连接成功时,清除重试计数器和缓存的数据(如果之前成功发送了)。
2. 实现重连逻辑
-
使用指数退避算法来延迟重连尝试,避免短时间内频繁重连。
- 例如,第一次重连延迟 1 秒,第二次 2 秒,然后 4 秒,最大延迟设置为 1 分钟。
-
在每次重连时,重置 WebSocket 对象并重新发起连接。
3. 缓存数据
- 发送数据前检查连接状态:如果 WebSocket 处于非开放状态,将数据缓存起来,待连接恢复后再发送。
- 使用队列存储待发送数据:便于按顺序发送,保证数据的完整性和顺序。
4. 发送缓存数据
-
在连接成功的回调(
onopen事件)中,检查是否有缓存的数据,如果有,则遍历队列发送。
如何做静态资源预加载
预加载是指在用户需要数据或资源之前,提前加载这些数据或资源的过程。
预加载的优点
- 提升加载速度:通过提前加载资源,用户在访问页面时可以更快地看到完整内容。
- 提高用户体验:减少页面加载时的延迟,使用户感到更流畅。
- 优化资源使用:合理安排资源加载顺序,提高网络利用率。
WebWorker 实现预加载
下面的示例将展示如何使用 Web Worker 来预加载静态资源。我们将创建一个简单的 Web Worker 脚本,用于在后台预加载一些指定的静态资源(例如图片、CSS、JavaScript 文件等)。这个过程不会阻塞主线程,使得主线程可以继续处理其他任务,如用户交互,从而提升页面的响应性能。
步骤 1:创建 Web Worker 脚本
首先,创建一个 JS 文件作为 Web Worker 的脚本。我们把这个文件命名为 preloadWorker.js。
// preloadWorker.js
self.addEventListener("message", (e) => {
const urls = e.data;
urls.forEach((url) => {
fetch(url)
.then((response) => {
// 一个简单的操作,标识资源已被预加载
if (response.status === 200) {
postMessage(`Resource preloaded: ${url}`);
} else {
postMessage(`Resource failed: ${url}`);
}
})
.catch((error) => {
postMessage(`Resource fetch error: ${url}`);
});
});
});
步骤 2:在主线程中使用 Web Worker
接下来,在 HTML 页面中使用这个 Web Worker。
首先,确保在你的 HTML 中引入一个脚本,初始化并使用这个 Web Worker。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Web Worker Preload Demo</title>
</head>
<body>
<script src="main.js"></script>
</body>
</html>
步骤3:程脚本 main.js 用于启动和与 Web Worker 交互。
// main.js
if (window.Worker) {
const worker = new Worker("preloadWorker.js");
const resources = [
"image.png", // 示例资源,确保替换为实际的 URL
"style.css",
"script.js",
];
worker.postMessage(resources);
worker.onmessage = (e) => {
console.log(e.data);
};
} else {
console.log("Your browser doesn't support web workers.");
}
这段脚本首先检查浏览器是否支持 Web Worker。如果支持,它会创建一个指向 preloadWorker.js 的新 Worker 实例,然后将要预加载的资源列表发送给这个 Worker。最后,它设置一个事件监听器来接收并处理 Worker 发出的消息。
如何处理异步加载组件
使用 defineAsyncComponent 方法
Vue 3 提供了 defineAsyncComponent 方法,使得定义和使用异步组件变得简单。你可以通过传递一个函数,该函数返回一个 import() 调用(返回 Promise),来动态加载组件。
javascript
代码解读
复制代码
import { defineAsyncComponent } from "vue";
const AsyncComponent = defineAsyncComponent(() => import("./components/AsyncComponent.vue"));
// 在组件中使用
export default {
components: {
AsyncComponent,
},
};
加载状态处理
你还可以使用 defineAsyncComponent 的高级用法,提供一个对象来处理加载状态,如显示加载中的提示、错误处理和超时处理。
const AsyncComponent = defineAsyncComponent({
// 加载异步组件的工厂函数
loader: () => import("./components/AsyncComponent.vue"),
// 加载中时要使用的组件
loadingComponent: LoadingComponent,
// 加载失败时要使用的组件
errorComponent: ErrorComponent,
// 在显示 loadingComponent 之前的延迟 | 默认值:200(毫秒)
delay: 200,
// 如果提供了超时时间(毫秒),超时后将显示错误组件 | 默认值:Infinity
timeout: 3000,
});
Vue 2 中处理异步组件的方法
在 Vue 2 中,异步组件的定义略有不同,你可以直接在组件注册时提供一个返回 Promise 的工厂函数。
javascript
代码解读
复制代码
Vue.component("async-component", () => import("./components/AsyncComponent.vue"));
或者为了处理加载状态,可以提供一个高级的对象形式:
Vue.component("async-component", (resolve, reject) => ({
// 需要加载的组件 (应该是一个 Promise)
component: import("./components/AsyncComponent.vue"),
// 异步组件加载时使用的组件
loading: LoadingComponent,
// 加载失败时使用的组件
error: ErrorComponent,
// 展示加载中组件前的等待时间。默认:200ms。
delay: 200,
// 如果提供了超时时间 (毫秒),超时后会显示错误组件。默认:Infinity
timeout: 3000,
}));