动态组件是一种可以根据数据变化而动态加载不同组件的方式。使用动态组件可以有效地减少代码复杂度,提高组件的复用性和灵活性。
动态组件通过一个特殊的属性is来实现动态加载,is的值可以是组件的名称或组件对象。
KeepAlive是一个内置组件,它的功能是在多个组件间动态切换时缓存被移除的组件实例。用于缓存动态组件实例并避免多次渲染的内置组件。通过使用 KeepAlive 组件包裹动态组件,可以实现组件的缓存、复用、提高组件性能等功能。
KeepAlive 的使用方式非常简单,只需要将动态组件包裹在 KeepAlive 标签中就可以了
vue3中的动态组件和KeepAlive组件_vue3.0 动态组件_九仞山的博客-CSDN博客
原理:
1 指令绑定表单元素的 value 属性(例如 input、textarea、select 等)到 Vue 实例中的一个属性。
2 Vue.js 监听该元素的 oninput 事件,并通过新旧值的比较来确定数据是否发生了变化。
3 如果数据已经发生变化,则更新 Vue 实例中绑定的属性值,从而实现数据的双向绑定
其实就是 表单元素 input 处理事件 使 value的值 绑定到 一个响应式数据上
再把 这个响应式数据显示使用 V-bind 帮定到 input 上
v-model 是 Vue.js 框架提供的一个指令,用于实现表单元素与 Vue 实例数据之间的双向数据绑定。
它的原理是:
如果用户在表单元素中按下回车键或者失去焦点,则该元素的 onchange 事件也会触发。Vue.js 同样监听该事件,并在事件处理函数中将表单元素的值同步到 Vue 实例中。
Vue3
v-model本质上只是一颗语法糖,真正的实现靠的还是v-bind和oninput事件。
v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
【1】闭包引起的内存泄露
解决这个问题的方法是在不需要的时候手动解除对外部变量的引用 赋null
【2】意外的全局变量引起的内存泄露
在JavaScript中,如果没有使用var、let或const关键字声明变量,它将成为全局变量,即使它在函数内部声明。如果创建了一个全局变量,但没有及时释放它,那么它将一直存在于内存中,可能导致内存泄漏。
【前端】内存泄露及解决方案_前端内存泄漏_Frenki_21的博客-CSDN博客
浅比一下,Less和Sass的区别_less sass_码农桃子的博客-CSDN博客
less和sass_sass和less_xinxin_zhu的博客-CSDN博客
(1) 解析URL
(2) 缓存判断
(3) DNS解析
(4) 获取MAC地址
(5) TCP三次握手
(6) HTTPS握手
(7) 返回数据
(8) 页面渲染
(9) TCP四次挥手
首先,浏览器会对URL进行解析,分析所需要使用的传输协议(例如HTTP或HTTPS)和请求的资源的路径。如果输入的URL中的协议或主机名不合法,浏览器会将该内容传递给搜索引擎进行搜索。
接下来,浏览器会检查URL中是否包含非法字符。如果有非法字符,浏览器会对这些字符进行转义,然后继续下一步骤。
浏览器会将解析后的URL发送给DNS解析器。DNS解析器负责将网址转换为相应的IP地址。DNS解析的过程是通过查询本地域名服务器、根域名服务器、顶级域名服务器等来完成的。这个过程是从右向左进行的,从顶级域名开始逐级向下查询,直到获得目标网址对应的IP地址。
一旦获得了目标网址的IP地址,浏览器会使用该IP地址与服务器建立连接,并发送HTTP请求以获取网页内容。
服务器接收到浏览器发送的HTTP请求后,会根据请求的资源路径查找对应的文件或数据,并将其作为HTTP响应返回给浏览器。
浏览器接收到服务器返回的HTTP响应后,会解析响应内容,并根据响应中的信息渲染网页,最终将网页显示在用户的浏览器窗口中。
所以,当在地址栏里输入一个地址并按下回车键后,浏览器会经过URL解析、DNS解析、建立连接、发送请求和接收响应等一系列步骤,最终将网页显示给用户。
按照渲染的时间顺序,流水线可分为如下几个子阶段:构建 DOM 树
、样式计算
、布局阶段
、分层
、栅格化
和显示
。
浏览器从网络或硬盘中获得HTML字节数据后会经过一个流程将字节解析为DOM树,先将HTML的原始字节数据转换为文件指定编码的字符,然后浏览器会根据HTML规范来将字符串转换成各种令牌标签,如html、body等。最终解析成一个树状的对象模型,就是dom树;
获取css,获取style标签内的css、或者内嵌的css,或者当HTML代码遇见标签时,浏览器会发送请求获得该标签中标记的CSS,当渲染引擎接收到 CSS 文本时,会执行一个转换操作,将 CSS 文本转换为浏览器可以理解的styleSheets
创建布局树,遍历 DOM 树中的所有可见节点,并把这些节点加到布局中;而不可见的节点会被布局树忽略掉,如 head 标签下面的全部内容,再比如 body.p.span 这个元素,因为它的属性包含 dispaly:none,所以这个元素也没有被包进布局树。最后计算 DOM 元素的布局信息,使其都保存在布局树中。布局完成过程中,如果有js操作或者其他操作,对元素的颜色,背景等作出改变就会引起重绘,如果有对元素的大小、定位等有改变则会引起回流。
因为页面中有很多复杂的效果,如一些复杂的 3D 变换、页面滚动,或者使用 z-indexing 做 z 轴排序等,为了更加方便地实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一棵对应的图层树。
渲染引擎实现图层的绘制,把一个图层的绘制拆分成很多小的绘制指令然后再把这些指令按照顺序组成一个待绘制列表,当图层的绘制列表准备好之后,主线程会把该绘制列表提交给合成线程,合成线程会将图层划分为图块,然后按照视口附近的图块来优先生成位图(实际生成位图的操作是由栅格化来执行的。所谓栅格化,是指将图块转换为位图)
一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令,然后将该命令提交给浏览器进程,浏览器最后进行显示。
其中解析HTML的时候会将HTML文档转换为DOM树,构建render树的时候会将DOM树转换为更加结构化的渲染树,布局和绘制render树的时候会将渲染树转换为可见的像素画面。
浏览器相关原理(面试题)详细总结二 - 掘金
浏览器从关闭状态进行启动,然后新开 1 个页面至少需要 1 个网络进程、1 个浏览器进程、1 个 GPU 进程以及 1 个渲染进程,共 4 个进程;后续再新开标签页,浏览器、网络进程、GPU进程是共享的,不会重新启动,如果2个页面属于同一站点的话,并且从a页面中打开的b页面,那么他们也会共用一个渲染进程,否则新开一个渲染进程。
最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程。
浏览器进程
:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。渲染进程
:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下。GPU 进程
:其实,Chrome 刚开始发布的时候是没有 GPU 进程的。而 GPU 的使用初衷是为了实现 3D CSS 的效果,只是随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制,这使得 GPU 成为浏览器普遍的需求。最后,Chrome 在其多进程架构上也引入了 GPU 进程。网络进程
:主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程。插件进程
:主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。进行三次握手,建立TCP连接。
ACK:此标志表示应答域有效,就是说前面所说的TCP应答号将会包含在TCP数据包中;有两个取值:0和1,为1的时候表示应答域有效,反之为0。 TCP协议规定,只有ACK=1时有效,也规定连接建立后所有发送的报文的ACK必须为1。 SYN(SYNchronization) : 在连接建立时用来同步序号。当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1. 因此, SYN置1就表示这是一个连接请求或连接接受报文。 FIN (finis)即完,终结的意思, 用来释放一个连接。当 FIN = 1 时,表明此报文段的发送方的数据已经发送完毕,并要求释放连接。
发送HTTP请求,服务器处理请求,返回响应结果
TCP连接建立后,浏览器就可以利用HTTP/HTTPS协议向服务器发送请求了。服务器接受到请求,就解析请求头,如果头部有缓存相关信息如if-none-match与if-modified-since,则验证缓存是否有效,若有效则返回状态码为304,若无效则重新返回资源,状态码为200.
如果一个请求url的 协议、域名、端口三者之间任意一个与当前页面url不同就会产生跨域的现象。
同源策略,是一种网页的安全协议。同源:同协议,同域名,同端口。
http;// www. aaa.com:8080/index/vue.js ,协议子域名 主域名 端口号资源。
同源策略是浏览器的核心,如果没有这个策略就会遭受网络攻击。
主要指的就是协议+域名+端口号三者一致,若其中一个不一样则不是同源,会产生跨域。
三个允许跨域加载资源的标签: img、 link、 script 跨域是可以发送请求,后端也会正常返回结果,只不过这个结果被浏览器拦截了!
之前做前端适配,要么通过使用css的media媒体查询,要么通过获取可视宽度按照想要的比例设置文档根字体大小。无意间在网上看到一种新的适配插件,postcss-px-to-viewport,就是用viewport(vw)单位,viewport单位越来越受到众多浏览器的支持,postcss-px-to-viewport,将px单位按照相应的配置自动转换成需要的viewport单位。
使用插件:postcss-px-to-viewport。可使用npm、yarn安装:npm install -D postcss-px-to-viewport 或 yarn add -D postcss-px-to-viewport 。
【 什么是BFC?】BFC的全称是block-formatting-context, 对应其中文翻译就是块级格式上下文,它是一个独立的渲染区域,我们可以把BFC理解为,一个封闭的容器,内部的元素无论怎么变化都不会影响到外部,容器内的样式布局自然也不会受到外界的影响。
【BFC内部规则】1BFC它就是一个块级元素,块级元素会在垂直方向上一个接一个的往下排列,2BFC就是页面中的一个隔离的独立容器,容器里的标签不会影响到外部标签,3BFC区域不会与浮动的容器发生重叠,4属于同一个BFC的两个相邻元素的外边距会发生重叠,垂直方向的距离由两个元素中margin的较大的值决定,5计算BFC的高度时,浮动元素也会参与计算。
【如何触发BFC? 】通过添加CSS属性,就可以触发,overflow:hidden;除了visible以外的值,position:absolute/fixed;display:inline-block/flex;
axios是一个封装好的独立的ajax请求库, 基于Promise。支持在浏览器和Node中使用。
axios封装的步骤:
在根目录创建 utils 文件夹
创建 request.js文件
在request.js里引入 axios
配置 基本路径和超时时间
配置请求拦截和响应拦截
在请求拦截里可以放 loading 和 token
在响应拦截中 可以 清除 loading 还有处理错误编码字典
最后把我们封装的 axios 实例 导出
互联网中的数据是通过数据包来传输的。数据包要在互联网上进行传输,就要符合网际协议(IP),互联网上不同的在线设备都有唯一的地址,地址只是一个数字,只要知道这个具体的地址,就可以往这里发送信息。
如果要想把一个数据包从主机 A 发送给主机 B,那么在传输之前,数据包上会被附加上主机 B 的 IP 地址信息,这样在传输过程中才能正确寻址。额外地,数据包上还会附加上主机 A 本身的 IP 地址,有了这些信息主机 B 才可以回复信息给主机 A。这些附加的信息会被装进一个叫 IP 头的数据结构里。IP 头是 IP 数据包开头的信息,包含 IP 版本、源 IP 地址、目标 IP 地址、生存时间等信息。
IP 是非常底层的协议,只负责把数据包传送到对方电脑,但是对方电脑并不知道把数据包交给哪个程序,是交给浏览器还是交给王者荣耀?因此,需要基于 IP 之上开发能和应用打交道的协议,最常见的是用户数据包协议(User Datagram Protocol),简称UDP
和传输控制协议(Transmission Control Protocol),简称TCP
.
基本传输过程为:
UDP 头
,组成新的 UDP 数据包,再将新的 UDP 数据包交给网络层3. UDP和TCP有什么区别?
主要原因是第一次加载页面过程中,缓存了一些耗时的数据。 那么,哪些数据会被缓存呢?
主要就是在浏览器本地把对应的 IP 和域名关联起来,这样在进行DNS解析的时候就很快。
是指存在内存中的缓存。从优先级上来说,它是浏览器最先尝试去命中的一种缓存。从效率上来说,它是响应速度最快的一种缓存。 内存缓存是快的,也是“短命”的。它和渲染进程“生死相依”,当进程结束后,也就是 tab 关闭以后,内存里的数据也将不复存在。
浏览器缓存
浏览器缓存,也称Http缓存,分为强缓存和协商缓存。优先级较高的是强缓存,在命中强缓存失败的情况下,才会走协商缓存。
强缓存
强缓存
是利用 http 头中的 Expires
和 Cache-Control
两个字段来控制的。强缓存中,当请求再次发出时,浏览器会根据其中的 expires 和 cache-control 判断目标资源是否“命中”强缓存,若命中则直接从缓存中获取资源,不会再与服务端发生通信。
实现强缓存,过去我们一直用expires。当服务器返回响应时,在 Response Headers 中将过期时间写入 expires 字段。像这样
expires: Wed, 12 Sep 2019 06:12:18 GMT
可以看到,expires 是一个时间戳,接下来如果我们试图再次向服务器请求资源,浏览器就会先对比本地时间和 expires 的时间戳,如果本地时间小于 expires 设定的过期时间,那么就直接去缓存中取这个资源。
从这样的描述中大家也不难猜测,expires 是有问题的,它最大的问题在于对“本地时间”的依赖。如果服务端和客户端的时间设置可能不同,或者我直接手动去把客户端的时间改掉,那么 expires 将无法达到我们的预期。
考虑到 expires 的局限性,HTTP1.1 新增了Cache-Control
字段来完成 expires 的任务。expires 能做的事情,Cache-Control 都能做;expires 完成不了的事情,Cache-Control 也能做。因此,Cache-Control 可以视作是 expires 的完全替代方案。在当下的前端实践里,我们继续使用 expires 的唯一目的就是向下兼容。
cache-control: max-age=31536000
在 Cache-Control 中,我们通过max-age来控制资源的有效期。max-age 不是一个时间戳,而是一个时间长度。在本例中,max-age 是 31536000 秒,它意味着该资源在 31536000 秒以内都是有效的,完美地规避了时间戳带来的潜在问题。
Cache-Control 相对于 expires 更加准确,它的优先级也更高。当 Cache-Control 与 expires 同时出现时,我们以 Cache-Control 为准。
协商缓存
协商缓存依赖于服务端与浏览器之间的通信。协商缓存机制下,浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求、下载完整的响应,还是从本地获取缓存的资源。如果服务端提示缓存资源未改动(Not Modified),资源会被重定向到浏览器缓存,这种情况下网络请求对应的状态码是 304。
协商缓存的实现,从 Last-Modified
到 Etag
,Last-Modified 是一个时间戳,如果我们启用了协商缓存,它会在首次请求时随着 Response Headers 返回:
Last-Modified: Fri, 27 Oct 2017 06:35:57 GMT
随后我们每次请求时,会带上一个叫 If-Modified-Since 的时间戳字段,它的值正是上一次 response 返回给它的 last-modified 值:
If-Modified-Since: Fri, 27 Oct 2017 06:35:57 GMT
服务器接收到这个时间戳后,会比对该时间戳和资源在服务器上的最后修改时间是否一致,从而判断资源是否发生了变化。如果发生了变化,就会返回一个完整的响应内容,并在 Response Headers 中添加新的 Last-Modified 值;否则,返回如上图的 304 响应,Response Headers 不会再添加 Last-Modified 字段。
Service Worker 是一种独立于主线程之外的 Javascript 线程。它脱离于浏览器窗体,因此无法直接访问 DOM。这样独立的个性使得 Service Worker 的“个人行为”无法干扰页面的性能,这个“幕后工作者”可以帮我们实现离线缓存、消息推送和网络代理等功能。我们借助 Service worker 实现的离线缓存就称为 Service Worker Cache。
Service Worker 的生命周期包括 install、active、working 三个阶段。一旦 Service Worker 被 install,它将始终存在,只会在 active 与 working 之间切换,除非我们主动终止它。这是它可以用来实现离线存储的重要先决条件.
Push Cache 是指 HTTP2 在 server push 阶段存在的缓存。这块的知识比较新,应用也还处于萌芽阶段,应用范围有限不代表不重要——HTTP2 是趋势、是未来。在它还未被推而广之的此时此刻,我仍希望大家能对 Push Cache 的关键特性有所了解:
1. 箭头函数比普通函数在写法上更加简洁。
(1)如果没有参数,就直接写一个空括号即可
(2) 如果只有一个参数,可以省去参数的括号
(3)如果有多个参数,用逗号分割
(4)如果函数体的返回值只有一句,可以省略大括号
2. 箭头函数没有自己的this
箭头函数不会创建自己的this, 所以它没有自己的this,它只会在自己作用域的上一层继承this。所以箭头函数中this的指向在它在定义时已经确定了,之后不会改变。
3. 箭头函数继承来的this指向永远不会改变,call()、apply()、bind()等方法不能改变箭头函数中this的指向 。
var id = 'GLOBAL';
var obj = {
id: 'OBJ',
a: function(){
console.log(this.id);
},
b: () => {
console.log(this.id);
}
};
obj.a(); // 'OBJ'
obj.b(); // 'GLOBAL'
new obj.a() // undefined
new obj.b() // Uncaught TypeError: obj.b is not a constructor
对象obj的方法b是使用箭头函数定义的,这个函数中的this就永远指向它定义时所处的全局执行环境中的this,即便这个函数是作为对象obj的方法调用,this依旧指向Window对象。需要注意,定义对象的大括号{ }是无法形成一个单独的执行环境的,它依旧是处于全局执行环境中。
4. 箭头函数不能作为构造函数使用
由于箭头函数时没有自己的this,且this指向外层的执行环境,且不能改变指向,所以不能当做构造函数使用。
5. 箭头函数没有自己的arguments
箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是它外层函数的arguments值。
6. 箭头函数没有prototype
7. 箭头函数的this指向哪⾥?
箭头函数不同于传统JavaScript中的函数,箭头函数并没有属于⾃⼰的this,它所谓的this是捕获其所在上下⽂的 this 值,作为⾃⼰的 this 值,并且由于没有属于⾃⼰的this,所以是不会被new调⽤的,这个所谓的this也不会被改变。
1 通过Array.from方法来实现转换
Array.from(arrayLike)
2 通过call调用数组的slice方法来实现转换
Array.prototype.slice.call(arrayLike)
3 通过call调用数组的splice方法来实现转换
Array.prototype.splice.call(arrayLike,0)
4 通过apply调用数组的concat方法来实现转换
Array.prototype.concat.apply([],arrayLike)
2023前端面试题汇总_下雪不过冬天的博客-CSDN博客
性能优化 :
当时项目树节点数量居多 节点间通信 节点组件业务功能代码冗余, 组件间通讯复杂 , 光场景匹配就写好多代码 ,虽然 , 只使用 Vuex /pinia 已经不能满足
后台推送 ,拖拽判定 ,新建子元素 ,新建关系
使用 EventBus 进行拆解与 解耦 提取 共公代码 ,将 业务代码进行抽离 ,优化看 树展开操作的 渲染时间以及相应速度 ,
EventBus 与Pinia相结合 进行版
页面缓存 :
【Vue3】电商网站吸顶功能_itpeilibo的博客-CSDN博客
遵循法则:STAR法则
当面试官给你提出:“开发Vue项目都遇到过哪些问题怎么解决的?”的时候不能单纯的从技术层面出发回答,而是可以采用STAR原则去讲解,它是结构化面试当中非常重要的一个理论,既可以帮助你有效地梳理出答案,也可以回答出面试官想知道同时你也展示的地方。
STAR原则是四个英文单词的首字母组合,分别是:
Situation(情景) 描述所从事岗位期间曾经做过的某件重要的且可以当作面试官考评标准的事件的所发生的背景状况。简单来说就是你的项目是在什么背景下制作的,要在什么情况下应用。
比如:为了用户可以更好的体验xxx,公司研发了xxx,该项目主要针对xx用户,由xxx和xxx系统或架构组成,由xx语言编写等等。
Task(目标) 即是要考察应聘者在其背景环境中所执行的任务与角色,从而考察该应聘者是否做过其描述的 职位及其是否具备该岗位的相应能力。也就是介绍你在该项目中主要负责什么,目标是什么。
比如:我主要负责xxx,它是用来xxx的,并且我负责报告的设计以及最终评审通过等。
Action(行动)
比如:使用xx管理用例的编写,通过xx管理代码和版本,使用xx工具做了什么,我对该模块的工作使用了xx技术等等。
Result(结果)比较简单和宽泛。其实就是你通过行动得出了什么结果
比如:编写了xx个用例,发现了xx个bug,编写了xx行代码,利用xx工具做的测试结果,开发成果,评审结果等。
vue项目总结,项目期间遇到的问题、难点等。【暂停更新】_vue项目难点及解决方法_柠檬不萌只是酸i的博客-CSDN博客
【Vue3】电商网站吸顶功能_itpeilibo的博客-CSDN博客
三个角度(页面渲染,打包优化,总体优化
)
页面渲染:
懒加载:预加载:
懒加载/预加载资源
减少页面重绘(repaint)和回流(reflow)
图片压缩, 雪碧图
字体包压缩 使用font-spider
字蛛将要使用到的文字提取出来
打包优化
. webpack优化resolve.alias配置(vite同理)
webpack优化resolve.extensions配置(vite同理)
webpack缩小loader范围
tree shaking
vite关闭一些打包配置项
总体优化
SSR服务端渲染
开启 gzip 压缩
Brotli 算法压缩
vite项目开启 brotli
压缩
6. 组件按需引入
7. 动态加载
8. 组件异步加载
9. 路由懒加载
10. CDN内容分发
12. DNS预解析
13. web worker
2023 前端性能优化清单 - 掘金
1 vuex数据持久化存储 使用 vuex-persist vuex-persistedstate
npm i vuex-persistedstate --save 或者 yarn add vuex-persistedstate
2 pinia数据持久化存储
使用pinia-plugin-persist插件
npm install pinia-plugin-persist 或者 yarn add pinia-plugin-persist
vue3全家桶之vuex和pinia持久化存储基础(二)_vue3 数据存储_追逐梦想之路_随笔的博客-CSDN博客
2023前端面试题合集(附答案)持续更新中..._前端面试问题_前端小渣渣(LZ集团)的博客-CSDN博客
2023前端面试题汇总_下雪不过冬天的博客-CSDN博客
2023最全最新前端面试题(附加解析)_前端最新面试题_耀南.的博客-CSDN博客
2023高频前端面试题总结(附答案)_三角鹿的博客-CSDN博客
浏览器相关原理(面试题)详细总结一 - 掘金【查漏补缺】那些漏掉的基础考点知识 - 掘金