前端入门到入土?

文章目录

  • 前言
  • 性能优化
    • 浏览器缓存优化
    • 配置CDN缓存
  • nextTick应用原理
  • diff算法的深度解析
    • vue2
    • vue3
    • react
  • 后言

前言

hello world欢迎来到前端的新世界


当前文章系列专栏:前端面试
‍博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)
感谢大家支持!您的观看就是作者创作的动力

性能优化

在我们面试过程中,面试官可能会问到我们在项目中有没有做过性能优化
或者直接给我们来一句,说出10个性能优化的方案
这个时候虽然我们心里想着”TMD“,公司里面有那么多大佬,哪里轮得到我来做性能优化,哈哈 但是我们还要装作内心毫无波澜,”嗯嗯 有的“
接下来分为三个优化部分给大家讲解。

前端入门到入土?_第1张图片

浏览器缓存优化

indexDB

IndexDB是一种浏览器内置的客户端数据库,它提供了一种在浏览器中存储和操作大量结构化数据的机制。

使用方式

  • 打开数据库:通过indexedDB.open(databaseName, version)方法来打开或创建一个数据库,并指定数据库名称和版本号。
  • 创建对象存储空间:使用db.createObjectStore(storeName, options)方法创建一个对象存储空间,并设置相关的选项,如主键、索引等。
  • 开启事务:使用db.transaction(storeNames, mode)方法开启一个事务,并指定需要操作的对象存储空间和事务模式。
  • 增删改查数据:通过事务对象的方法进行数据的增删改查操作,如objectStore.add(), objectStore.delete(), objectStore.put(), objectStore.get()等。
  • 索引操作:可以使用createIndex()方法为对象存储空间创建索引,以加速查询操作。
    关闭数据库:使用db.close()方法关闭数据库连接。

存储规则

  • Chrome:在Chrome浏览器中,IndexedDB默认的存储限制为无限制,但实际上受到硬件和操作系统的存储空间限制。估计存储上限在几十兆字节到数百兆字节之间。

  • Firefox:在Firefox浏览器中,IndexedDB的存储限制通常为50MB,但可以通过用户授权来增加存储空间,最高可达数百兆字节。

  • Safari:在Safari浏览器中,IndexedDB的存储限制通常为50MB,但也可以通过用户授权来增加存储空间。
    注意

这些存储限制是浏览器默认设置的值,并且不同版本的浏览器可能会有所不同。此外,浏览器还可以要求用户授权来扩大IndexedDB的存储空间。
如果需要存储更大量的数据,可以考虑将数据分割为多个存储对象,或者使用其他数据存储方案,如文件存储或服务器端数据库。
需要了解详细的请前往:indexDB官网

cookie

Cookie是一种在客户端(浏览器)存储数据的机制,它可以用于记录用户的会话状态、用户的喜好设置、页面访问次数等信息。

使用方式:

  • 添加Cookie:可以通过document.cookie属性来添加Cookie,例如:document.cookie = ‘cookie_name=cookie_value; expires=Wed, 28 Oct 2023 12:00:00 GMT; path=/;’。这里将Cookie的名称、值、过期时间和有效路径作为参数传递给document.cookie属性即可。
  • 读取Cookie:可以通过document.cookie属性来读取Cookie,例如:var cookieValue = document.cookie;。document.cookie属性返回当前页面所有的Cookie信息,可以通过解析字符串来获取指定Cookie的值。
  • 删除Cookie:可以通过将Cookie的过期时间设置为一个过去的日期来删除Cookie,例如:document.cookie = ‘cookie_name=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/;’。

最大存储量

需要注意的是每个cookie的存储限制是由浏览器实现和配置所决定的,并且不同浏览器可能有不同的限制。通常情况下,单个cookie的存储大小限制为4kb,这包括cookie的名称,值,属性以及一些额外的属性
一个网站可以设置多个cooke,但是每个域名下的cookie总大小也受到限制,不同浏览器对于单个域名下所有的cookie的总存储大小限制也有所不同,一般在实际kb至数百kb之间
当cookie的总大小超过限制时,浏览器可能会根据特定的策略进行处理。
为了能够确保兼容性和良好的用户体验,建议在开发网站时合理管理cookie的数量和大小,避免食用过多或者过大的cookie,以减少用户浏览器的负担。如果需要存储大量的数据可以采取其他的数据存储方案,如,indexDB数据库

localstorage

LocalStorage是浏览器提供的一种用于在客户端存储数据的Web API。

特点

  • 容量:LocalStorage提供了较大的存储容量,一般为5MB以上。与Cookie相比,LocalStorage可以存储更多的数据。

  • 永久性:LocalStorage中的数据在用户关闭浏览器后仍然保留,下次用户访问网站时可以继续使用。与会话期间的存储方式(如SessionStorage)不同,LocalStorage中的数据没有过期时间。

  • 域名绑定:LocalStorage是基于域名的,存储在特定的域名下,不同域名之间的数据是隔离的,一个域名无法访问另一个域名下的LocalStorage数据。

  • API简单:LocalStorage提供了简单易用的API,包括setItem(key, value)、getItem(key)、removeItem(key)等方法,可以方便地进行数据的存储、读取和删除。

  • 数据类型限制:LocalStorage只能存储字符串类型的数据。如果要存储其他类型的数据,需要先将其转换为字符串形式,再进行存储和读取操作。

