# 前端知识点

58 阅读9分钟

防抖

事件触发后,只有在规定的时间内没有再次触发,处理函数才会执行。如果在规定时间内事件再次触发,则重新计时。

防抖可以有效避免频繁触发事件时,执行过多无用的操作。

 

应用场景:

用户输入搜索框时:当用户停止输入一段时间后再发起搜索请求,防止每个输入都触发搜索操作。

浏览器窗口大小调整:用户停止调整浏览器窗口大小后再执行调整后的操作,防止窗口每次变化都触发大量重绘。

 

实现:

当事件被触发时,设置一个定时器。如果在定时器结束前再次触发事件,清除之前的定时器,重新设置新定时器。当定时器结束后,才执行回调函数。

function debounce(func, delay) {

let timer = null;

return function (...args) {

if (timer) clearTimeout(timer);

timer = setTimeout(() => {

func.apply(this, args);

}, delay);

};}

节流

保证一个函数在一定时间内只执行一次,即使在这段时间内事件被频繁触发。

节流可以限制函数的执行频率,适合那些需要定期执行的操作。

 

应用场景:

滚动事件:当用户滚动页面时,每隔一段时间触发一次回调,防止滚动时每次触发滚动事件都导致大量计算。

按钮点击事件:防止按钮被用户频繁点击,导致多次触发事件。

 

实现:

设置一个变量,事件触发后,变量设置为true,并开始计时,计时未结束期间的方法调用不触发事件,至计时结束,变量设置为false;

function throttle(func, limit) {

let inThrottle;

return function (...args) {

if (!inThrottle) {

func.apply(this, args);

inThrottle = true;

setTimeout(() => {

inThrottle = false;

}, limit);

}

};}

浏览器缓存机制

浏览器为了提高网络请求速度,减少服务器请求,节省网络带宽,通常会把页面需要的部分资源如(js脚本,html文件,css、图片等静态资源)缓存在本地

缓存类型

内存缓存:存储速度最快,存储在计算机内存中,存储量小,浏览器关闭后清空

磁盘缓存:存储速度低于内存缓存,存储在硬盘中,存储量大,不会自动清空可以在浏览器设置中手动清空

应用缓存: 更高级的缓存机制主要用于离线应用,允许开发者指定哪些资源需要被缓存,以便用户在没有网络的情况下也能访问这些资源。应用缓存由HTML5引入,但已被Service Workers逐渐取代。

servers worker:

● 是一种运行在浏览器后台的脚本,通过 JavaScript 编程实现

● 是一种独立于页面的线程

● 可以拦截网络请求,并根据开发者定义的逻辑决定是使用缓存还是从网络获取资源

● 允许开发者在客户端实现复杂的缓存策略,例如离线支持、动态缓存更新等

● 开发者可以通过 JavaScript 完全控制缓存逻辑,包括缓存的内容、缓存的更新策略、请求的拦截等。

 

 

 

主要功能:
拦截网络请求:

Service Worker 可以拦截浏览器发出的所有网络请求(包括 HTML、CSS、JavaScript、图片等),并根据开发者定义的逻辑决定是直接从网络获取资源,还是从缓存中返回资源。

这种机制使得开发者可以实现复杂的缓存策略,例如:

缓存优先策略:先从缓存中查找资源,如果缓存中没有,则从网络获取并更新缓存。

网络优先策略:先尝试从网络获取资源,如果网络请求失败,则从缓存中返回资源。

自定义策略:根据资源类型、网络状况、用户行为等因素,动态调整缓存策略。

离线支持:

通过 Service Worker,开发者可以预先缓存一些关键资源(如 HTML 文件、CSS 文件、JavaScript 文件、图片等),使得用户即使在离线状态下也能访问网页的基本功能。

例如,一个新闻网站可以通过 Service Worker 缓存一些热门文章的页面,用户在离线时仍然可以阅读这些文章。

消息推送:

Service Worker 支持消息推送功能,即使用户没有打开网页,也可以通过推送通知向用户发送消息。这种功能常用于即时通讯应用、新闻推送、日程提醒等场景。

后台同步:

Service Worker 可以在后台同步数据,即使用户没有打开网页,也可以在设备联网时自动同步数据。

例如,一个待办事项应用可以在后台自动同步用户的待办事项数据。

 

应用场景

● 适用于需要高度定制化缓存策略的场景,例如离线支持、动态缓存更新、消息推送等。

● 适用于复杂的 Web 应用,如单页面应用(SPA)、离线应用等。

 

缓存类型策略 强缓存/协商缓存

● 适用于简单的静态资源缓存,例如图片、CSS 文件、JavaScript 文件等。

● 适用于大多数 Web 应用的静态内容优化。

● 开发者只能通过 HTTP 响应头设置缓存策略,浏览器会根据这些策略自动决定是否使用缓存。

强缓存

依赖 Cache-Control 和 Expires,直接使用本地缓存,无需与服务器通信。适合静态资源和长时间不变的文件。

