面试题答案
一键面试1. 图片懒加载策略
- 使用
react - lazyload
或react - loadable
库:这些库提供了方便的懒加载功能,能够在图片进入视口时才加载图片资源。例如使用react - lazyload
,可以这样实现:
import React from 'react';
import LazyLoad from'react - lazyload';
const MyImage = () => {
return (
<LazyLoad>
<img src="your - image - url" alt="description" />
</LazyLoad>
);
};
- IntersectionObserver API:手动实现懒加载。通过
IntersectionObserver
可以异步观察目标元素与其祖先元素或顶级文档视口的交集变化情况。当图片进入视口时,加载图片。如下示例:
import React, { useRef, useEffect } from'react';
const MyImage = () => {
const imgRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = imgRef.current;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});
if (imgRef.current) {
observer.observe(imgRef.current);
}
return () => {
if (imgRef.current) {
observer.unobserve(imgRef.current);
}
};
}, []);
return <img ref={imgRef} data - src="your - image - url" alt="description" />;
};
2. 处理回流重绘
- 减少直接操作 DOM 样式:避免频繁修改图片的样式属性,例如
width
、height
等。如果需要修改,尽量一次性修改多个样式,或者使用classList
来切换 CSS 类,因为浏览器会批量处理classList
的更改,减少回流重绘次数。 - 使用
will - change
声明:对于图片动态更新,可以在 CSS 中使用will - change
属性来提示浏览器提前做好优化准备。例如:
img {
will - change: transform;
}
这会让浏览器在图片实际发生变换之前,就开始分配资源进行优化,减少回流重绘带来的性能损耗。
3. 内存管理
- 及时销毁不再使用的图片资源:当图片从 DOM 中移除时(例如通过组件卸载),确保相关的图片资源也被释放。在 React 组件中,可以使用
useEffect
的返回函数来清理资源。例如:
import React, { useEffect } from'react';
const MyImage = () => {
const imgRef = useRef(null);
useEffect(() => {
// 加载图片逻辑
return () => {
if (imgRef.current) {
imgRef.current.src = '';
// 可以进一步取消任何未完成的图片加载请求(如果有)
}
};
}, []);
return <img ref={imgRef} src="your - image - url" alt="description" />;
};
- 限制同时加载的图片数量:对于频繁动态更新的图片,可以设置一个最大同时加载图片的数量,避免一次性加载过多图片导致内存占用过高。例如在懒加载逻辑中,可以维护一个加载队列,当队列满时,等待有图片加载完成后再继续加载新的图片。
4. 优化复杂嵌套布局
- 使用
CSS Flexbox
或CSS Grid
:相比于传统的浮动布局,Flexbox 和 Grid 布局更加高效且易于维护。它们可以减少嵌套层级,并且在布局计算上更加优化,从而减少回流重绘的范围。例如,对于一个包含图片的复杂列表布局,可以使用 Flexbox 实现:
.container {
display: flex;
flex - direction: column;
flex - wrap: wrap;
}
.image - item {
flex: 1 0 200px; /* 图片项的宽度可根据需求调整 */
margin: 10px;
}
- 虚拟化列表:如果图片数量众多且在复杂嵌套布局中,可以考虑使用虚拟化列表技术,如
react - virtualized
或react - window
。这些库只渲染视口内可见的图片,大大减少了 DOM 元素数量,从而提升性能,减少内存占用和回流重绘的范围。例如使用react - virtualized
的List
组件:
import React from'react';
import { List } from'react - virtualized';
const images = [/* 图片数据数组 */];
const renderImage = ({ index, key, style }) => {
const image = images[index];
return (
<div key={key} style={style}>
<img src={image.url} alt={image.alt} />
</div>
);
};
const MyImageList = () => {
return (
<List
height={400}
rowCount={images.length}
rowHeight={200}
rowRenderer={renderImage}
width={300}
/>
);
};