1、防抖节流
- 防抖:事件停止一段时间后才执行(拖延执行)
- 常用于:搜索框输入、表单校验、防止按钮频繁提交
// 每次触发事件都会重置定时器,只有最后一次会被执行
function debounce(fn:Function,delay:number=3000){
let timer: any = null;
return (...args: any[])=>{
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
}
}
- 节流:事件每隔一段时间就执行一次(定期执行)
- 常用于:页面滚动监听(scroll)、鼠标拖拽(mousemove)、按钮防连击
function throttle(fn:Function,delay:number){
let last = 0;
return function (...args: any[]) {
const now = Date.now();
if (now - last >= delay) {
last = now;
fn.apply(this, args);
}
}
}
2、闭包
答:闭包就是函数可以“记住”并访问它定义时的作用域,即使它在定义作用域之外执行。
function outer() {
const name = '尊敬的大人';
return function inner() {
console.log('Hello,', name);
};
}
const greet = outer(); // outer 已经执行完毕
greet(); // → Hello, 尊敬的大人
- 闭包的本质:你可以外外部函数执行后返回了一个内部函数,这个函数持有对外部变量的引用。
- 常见的坑:循环绑定点击事件
// 把 var 换成 let 可以输出1、2、3 let 有块级作用域
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i); // 这里不会输出1、2、3; 会输出 3 次 3
}, 1000);
}
- 存在问题:
- 闭包会导致内存不释放,因为变量引用仍然存在
- 不要滥用闭包,闭包越多、内存越大
3、首屏加载速度如何优化提升(针对 Vue 项目)
- 代码拆分 & 路由懒加载
- 利用
Vue Router的懒加载功能,拆分路由组件,按需加载首屏以为的代码。
- 利用
import Home from '@/views/Home/index.vue';
const Home = () => import('@/views/Home.vue');
const router = createRouter({
routes: [
{ path: '/', component: Home },
{ path: '/about', component: () => import('@/views/about/index.vue') }
]
});
- 关键 CSS 内联 & CSS 拆分
- 使用
vue-cli-plugin-critical或手动抽取关键 CSS 并内联到 index.html 中,减少首屏 CSS 请求 - 非关键 CSS 异步加载
- 使用
- 图片优化和懒加载
- 使用现代图片格式(webp、avif),项目中的图片可以使用压缩工具进行压缩。
- 对非首屏图片使用懒加载,Vue 中可以用插件如 vue-lazyload。
import VueLazyload from 'vue-lazyload';
app.use(VueLazyload, {
loading: 'loading-spinner.gif'
});
- 预加载资源
- 在
index.html里添加关键图片、字体预加载。
- 在
<link rel="preload" href="/fonts/myfont.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/assets/fonts/YourFont.ttf" as="font" type="font/ttf" crossorigin="anonymous" />
<link rel="preload" href="/img/hero.webp" as="image" />
// 其他字体文件
@font-face {
font-family: 'YourFont';
src: url('/assets/fonts/YourFont.woff2') format('woff2'), url('/assets/fonts/YourFont.ttf') format('truetype');
font-display: swap;
}
- 异步组件 & 动态导入
- Vue 支持异步组件,非关键组件动态导入,减少首屏包体积。
const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue'));
- 优化字体加载
- 字体子集化,只加载首屏用到的字符。
- 使用
font-display: swap,防止字体阻塞页面渲染。
- 开启 HTTP/2 & 缓存
- 静态资源通过 CDN 发布,开启 HTTP/2 多路复用。
- 合理设置缓存策略(Cache-Control、ETag)。