得物一面

86 阅读10分钟

盒模型

盒模型(Box Model)是网页布局和设计的一个基本概念,它定义了一个元素在网页上的占位方式

  • 标准盒模型 box-sizing: content-box
  • 怪异盒模型(IE盒模型)box-sizing: border-box

主要区别:

在标准盒模型中,widthheight 只包括内容区域(content area)的宽度和高度,不包含内边距和边框

在怪异盒模型中,widthheight 包括了内容区域、内边距和边框的总宽度

响应式布局有哪些

流式布局(百分比)/ 弹性盒模型(flex)/ 网格布局(grid)/ 媒体查询 / 响应式单位

flex

  1. 主轴怎么确定?flex-direction:column
  2. 主轴怎么居中?justify-content:center
  3. flex:1的代表什么意思,各个属性是什么?
    • flexflex-grow, flex-shrink, 和 flex-basis 三个属性的简写形式。

axios是怎么封装的

先找一张大神的流程图

image.png

在我们正式开发前,首先需要清楚请求一个接口都做了什么。主要包含两部分基础请求流程 、 拦截器 。

前端架构带你 封装axios,一次封装终身受益「美团后端连连点赞」屋里美团的姑娘喊我帮她写前端,忙到凌晨两点的我苦不堪言 - 掘金 (juejin.cn)

主要代码

axios怎么取消重复请求

应用场景

1. tab切换时刷新某个列表数据,如果他们共用一个变量存储数据列表,当请求有延时,可能会导致两个tab数据错乱; 这个我遇到过,我记得是给要切换过去的tab button加一个loading,等待当前请求结束后,再执行切换

2. 导出文件或下载文件时,中途取消 。

v0.22之前使用 cancelToken(已弃用)

AbortController 直接粘贴源码吧,很清楚

原理

AbortController 接口表示一个控制器对象,允许你根据需要中止一个或多个 Web 请求。 我们先使用 AbortController() 构造函数创建一个控制器,然后使用 AbortController.signal 属性获取其关联 AbortSignal 对象的引用。 当 fetch 请求初始化时,我们将 AbortSignal 作为一个选项传递进入请求的选项对象中(下面的 {signal})。这将 signal 和 controller 与 fetch 请求相关联,并且允许我们通过调用 AbortController.abort() 去中止它。

let controller;
const url = "video.mp4";

const downloadBtn = document.querySelector(".download");
const abortBtn = document.querySelector(".abort");

downloadBtn.addEventListener("click", fetchVideo);

abortBtn.addEventListener("click", () => {
  if (controller) {
    controller.abort();
    console.log("中止下载");
  }
});

function fetchVideo() {
  controller = new AbortController();
  const signal = controller.signal;
  fetch(url, { signal })
    .then((response) => {
      console.log("下载完成", response);
    })
    .catch((err) => {
      console.error(`下载错误:${err.message}`);
    });
}

批量取消?

传入相同的signal

取消后重新发起请求?

使用axios-retry这个库去实现重试

直接执行axiosRetry传递axios实例即可。同时它会支持几个配置参数

  • retries: 重试次数,默认是3次
  • retryCondition:一个函数判断发生错误时是否重试。默认是5xxhttp 错误或者网络异常或者是幂等请求(GET/HEAD/ OPTIONS/PUT/DELETE)才会重试。
  • shouldResetTimeout:重试的时候是否重置超时时间。默认不重置。也就是说多次重试请求必须在timeout内结束
  • retryDelay每个请求之间的重试延迟时间,默认为0 例如,如果我想定制,重试4次、除了默认情况重试外,404也重试、重置超时时间、重试延迟时间50ms,则这样即可
import axiosRetry from 'axios-retry';
axiosRetry(axios, {
    retries: 4,
    retryCondition: (err) => axiosRetry.isNetworkOrIdempotentRequestError(err) || error.response.status === 404,
    shouldResetTimeout: true,
    retryDelay: 50
});

axios-retry实现重试的原理:

  • axios-retry会在axios的config的axios-retry字段中保存当前已经重试的次数(retryCount)

  • axios会在http异常/网络异常的情况下抛出错误。axios-retry则在响应拦截器中注册错误处理函数,执行retryCondition判断是否需要进行重试。如果需要重试则对retryCount进行++操作,然后返回一个Prommise使用当前的config重新发起一次新的请求new Promise(resolve => setTimeout(() => resolve(axios(config)), delay));。如果当前不需要重试(retryCondition返回false或者已经超过重试次数的场景,直接reject这个错误对象)

  axios.interceptors.response.use(null, error => {
    const config = error.config;
    // ....
    const currentState = getCurrentState(config);
    const shouldRetry = retryCondition(error) && currentState.retryCount < retries;
​
    if (shouldRetry) {
      currentState.retryCount += 1;
        //.....
​
      return new Promise(resolve => setTimeout(() => resolve(axios(config)), delay));
    }
​
    return Promise.reject(error);
  });

fiber 原理

传统 React 架构的局限性

React 最初的架构在处理 UI 更新时采用了同步的、阻塞的方式。即一次更新会从根节点开始递归遍历整棵组件树,直至完成所有组件的渲染。这种方式在处理简单的 UI 时表现良好,但随着应用的复杂性增加,特别是在处理大量节点更新或频繁用户交互时,传统架构暴露出了以下几个主要局限性:

  • 单次渲染时间过长:当组件树较大时,一次完整的渲染更新可能会占用大量的时间,这会导致主线程被阻塞,无法响应用户的输入,进而影响用户体验。

  • 缺乏优先级管理:传统架构无法根据任务的重要性分配优先级,所有更新一视同仁,这意味着关键任务(如用户输入处理)可能会被不重要的任务(如低优先级的动画或日志更新)阻塞。

  • 中断和恢复困难:在传统架构中,一旦开始渲染更新,就无法中途中断并恢复,这使得在处理高优先级任务时非常不灵活。