它主要依赖于HTTP响应头中的Cache-Control和Expires字段。

Cache-Control:用于控制缓存的策略,例如max-age表示资源在本地缓存的有效时间。

Expires:表示资源的过期时间,是一个绝对时间戳。

如果资源在强缓存有效期内,浏览器会直接使用本地缓存,不会向服务器发送任何请求。

强缓存存储的数据

静态资源文件:如图片(.jpg、.png)、CSS 文件(.css)、JavaScript 文件(.js)等。这些文件通常在一段时间内不会改变,适合设置较长的强缓存时间。

HTML 文件:某些静态页面也可以设置强缓存,但需要谨慎,因为 HTML 文件内容可能会频繁更新。

字体文件:如 .woff、.ttf 等,这些文件通常不会频繁更新,适合强缓存。

 

 

协商缓存(Negotiated Cache)

协商缓存是当强缓存失效后,浏览器会向服务器发送请求,通过验证资源是否更新来决定是否使用本地缓存,依赖 Last-Modified 和 ETag,与服务器进行验证,适合动态内容和可能会更新的静态资源。

Last-Modified

这是一个时间戳,表示资源最后修改的时间。服务器会在响应头中返回 Last-Modified,浏览器在后续请求中会通过 If-Modified-Since 请求头将这个时间戳发送给服务器。如果服务器发现资源在这个时间戳之后没有被修改,就会返回 304 状态码,浏览器继续使用本地缓存。

ETag

这是一个唯一标识符,用于标识资源的版本。服务器会在响应头中返回 ETag,浏览器在后续请求中会通过 If-None-Match 请求头将这个标识符发送给服务器。如果服务器发现资源的 ETag 没有变化,就会返回 304 状态码。

 协商缓存存储的数据

动态内容:如用户个人信息页面、新闻网站的新闻列表等。这些内容可能会频繁更新,但又不适合完全不缓存,因此适合使用协商缓存。

部分静态资源:对于一些可能会更新的静态资源(如某些配置文件),也可以使用协商缓存来减少不必要的数据传输。

【如果资源未被修改,服务器会返回304 Not Modified状态码,浏览器会使用本地缓存。

如果资源被修改,服务器会返回新的资源和200 OK状态码,浏览器会更新本地缓存。】

 

 

重绘

浏览器重新绘制页面的一部分或全部;相对轻量级,只改变元素的样式外观(颜色、背景、边框),不改变DOM元素的几何尺寸(宽、高、位置)。

例如:修改color、background、opacity样式

重排(回流)

浏览器重新计算DOM元素的几何尺寸、位置,并重新渲染页面及布局,相比重绘更加耗性能。

重排必会触发重绘,频繁重排会使页面卡顿。

例如:改变元素的 width、height、padding、margin、font-size 等样式。

改变元素的 display 属性。

添加、删除或修改 DOM 元素。

 

优化建议:

减少 DOM 操作,批量修改样式,使用虚拟 DOM,优化滚动和动画。

减少对元素几何尺寸的修改:

使用 transform 和 opacity 替代 top、left 等样式,因为 transform 和 opacity 不会触发重排。

 

赋值、拷贝

引用赋值:

a=b;

浅拷贝:

...{} ,Object.assign({},{})

深拷贝:

structuredClone

a= structuredClone (b);

性能更高,更广泛的数据类型支持,由现代浏览器提供的原生 JavaScript 方法,用于实现深拷贝,是作为 Web API 的一部分提供的,虽然可以通过 window.structuredClone 访问 structuredClone,但它本身并不是 Window 接口的一部分,而是一个独立的全局函数。

基于 HTML 标准中的结构化克隆算法,该算法最初是为了满足 Web Workers 中数据传输的需求而设计的,后来被整合到 Web API 中,成为浏览器原生支持的深拷贝方法

 

支持:

基础数据类型(字符串、数字、布尔值、null、undefined)。

对象和数组。

特殊对象类型(如; Date、Map、Set、RegExp 等)。

循环引用(能够正确处理循环引用)。

二进制数据类型(如 ArrayBuffer、Buffer 等)。

 

不支持:

● 函数:无法克隆函数。

● DOM 节点:无法克隆 DOM 元素。

● 属性描述符、getter 和 setter:不会保留这些元数据。

● 对象原型:不会保留原型链。

 

JSON.parse(JSON.stringify())

a= JSON.parse(JSON.stringify(b))

 

支持:

只能处理 JSON 兼容的数据类型,包括对象、数组、字符串、数字、布尔值、null

 

不支持:

● 函数 :会被忽略。undefined :会被忽略。

● 循环引用 :会报错。

● 特殊对象类型 :如 Date、RegExp、Map、Set、Buffer 等会被转换为普通对象或字符串。

 

手动编写function

函数、特殊引用数据类型(date、)等无法直接深拷贝需要通过手写函数循环️属性判断原型类型,新增对应类型数据用于接收被属性值返回的value信息。