首页/文章/八股文

React高阶篇前端面试题

2025-07-20
592620 分钟
...

一、React-Router

2.React-Router的核心作用

  • SPA导航:在单页面应用中管理不同视图的切换,无需重新加载页面
  • URL与组件映射:将URL路径映射到对应的React组件,保持UI和URL同步
  • 历史记录管理:支持浏览器历史记录的导航(前进/后退)

2.核心组件与API

1.路由器类型

BrowserRouter
  • 使用HTML5 History API(pushState,replaceState)保持UI与URL同步
import { BrowserRouter } from 'react-router-dom';
<BrowserRouter>
  <App />
</BrowserRouter>
HashRouter
<HashRouter>
  <App />
</HashRouter>

2.路由定义

Route:定义路径与组件的映射关系
  • 使用URL的hash部分(如/#home),适用于不支持History API的旧浏览器
    • v5版本:
<Route path="/users" component={Users} />
- v6版本
<Route path="/users" element={<Users />} />
Routes(v6替代v5的Switch)
  • 仅渲染第一个匹配的Route,提升性能
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
</Routes>

2.导航组件

  • Link:生成无刷新导航链接
<Link to="/about">关于</Link>
  • Navigate(V6替代V5的Redirect):重定向到指定路径
<Route path="/old" element={<Navigate to="/new" />} />

3.版本差异(v5 VS v6)

特性v5v6
路由匹配顺序匹配所有 Route优先精确匹配,使用 Routes
嵌套路由在子组件中定义嵌套 Route直接在父 Route 内嵌套
重定向Redirect 组件Navigate 组件 + replace 属性
编程式导航useHistoryuseNavigate
路由参数useParams 获取useParams + 动态路由语法优化

常见问题与解决方案

1.如何实现嵌套路由

  • v5
<Route path="/users" component={Users}>
  <Route path="/users/:id" component={UserDetail} />
</Route>

{this.props.children}
  • v6
<Route path="/users" element={<Users />}>
  <Route path=":id" element={<UserDetail />} />
</Route>

import { Outlet } from 'react-router-dom';
function Users() {
  return (
    <div>
      <h1>用户列表</h1>
      <Outlet />
    </div>
  );
}

2.如何动态处理路由参数?

<Route path="/users/:userId" element={<UserProfile />} />


import { useParams } from 'react-router-dom';
function UserProfile() {
  const { userId } = useParams();
  return <div>用户ID: {userId}</div>;
}

3.编程式导航的实现

  • v5
import { useHistory } from 'react-router-dom';
function Login() {
  const history = useHistory();
  const handleLogin = () => {
    history.push('/dashboard');
  };
  return <button onClick={handleLogin}>登录</button>;
}
  • v6
import { useNavigate } from 'react-router-dom';
function Login() {
  const navigate = useNavigate();
  const handleLogin = () => {
    navigate('/dashboard', { state: { from: '/login' } });
  };
  return <button onClick={handleLogin}>登录</button>;
}

4.路由守卫

function PrivateRoute({ children }){
    const isAuthenticated = useAuth(); 
    return isAuthenticate ? chilren : <Navigate to="/login" />;
    
}

<Route
    path="/dashbord"
    element={ 
        <PrivateRoute>
            <Dashboard />
        </PrivateRoute>
    }

5.处理404页面

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="*" element={<NotFound />} />
</Routes>

5.高级技巧与最佳实践

1.代码分割与懒加载

  • 结合React.lazySuspense实现按需加载
const Users = React.lazy(() => import('./Users'));
<Route path="/users" element={
  <Suspense fallback={<Loading />}>
    <Users />
  </Suspense>
} />

2.传递状态至路由组件

  • 使用state属性传递
navigate('/profile', { state: { userData: data } });

const location = useLocation();
const userData = location.state?.userData;

3.使用useRoutes配置式路由(V6)

  • 集中管理路由配置
const routes = useRoutes([
  { path: '/', element: <Home /> },
  { path: 'users', element: <Users />, children: [
    { path: ':id', element: <UserDetail /> }
  ]}
]);
return routes;

6.高频面试题

1.BrowserRouter和HashRouter有什么区别?
  • BrowserRouter使用HTML5 History API,URL格式为example.com/path
  • HashRouter使用URL Hash(example/#/path),兼容旧浏览器但不够美观
2.React-Router V6有哪些重大改进
  1. 引入Routes代替Switch,提升匹配逻辑
  2. 嵌套路由配置更简洁,支持相对路径
  3. 移除Redirect,改用Navigate
  4. element属性直接传递JSX元素,支持更灵活的组件组合
3.如何实现路由鉴权
  • 使用高阶组件或自定义路由组件包裹需要保护的路径,检查用户权限后决定渲染目标组件还是重定向到登录页
4.为什么需要exact属性(V5)
  • 确保路径完全匹配。例如,path=“/” 没有exact时会匹配所有以/开头的URL。v6中默认精确匹配,无需此属性。

二、性能优化

1.优化核心思路

  1. 减少不必要的渲染:避免组件因无关状态/props变化而重新渲染
  2. 降低计算开销:缓存高成本计算和函数引用
  3. 优化DOM操作:减少实际DOM的无效变更
  4. 合理加载资源:按需加载关键代码与数据

2.关键优化策略与实现

1.组件渲染控制

  • React.memo:缓存函数组件渲染结果
const MemoComponent = React.memo(Component, (prevProps, nextProps) => {
  return prevProps.id === nextProps.id; 
});
  • PureComponent:类组件自动浅比较props/state
class OptimizedComponent extends React.PureComponent {
  
}
  • shouldComponentUpdate:手动控制类组件更新
shouldComponentUpdate(nextProps, nextState) {
  return this.props.data.id !== nextProps.data.id; 
}

2.高效数据管理

  • useMemo:缓存复杂计算结果
const processedData = useMemo(() => transformData(rawData), [rawData]);
  • useCallback:稳定函数引用
const handleClick = useCallback(() => {
  submitData(id);
}, [id]); 
  • 状态结构优化:扁平化数据,避免深层嵌套
const [data, setData] = useState({ user: { profile: { name: '' } } });


const [userName, setUserName] = useState('');

3.列表渲染优化

  • key属性优化:使用唯一稳定标识
{items.map(item => (
  <ListItem key={item.id} data={item} /> 
))}
  • 虚拟列表技术:使用react-window实现
import { FixedSizeList as List } from 'react-window';

<List height={600} itemSize={35} itemCount={1000}>
  {({ index, style }) => <div style={style}>Row {index}</div>}
</List>

4.资源加载优化

  • 代码分割:动态加载非关键组件
const LazyComponent = React.lazy(() => import('./HeavyComponent'));

<Suspense fallback={<Spinner />}>
  <LazyComponent />
</Suspense>
  • 图片懒加载:使用Intersection Observer
const LazyImage = ({ src }) => {
    const imageRef = useRef();
    useEffect(() => {
        const observer = new IntersectionObserver((entries) => {
            if (entries[0].isIntersecting){
                imgRef.current.src = src;
                observer.unobserve(imgRef.current);
            }
        });
        observer.observe(imgRef.current);
        return () => observer.disconnect();
    }, []);
    return <img ref={imgRef} alt="Lazy loaded" />;
}

3.性能分析工具

1. React DevTools Profiler

  • 记录组件渲染耗时
  • 查看渲染原因

2. Chorme Perfomance面板

  • 分析JavaScript执行耗时
  • 识别长任务(Long Tasks)

3. Lighthouse审计

  • 综合评估性性能指标(FCP,TTI,TBT)
  • 获取优化建议

4.高级优化技术

1.并发模式优化(React18+)

  • 自动批处理:合并多个状态更新
const handleClick = () => {
  setCount(c => c + 1);
  setValue(v => v + 1);
};
  • useTransition:区分紧急/非紧急更新
const [isPending, startTransition] = useTransition();

const handleSearch = (query) => {
  startTransition(() => {
    setSearchQuery(query); 
  });
};

2.服务端渲染优化

  • 流式SSR:分块传输HTML
export async function getServerSideProps() {
    return {
        props: { data: await fetchData() },
    };
}
  • 静态生成:预渲染静态页面
export async function getStaticProps() {
    return { props: {  }, recalidate: 60 }; 
}

5.常见性能陷阱与方案

问题解决方案
不必要的 Context 更新拆分多个 Context,使用 useMemo 缓存 Provider 值
过度使用 useMemo仅对高开销计算使用,避免对小计算进行不必要的缓存
内存泄漏及时清理定时器、事件监听器、订阅等副作用
大状态对象更新使用 Immer 实现不可变更新,避免深拷贝性能问题

6.性能优化黄金法则

  1. 优先解决关键瓶颈:使用Profiler定位主要性能
  2. 避免过早优化:在出现可测量的性能问题后再实施优化
  3. 保持组件简单:单一职责组件更易优化
  4. 渐进增强:优先优化首屏关键路径,再处理次要内容

三、高级特性

1.错误边界

1.定义与作用

  • 错误边界是React中的一种特殊类组件,用于捕获其子组件树中发生的JavaScript错误,防止这些错误导致整个应用崩溃。通过错误边界,开发者可以优雅地处理错误,并展示降级UI以提升用户体验

2.实现方式

错误边界必须使用类组件实现,并定义以下两个生命周期方法之一(或两者):

  1. static getDerivedStateFromError(error)
  • 作用:捕获子组件抛出的错误,返回一个状态对象来更新组件状态
  • 触发时机:渲染阶段(Render Phase)
  • 返回值:必须返回一个对象用于更新state,以控制是否显示降级UI

2.componentDidCatch(error, errorInfo)

  • 作用:记录错误信息(如发送至监控平台)
  • 触发时机:提交阶段(Commit Phase)
  • 参数
    • error:抛出的错误对象
    • errorInfo:包含组件栈信息的对象(componentStack)
class ErrorBoundary extends React.Component {
    state = { hasError: false };
    static getDerivedStateFromError(error) {
        return { hasError: true }; 
    }
    
    componentDidCatch(error, errorInfo) {
        logErrorToService(error, errorInfo); 
    }
    
    render() {
        if (this.state.hasError) {
            return <h1>Oops! Something went wrong.</h1>;
        }
        return this.props.children; 
    }
}

3.使用场景

1.包裹高风险组件
<ErrorBoundary>
  <UnstableComponent />
</ErrorBoundary>
2.全局兜底错误处理
<ErrorBoundary>
  <App />
</ErrorBoundary>

4.错误边界的限制

可捕获的错误类型无法捕获的错误类型
子组件渲染期间的错误事件处理器中的错误(需手动 try/catch
生命周期方法中的错误异步代码(如 setTimeoutfetch
构造函数中的错误服务端渲染(SSR)的错误
子组件错误边界未处理的错误错误边界自身抛出的错误

5.最佳实践

1.避免滥用
  • 仅在关键组件或模块使用,而非整个组件
2.组合使用
  • 多层错误边界实现局部错误隔离
<ErrorBoundary>
  <Header />
  <ErrorBoundary>
    <MainContent />
  </ErrorBoundary>
  <Footer />
</ErrorBoundary>
3.try/catch互补
  • 错误边界处理渲染错误
  • try/catch处理事件处理器、异步代码错误
function MyComponent() {
  const handleClick = () => {
    try {
      
    } catch (error) {
      logError(error);
    }
  };
  return <button onClick={handleClick}>Click</button>;
}

6.高频面试题

1.函数式组件能否作为错误边界?
  • 不能。错误边界必须通过类组件的生命周期方法实现,函数式组件需包裹在类组件的错误边界中
2.错误边界可以捕获哪些阶段的错误?
  • 仅捕获渲染阶段(如render、constructor、生命周期方法)的错误,无法捕捉提交阶段(如DOM操作)或异步代码中的错误
3.如何测试错误边界?
  1. 测试中模拟子组件抛出错误
  2. 验证错误边界是否显示降级UI
  3. 检查错误是否正确上报
test('ErrorBoundary shows fallback UI on error', () => {
  const ErrorComponent = () => {
    throw new Error('Test error');
  };
  const { getByText } = render(
    <ErrorBoundary>
      <ErrorComponent />
    </ErrorBoundary>
  );
  expect(getByText('Oops! Something went wrong.')).toBeInTheDocument();
});
4.错误边界如何处理自身错误?
  • 错误边界自身的错误会冒泡到上一层的错误边界。若没有父级边界,则导致整个应用崩溃

2.高阶组件

1.定义

高阶组件(Higher-Order Component)是React中用于复用组件逻辑的一种高级技巧。它是一个函数,接受一个组件作为参数,并返回一个新的增强组件。HOC本身不是组件,而是一个组件工厂函数

2.HOC的核心作用

  1. 逻辑复用:抽离多个组件的公共逻辑(如数据获取,权限控制)
  2. 增强组件能力:为组件注入额外的props或扩展生命周期行为
  3. 代码解耦:将业务逻辑与UI组件分离,提升可维护性

3.HOC的实现

1.属性代理(Props Proxy)
  • 特点:HOC包裹目标组件,通过props传递数据或方法
function withLogging(wrappedComponent) {
    return class extends React.Component {
        componentDidMount() {
            console.log('Component is mounted:', WrappedComponent.name);
        }
        render() {
            
            return <WrappedComponent {...this.props} />;
        }
    }
}

const EnhancedComponent = withLogging(MyComponent);
2.反向继承(Inheritance Inversion)
  • 特点:通过继承目标组件,控制其渲染流程(较少使用)
function withEnhancement(WrappedComponent) {
    return class extends WrappedComponent {
        render() {
            
            const elements = supoer.render();
            return React.cloneElement(elements, { newPorps: 'value' });
        }
    }
}

const EnhancedComponent = withEnhancement(MyComponent);

4.HOC应用场景

场景示例 HOC功能
权限控制withAuth检查用户权限,未登录则跳转
数据请求withFetchData统一处理 API 请求与状态管理
UI 功能增强withHover/withClickOutside添加悬停或点击外部关闭功能
状态管理Redux connect连接组件与 Redux Store

5.注意事项

1.不要修改原始组件
  • 使用组合而非继承,避免直接修改原始组件的原型
2.透传无关props
  • 确保HOC传递所有与自身无关的props到被包裹组件
render() {
  const { extraProp, ...restProps } = this.props;
  return <WrappedComponent {...restProps} />;
}
3.处理静态方法
  • 使用hoist-non-react-statics复制静态方法到新组件
npm install hoist-non-react-statics
import hoistNonReactStatic from 'hoist-non-react-statics';

function withEnhancement(WrappedComponent) {
  class EnhancedComponent extends React.Component {  }
  hoistNonReactStatic(EnhancedComponent, WrappedComponent);
  return EnhancedComponent;
}
4.Ref传递问题
  • 使用React.forwardRef转发Ref到被包裹组件
function withRefForwarding(WrappedComponent) {
    class EnhancedComponent extends React.Componnet {
        render() {
            const { forwardedRef, ...resetProps } = this.props;
            return <WrappedComponent ref={forwardedRef} {...resetProps} />;
        }
    }
    return React.forwardRef((props, ref) => (
        <EnhancedComponent forwardedRef={ref} {...props} />;
    ))
}

6.HOC和Hooks对比

维度HOCHooks
适用组件类型类组件/函数组件仅函数组件
逻辑复用方式包裹组件,形成组件树层级在组件内部直接调用 Hook 函数
代码组织可能引入多层嵌套,可读性下降扁平化逻辑,易于追踪数据流
性能影响可能因层级嵌套导致不必要的渲染依赖数组精准控制更新
学习曲线需理解高阶函数和组件组合需掌握闭包和依赖数组规则

7.高频面试题

1.HOC的优缺点
  • 优点

    1. 跨组件复用逻辑,减少代码冗余
    2. 适用于类组件,兼顾旧项目
  • 缺点

    1. 组件层级嵌套过深,调试困难
    2. 需处理静态方法和Ref传递
    3. 可能引发props命名冲突
2.如何避免HOC的props命名冲突?
  • 使用命名空间或特点前缀
<WrappedComponent hocData={data} {...restProps} />
  • 在HOC中过滤专属props
render() {
  const { hocProp, ...passThroughProps } = this.props;
  return <WrappedComponent {...passThroughProps} />;
}
3.HOC在React生态的典型应用有哪些?
  • Reduxconnect(mapStateToProps, mapDispatchToProps)(Component)
  • React RouterwithRouter(Component)
  • Material-UIwhithStyle(styles)(Component)
4.HOC是否会导致性能问题?如何优化?
  • 问题:每次父组件渲染时创建新的HOC实例,导致子组件重新挂载
  • 优化:在组件外部定义HOC,而非在render方法中动态创建
function Parent() {
  const HocComponent = withLogging(Child);
  return <HocComponent />;
}


const EnhancedChild = withLogging(Child);
function Parent() {
  return <EnhancedChild />;
}

3.服务端渲染方案

1.核心优势

  1. SEO友好:爬虫直接解析服务端返回的HTML,提升搜索引擎排名
  2. 首屏性能优化:减少客户端渲染的白屏时间,提升用户体验
  3. 兼容性保障:确保低端设备或禁用JavaScript的环境下基础内容可访问

2.主流SSR方案对比

方案特点适用场景
Next.js开箱即用、约定式路由、支持 SSG/SSR/ISR全栈应用、SEO 要求高的项目
Gatsby基于 GraphQL 的静态站点生成(SSG)、插件生态丰富内容型网站(博客、文档)
自定义 SSR灵活控制渲染流程、深度定制化复杂企业级应用、特殊架构需求
React Server Components混合渲染(服务端/客户端组件结合)、减少客户端 JS 体积动态内容与静态内容混合的场景

3.Next.js实现SSR深度解析

1.页面级SSR

使用getServerSideProps在每次请求时生成页面

export async function getServerSideProps(context) {
    const data = await fetchData(context.data.id);
    return { props: { data } }; 
}

function Page({ data }) {
    return <div>{data}</div>;
}
2.增量静态再生(ISR)

结合静态生成与按需更新

export async function getStaticProps() {
  const data = await fetchData();
  return { 
    props: { data },
    revalidate: 60 
  };
}
3.客户端水合(Hydration)

自动处理服务端与客户端渲染链接

import { renderToString } from 'react-dom/server';
const html = renderToString(<App />);


import { hydrateRoot } from 'react-dom/client';
hydrateRoot(document.getElementById('root'), <App />);

4.自定义SSR实现步骤

1.项目结构配置
- src/
  - client/
    - index.js 
  - server/
    - index.js 
2.Webpack多环境配置
module.export = {
    entry: './src/client/index.js',
    output: {
        filename: 'client-bundle.js',
        path: path.resolve(__dirname, 'dist'),
    }
};

module.exports = {
    entry: './src/server/index.js',
    target: 'node',
    output: {
        filename: 'server-boudle.js',
        path: path.resolve(__dirname, 'dist'),
    }
};
3.服务端渲染核心逻辑
import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from '../shared/App';

const app = express();
app.get('*', (req, res) => {
  const html = renderToString(<App />);
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>SSR App</title>
      </head>
      <body>
        <div id="root">${html}</div>
        <script src="/client-bundle.js"></script>
      </body>
    </html>
  `);
});
4.数据预取和状态同步
const fetchData = async () => {
  const res = await fetch('https://api.example.com/data');
  return res.json();
};


window.__INITIAL_STATE__ = serverData;


const initialState = window.__INITIAL_STATE__;
const store = configureStore(initialState);
hydrateRoot(document.getElementById('root'), <App store={store} />);

5.性能优化策略

1.缓存机制
const microCache = new LRU({
  max: 100,
  maxAge: 1000 * 60 
});

app.get('*', (req, res) => {
  const cachedHtml = microCache.get(req.url);
  if (cachedHtml) return res.send(cachedHtml);
  
  const html = renderToString(<App />);
  microCache.set(req.url, html);
  res.send(html);
});
2.流式渲染
import { renderToPipeableStream } from 'react-dom/server';

app.use((req, res) => {
  const stream = renderToPipeableStream(<App />, {
    onShellReady() {
      res.setHeader('Content-type', 'text/html');
      stream.pipe(res);
    }
  });
});
3.代码分割
import loadable from '@loadable/component';
const LazyComponent = loadable(() => import('./HeavyComponent'));


import { ChunkExtractor } from '@loadable/server';
const extractor = new ChunkExtractor({ statsFile: 'dist/loadable-stats.json' });
const jsx = extractor.collectChunks(<App />);
const html = renderToString(jsx);
const scriptTags = extractor.getScriptTags(); 

6.常见问题与解决方案

问题解决方案
客户端-服务端状态不一致使用 Redux 或 Context API 同步初始化状态
window 未定义错误通过条件判断限制客户端专用代码执行:if (typeof window !== 'undefined')
样式闪烁(FOUC)​使用 isomorphic-style-loader 提取服务端样式到 <style> 标签
内存泄漏监控服务器内存使用,使用 --max-old-space-size 调整 Node.js 内存限制

4.React18+新特性

1.并发渲染

React 18的核心更新是引入并发渲染能力,允许React在渲染过程中中断并优先处理更高优先级的任务(比如用户输入),从而提升响应速度。

关键机制
  • 时间切片:将渲染任务拆分成小块,避免长时间阻塞主线程
  • 优先级调度:用户交互(如点击)优先于数据更新(如API响应)
相关API
  • startTransition:标记非紧急更新,可被高优先级任务打断
import { startTransition } from 'react';

const handleSearch = (query) => {
  startTransition(() => {
    setSearchQuery(query); 
  });
};
  • useTransition:跟踪过渡状态,显示加载指示
const [isPending, startTransition] = useTransition();

return (
  <button onClick={() => startTransition(handleClick)}>
    {isPending ? '加载中...' : '提交'}
  </button>
);

2.自动批处理

React 18默认将多次状态更新合并为单次渲染,减少不必要的重复渲染

更新场景对比
场景React 17 及之前React 18
事件处理器中的更新批量处理批量处理
setTimeout/Promise 中的更新不批量处理批量处理
强制同步更新
import { flushSync } from 'react-dom';

flushSync(() => {
  setCount(c => c + 1); 
});

3.流式服务端渲染

通过分块传输HTML选择性水合,显著提升服务端渲染性能

核心改进
  • 流式传输:服务器逐步发送HTML到客户端,缩短首屏时间
  • 并行水合:客户端在接收HTML时逐步激活交互功能,无需等待全部内容加载
import { renderToPipeableStream } from 'react-dom/server';

app.get('/', (req, res) => {
  const stream = renderToPipeableStream(<App />, {
    onShellReady() {
      res.setHeader('Content-type', 'text/html');
      stream.pipe(res);
    },
    bootstrapScripts: ['/main.js'] 
  });
});

4.新根API与严格模式增强

1.新根API createRoot

替换原有的ReactDOM.render,启用并发功能

ReactDOM.render(<App />, document.getElementById('root'));


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
2.严格模式
  • 模拟卸载-挂载:开发环境下组件挂载后立即卸载再重新挂载,检测副作用清理问题
  • 重复渲染检测:故意双调用组件函数和Hook,暴露潜在副作用

5.新Hook与API

1.useId
  • 生成唯一ID,解决服务端与客户端ID不一致的问题
const id = useId(); 
return <label htmlFor={id}>用户名</label>;
2.useDeferredValue
  • 延迟更新非关键UI,保持高优先级交互流程
const deferredQuery = useDeferredValue(query);
return <SearchResults query={deferredQuery} />;
3.useSyncExternalStore
  • 简化外部状态库(如Redux)集成,避免并发渲染下的撕裂问题
const state = useSyncExternalStore(store.subscribe, store.getState);

6.改进的Suspense功能

  • 支持在SSR中与流式渲染结合,优化体验
<Suspense fallback={<Spinner />}>
  <Comments /> {}
</Suspense>

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
八股文2026-08-27
定时器按顺序播放多个音频,切后台音频会乱
本身不会补触发,但 它会被系统级冻结 ——iOS Safari 后台完全停止计时,切回前台后 只补执行一次 (不是不补,而是"缺失的中间状态补不上")。间隔短的不会出大问题, 间隔长的会出现"音频流被压缩" ——切回来后本该播 5 分钟的间隙,实际只过了 3 分钟,结果整段对不上。 核心原则 :定时器只能用来"提醒一次", 真正决定"该不该播"的是绝对时间戳 。 setTimeout 在后台会发生什么(按平台) | 平台 | 后台行为...
面试
八股文2026-08-27
线上项目白屏的原因
白屏的本质是 渲染管线某一环断了 ——可能是资源、JS、接口、路由、样式、兼容性任一环节出问题。排查按"控制台 → 网络 → DOM → 环境"四步定位。 本质(前端类比) 把网页想成一栋楼: 白屏 ≠ 一定是同一种原因——这是面试想听的层次。 六大类原因(按出现频率) | 类别 | 典型表现 | 真实案例 | | : | : | : | | ① 资源加载失败 | DOM 是空的 | 入口 JS 404、CDN 挂了、CSS 阻塞 |...
面试
八股文2026-08-27
背景图就是 1MB 大图,怎么优化
1MB 大背景图优化分 三步 :压缩体积(10 30x)、按需加载(按设备/视口/网速)、渲染期优化(GPU 合成)。背景图跟 不同——它是 CSS,不走浏览器的原生懒加载机制,得手动处理。 背景图 vs 的关键区别(先讲清楚这个) 这是面试官想听的"针对性认知"——背景图不是普通图片,不能套通用方案。 三步优化(按优先级) 第 1 步:压缩体积(最重要,立竿见影) 1MB 的来源一般是这几种 ,对应解决方案: | 原始问题 | 体积来...
面试
八股文2026-08-27
项目里很多图片和视频,怎么优化
图片视频优化分 四层 :网络层(CDN/格式)、加载层(懒加载/预加载)、渲染层(解码/缓存)、业务层(按需/降级)。面试要把这四层都讲到位才算有体系。 四层优化模型 第 1 层:网络层(省钱、省时间) 核心目标:让资源体积小、让用户拿到资源快 | 手段 | 作用 | 关键点 | | : | : | : | | 图片格式 | WebP/AVIF 比 JPEG 小 25 50% | 兼容 fallback | | 视频格式 | H.265...
面试
八股文2026-08-20
Embedding 向量模型:从语义表示到相似度计算
前言 大模型「读懂」文字靠的是 token,但 token 之间只有离散的编号关系,模型并不知道「苹果」和「李子」在语义上很近。要让程序能「理解」两段文字的相似程度,必须先把文本映射成一个 高维向量 ,再用几何方法比较。这一步就是 Embedding。 本篇基于我本地 今天的真实代码,从语义表示讲到余弦相似度,并复盘几个踩过的真实坑。 一、为什么需要 Embedding 传统关键词检索是「字面匹配」: Embedding 做的是「语义匹...
面试
八股文2026-08-19
前端面试100题
前端面试 100 题 适用方向:中高级前端 / React / Vue / Next.js / Nuxt / TypeScript / 工程化 / 实时通信 / Electron / Node.js / AI 应用前端 使用方式:优先掌握“标准回答”,再练“面试官追问”,最后把“结合你的简历怎么答”组织成自己的项目故事。 说明 “结合你的简历怎么答”只使用你简历中已经出现的项目与技术事实。 “标准回答 / 追问”属于通用前端知识总结,用...
面试

评论

请登录后发表评论

去登录
加载评论中...

目录