为什么需要 Fiber?

为了克服传统 React 架构的局限性,React 团队提出了 Fiber 架构。Fiber 是 React 的一种新的协调引擎,它通过将更新过程拆分为多个小任务来解决性能瓶颈和用户体验问题。

性能瓶颈

  • 增量渲染:Fiber 将渲染过程分成多个可以中断的小任务,这样即使组件树非常庞大,每个任务的执行时间也会较短,避免了长时间的阻塞。
  • 任务分片:通过任务分片(Time Slicing)技术,Fiber 可以在空闲时间片段内执行渲染任务,从而最大限度地利用浏览器的空闲时间,提升整体性能。

举个例子:假设 React 正在渲染一个很复杂的组件树,如果它一口气渲染整个组件树,可能会占用超过 16 毫秒的时间,导致页面卡顿。但 Fiber 会把这个渲染过程分成多个小块,在每个小块执行一部分渲染任务。当某个小块快要超过 16 毫秒时,React 会暂停渲染,稍后继续,确保浏览器能及时处理用户操作和更新动画。

深入理解 React 的 Fiber 架构React 是由 Facebook 开发并于 2013 年开源的前端库,最初的 - 掘金 (juejin.cn)

React15和18的区别

一、 Render API

二、setState 自动批处理

三、flushSync

React18 新特性解读 & 完整版升级指南React 18 正式版它来啦!一起来看看 React 18 有哪些新特性 - 掘金 (juejin.cn)

npm和yarn的区别

注意:通常情况下不建议通过npm进行安装。npm安装是非确定性的,程序包没有签名,并且npm除了做了基本的SHA1哈希之外不执行任何完整性检查,这给安装系统程序带来了安全风险。

基于这些原因,强烈建议你通过最适合于你的操作系统的安装方法来安装yarn。

防抖和节流的区别

防抖

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

节流

规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

性能优化

网络层面

强缓存和协商缓存

image.png

强缓存

强缓存是指在缓存期间,浏览器直接从缓存中获取资源,而不会向服务器发送请求验证资源是否发生了变化。它主要通过设置HTTP响应头来控制资源的缓存时间。

常用的强缓存相关的HTTP头:

  • Cache-Control:这是HTTP/1.1引入的字段,解决了Expires的时间不精确问题。常用的取值包括:

    • max-age=<seconds>:指定资源的缓存时间,单位是秒。
    • public:资源可以被所有用户缓存,包括CDN、代理等。
    • private:资源只能被用户私有缓存。
    • no-store:不缓存资源。
    • no-cache:每次请求都必须向服务器验证缓存的有效性。

如果资源在缓存时间内未过期,浏览器将直接使用缓存,不会向服务器发送任何请求。

协商缓存

协商缓存是指在资源缓存过期或没有强缓存时,浏览器向服务器发送请求,通过服务器确认资源是否发生变化。如果资源没有变化,服务器返回304状态码,告知浏览器继续使用缓存的资源。

常用的协商缓存相关的HTTP头:

  • Last-ModifiedIf-Modified-Since

    • 服务器通过Last-Modified返回资源的最后修改时间,浏览器在下一次请求时,会带上If-Modified-Since头,询问服务器该时间之后资源是否被修改。如果没有修改,服务器返回304状态码,表示资源未改变,浏览器继续使用缓存的资源。
  • ETagIf-None-Match

    • 服务器通过ETag返回资源的唯一标识符,通常是基于文件内容生成的哈希值。浏览器在下一次请求时,会带上If-None-Match头,服务器通过比较ETag值判断资源是否发生变化。如果没有变化,同样返回304状态码。

典型的缓存流程:

  1. 浏览器请求资源,服务器返回资源并附带缓存控制的头信息。

  2. 浏览器根据Cache-ControlExpires判断资源是否需要重新请求。

    • 如果未过期,直接使用缓存(强缓存)。
    • 如果已过期,浏览器向服务器发送验证请求(协商缓存)。
  3. 服务器根据If-Modified-SinceIf-None-Match判断资源是否有变化。

    • 如果没有变化,返回304状态码,浏览器继续使用缓存。
    • 如果有变化,返回新的资源内容。

cdn实时更新

  1. 如果我使用了某厂商的CDN服务,我现在想要实时更新这个CDN上的资源,那么我首先要确保这个资源在远端节点更新的实时性;CDN全程是内容分发网络,对于不同地方的用户可能会命中不同地方的CDN服务节点,CDN运营商从收到更新的文件到全节点生效,是需要一定的时间的,这方面需要CDN运营商去保障,我们能做的就是选一个性能好一点的厂商

  2. CDN资源在我们前端页面上的生效;这个首先我们可以禁用所有缓存策略,并且链接上拼一些无用参数来保证每次都临时拉取CDN资源;如果追求性能的话,就使用协商缓存进行优化;具体实现原理是后台增加一个返回头来控制,一般实践上是前端来配置CDN服务的策略,CDN服务给资源的时候写好返回头

总结:

重复性问题慢慢整理。时机蛮重要的。。一旦negative...maybe the start of unlucky