用法

// 存储数据
localStorage.setItem('username', 'Alice');

// 读取数据
var username = localStorage.getItem('username');
console.log(username); // 输出:Alice

// 删除数据
localStorage.removeItem('username');

小扩展(localstorage设置失效时长)

localStorage本身不提供直接设置失效时长的功能。与Cookie不同,LocalStorage是持久性存储,数据会一直保存在用户的浏览器中,除非被显式删除或网站清除所有存储的数据。

如果你需要在LocalStorage中实现失效时长的功能,可以结合使用时间戳或过期时间来手动管理数据的有效期。

// 存储数据和过期时间
var data = { username: 'Alice', expires: Date.now() + 24 * 60 * 60 * 1000 }; // 设置有效期为1天
localStorage.setItem('userData', JSON.stringify(data));

// 读取数据并检查是否过期
var storedData = localStorage.getItem('userData');
if (storedData) {
  var parsedData = JSON.parse(storedData);
  if (parsedData.expires > Date.now()) {
    var username = parsedData.username;
    console.log(username); // 输出用户名
  } else {
    console.log('数据已过期');
    localStorage.removeItem('userData'); // 数据过期,进行清除
  }
}

sessionstorage

SessionStorage与LocalStorage类似,是浏览器提供的Web API用于在客户端存储数据的机制。但与LocalStorage不同的是,SessionStorage中存储的数据在用户会话期间有效,当用户关闭浏览器标签页或窗口时,数据会被清除。

特点

  • 存储容量:与LocalStorage相比,SessionStorage的存储容量通常较小,一般为几MB。

  • 生命周期:SessionStorage中存储的数据仅在当前会话期间有效。当用户关闭浏览器标签页或窗口时,数据会被自动清除。

  • 域名绑定:SessionStorage也是基于域名的,存储在特定的域名下。不同域名之间的SessionStorage数据是隔离的,一个域名无法访问另一个域名下的SessionStorage数据。

  • API简单:SessionStorage提供了与LocalStorage类似的简单API,包括setItem(key, value)、getItem(key)、removeItem(key)等方法,用于存储、读取和删除数据。

  • 数据类型限制:SessionStorage同样只能存储字符串类型的数据。如果要存储其他类型的数据,需要先将其转换为字符串形式。
    用法

// 存储数据
sessionStorage.setItem('username', 'Alice');

// 读取数据
var username = sessionStorage.getItem('username');
console.log(username); // 输出:Alice

// 删除数据
sessionStorage.removeItem('username');

配置CDN缓存

CDN是什么

CDN 是构建在数据网络上的一种分布式的内容分发网。 CDN 的作用是采用流媒体服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提升系统支持的并发流数目,减少或避免单点失效带来的不良影响。

为什么要有CDN缓存

减少服务器负载:通过将静态资源(如图像、脚本、样式表等)缓存在CDN节点上,可以减轻源服务器的负载。由于CDN节点位于全球各地,可以更接近用户,使用户能够从最近的节点获取所需的内容,减轻源服务器的压力。

提高页面加载速度:CDN通常具有分布式的节点网络,这些节点分布在不同的地理位置。当用户请求页面时,CDN会根据用户的物理位置,从最近的节点提供内容,减少网络延迟和传输时间,从而加快页面加载速度。

改善用户体验:快速加载的网页可以提供更好的用户体验。通过使用CDN缓存,网页资源可以更快地加载,减少等待时间和加载失败的可能性,提供更流畅的浏览体验。

减少带宽消耗和运营成本:由于CDN可以在全球范围内就近提供内容,可以减少源服务器的带宽消耗,降低了网站运营的成本。

提高可靠性和稳定性:CDN通常具有冗余和故障转移机制,可以在某个节点发生故障时自动切换到其他可用节点。这提高了网站的可靠性和稳定性,减少了服务不可用的风险。

CDN怎么使用?

CDN加载静态资源

nextTick应用原理

nextTick是什么呢?

nextTick是JavaScript中一种异步执行的机制,用于在当前执行栈的末尾添加一个回调函数。在Vue.js等前端框架中,nextTick常用于处理DOM更新后的操作。

官方对其的定义

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM

什么意思呢?

我们可以理解成,Vue 在更新 DOM 时是异步执行的。当数据发生变化,Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新

应用原理

  • 当需要更新DOM时,Vue.js会将DOM更新的操作加入到一个队列中,而不是立即执行。
  • 在当前的执行栈全部执行完毕后,Vue.js会优先处理微任务(Promise、MutationObserver)的回调函数,然后才会执行nextTick的回调函数。
  • 这样可以保证在DOM更新完成后,再执行nextTick的回调函数,以确保操作的准确性和一致性。

常用的开发场景

在数据变化后,立即获取更新后的DOM信息或进行相关操作。
在Vue组件中使用this.$nextTick方法,等待组件更新后执行某些逻辑或操作。
在监听DOM事件后,使用nextTick确保对DOM更新的操作在事件回调之后执行。

diff算法的深度解析

diff算法我分为两大框架来给大家进行讲述,1.vue,2.react

vue2

在Vue2中,虚拟DOM的diff算法采用的是双端比较算法,即同时从新旧节点列表的头部和尾部开始遍历,以找到最长的相同的子序列。

执行步骤
1.遍历新旧节点列表头部,并对比每个节点:

  • 如果新旧节点相同,则继续匹配下一个节点。
  • 如果新旧节点不同,则进入下一步。

2.遍历新旧节点列表尾部,并对比每个节点:

  • 如果新旧节点相同,则继续匹配下一个节点。
  • 如果新旧节点不同,则进入下一步。

3.开始双端比较:

  • 将新旧节点列表的头部和尾部依次配对,共四种组合方式。
  • 对每组节点进行比较:
    • 如果头节点和头节点相同,则继续匹配下一个节点。
    • 如果尾节点和尾节点相同,则继续匹配下一个节点。
    • 如果头节点和尾节点相同,则说明该节点被移动了位置,将该节点移动到正确的位置上。
    • 如果以上三种情况都不符合,则进入下一步。

4.处理剩余节点:

  • 如果新节点列表比旧节点列表长,说明有新增节点,在旧节点列表的末尾插入这些节点。
  • 如果旧节点列表比新节点列表长,说明有删除节点,在旧节点列表中删除这些节点。

总结

在上述过程中,双端比较算法通过同时从头部和尾部开始遍历节点列表,减少了对节点移动的操作,从而提高了效率。同时,Vue还结合了DOM节点的key属性,以进一步优化diff算法的效率。

vue3

在Vue3中,引入了全新的diff算法,称为“静态标记”(Static Marking)和“动态追踪”(Dynamic Tracking)。Vue3的diff算法相对于Vue2有了一定的改进,以提高性能和渲染效率。

执行步骤
1.静态标记:

  • 在编译阶段,Vue3会对模板进行静态分析,并给每个节点添加标记,区分静态节点和动态节点。
  • 静态节点是不会变化的,不需要进行diff比较,可以直接复用。
  • 静态标记可以提前确定哪些节点是稳定的,从而避免不必要的比较和更新。

2.动态追踪

  • 在组件实例初始化时,Vue3会创建一个响应式的Proxy对象代理组件的状态。
  • 当组件状态发生变化时,Vue3可以追踪到具体哪些状态发生了变化。
  • 根据变化的状态,Vue3会更新相关的节点,而不是对整个虚拟DOM树进行比较。

3.基于patchFlag的一个精确标记

  • 在节点上引入PatchFlag,用位运算表示节点类型和属性的变化。
  • 当节点状态发生变化时,通过PatchFlag可以快速地找到发生变化的节点,而不需要对每个节点进行比较。

总结

通过静态标记和动态追踪,Vue3可以更精确地确定哪些节点需要更新,避免了无谓的比较操作。这种优化可以显著提高DOM渲染的性能,在大型应用中尤为明显。此外,Vue3还引入了其他一些性能优化措施,如基于Proxy的响应式系统和模块化编译等,进一步提升了整体性能。

react

React的diff算法也称为“协调”(Reconciliation)算法,主要是通过比较新旧虚拟DOM树的节点差异来进行最小化更新,以提高渲染效率。

react的diff算法主要基于三个规律:

  • DOM 节点的跨层级移动的操作特别少,可以忽略不计
  • 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构
  • 对于同一层级的一组子节点,可以通过唯一的 id 进行区分

react的diff比较层级分为tree,component,element

tree diff

因为上面的三个策略中的第一点, DOM 节点的跨级操作比较少,那么 diff 算法只会对相同层级的 DOM 节点进行比较。如果发现节点不存在 那么会将该节点以及其子节点完全删除,不会再继续比较。如果出现了 DOM 节点的跨层级的移动操作,那么会删除改节点以及其所有的子节点,然后再移动后的位置重新创建。

component diff

如果是同一类型的组件,那么会继续对比 VM 数
如果不是同一类型的组件,那么会将其和其子节点完全替换,不会再进行比对
同一类型的组件,有可能 VM 没有任何的变化,如果可以确定的知道这点,那么就可以节省大量的 diff 时间,所以用户可以设置 shouldComponentUpdate() 来判断是否需要进行 diff 算法。

element diff

当节点处于同一层级的时候时,有三种操作:INSERT_MAKEUP插入、 MOVE_EXISTING 移动、 REMOVE_NODE 删除
这里 React 有一个优化策略,对于同一层级的同组子节点,添加唯一的 key 进行区分。这样的话,就可以判断出来是否是移动节点。通过 key 发现新旧集合中的节点都是相同的节点,就只需要进行移动操作就可以。

后言

创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力

你可能感兴趣的:(前端面试,前端,vue.js)