网络相关:
2.osi七层网络模型是什么
开放式系统互联。其各个层次的划分遵循下列原则:
(1)同一层中的各网络节点都有相同的层次结构,具有同样的功能。
(2)同一节点内相邻层之间通过接口进行通信。
(3)七层结构中的每一层使用下一层提供的服务,并且向其上层提供服务。
(4)不同节点的同等层按照协议实现对等层之间的通信。
———————————————————————————————————————————————
物 数 网 传 会 表 应
3.http工作在哪一层(应用层)https(传输层) 区别 https 的加密过程 怎么进行加密的
虽然HTTP和HTTPS都是基于TCP/IP协议栈的应用层协议,但HTTPS通过引入SSL/TLS协议,在传输层提供了加密和安全性保障,使得通信内容更加安全可靠。
因为http是明文传输,内容可能被窃听,无法证明报文的完整,而且通信方的身份有可能遭遇伪装,所以要对http进行ssl加密,也就是https, https是这样解决http的问题的
Https引入了
对称加密:加密和解密使用一个秘钥
非对称加密:他就有两个秘钥了,一个是公开密钥,一个是私有密钥。
公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
注意:对称加密加密速度快,非对称加密速度慢
证书:
总结:!!!!!
第一组(非对称加密): 用于校验证书是否被篡改. 服务器持有私钥(私钥在注册证书时获得), 客户端持有公钥(操作系统包含了可信任的 CA 认证机构有哪些, 同时持有对应的公钥). 服务器使用这个私钥对证书的签名进行加密. 客户端通过这个公钥解密获取到证书的签名, 从而校验证书内容是否是篡改过。
第二组(非对称加密): 用于协商生成对称加密的密钥. 服务器生成这组 私钥-公钥 对, 然后通过证书把公钥传递给客户端. 然后客户端用这个公钥给生成的对称加密的密钥加密, 传输给服务器, 服务器通过私钥解密获取到对称加密密钥。
第三组(对称加密): 客户端和服务器后续传输的数据都通过这个对称密钥加密解密。
————————————————
4.http各种版本的区别
HTTP版本怎么选?
如果使用HTTPS那就2.0甚至是3.0,如果没有使用HTTPS那就1.1,而1.0估计是没人用了
HTTP协议即超文本传送协议,HTTP协议是建立在TCP协议之上的一种应用。
HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。
- Http1.0
HTTP1.0默认使用 Connection:cloose,浏览器每次请求都需要与服务器建立一个 TCP 连接,服务器处理完成后立即断开 TCP 连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。
- Http1.1
keep-alive(长连接),避免了连接建立和释放的开销,减少服务器压力,可以同时并行多个请求,不需要一个接一个的等待响应;通过 Content-Length 字段来判断当前请求的数据是否已经全部接受。不允许同时存在两个并行的响应。
但是他也有缺段,就是高延迟,效率低
- Http2.0
基于SPDY,目标是在用户和网站直接只用一个连接。
1)二进制传输
http2.0将请求和响应数据分割为更小的帧,并且它们采用二进制编码(http1.0基于文本格式)。多个帧之间可以乱序发送,根据帧首部的流表示可以重新组装。
(2)Header压缩
Http2.0开发了专门的“HPACK”算法,大大压缩了Header信息。
(3)多路复用
http2.0中引入了多路复用技术,很好的解决了浏览器限制同一个域名下的请求数量的问题
多路复用技术可以只通过一个TCP链接就可以传输所有的请求数据
(4)服务端推送
HTTP2.0在一定程度上改不了传统的“请求-应答”工作模式,服务器不再完全被动地响应请求,也可以新建“流”主动向客户端发送消息。(例如,浏览器在刚请求html的时候就提前把可能会用到的JS,CSS文件发送给客户端,减少等待延迟,这被称为“服务端推送”)
————————————————
HTTP2.0缺点
(1)TCP以及TCP+TLS建立连接的延迟(握手延迟)
(2)HTTP/2.0 虽然支持多路复用,允许多个请求在同一个 TCP 连接上并行传输,但是在遇到任何一个数据包丢失时,整个 TCP 连接的数据都会受到影响,直到丢失的包被重新传输成功,这就是所谓的队头阻塞。
因为HTTP2.0存在这些缺点,所以出现了HTTP3.0。
————————————————
Http3.0
基于UDP协议的“QUIC”协议,让HTTP跑在QUIC上而不是TCP上。从而解决了“队头阻塞”的问题。
因为 QUIC 基于 UDP 实现,并引入了自己的流控制、拥塞控制以及可靠性传输的机制。
-
独立流的传输:在 QUIC 中,每个请求都是在独立的流上进行的,这样即使某个流上的数据包丢失,也只会影响该流自己的数据传输,而不会影响到其他并行流的传输。
-
快速重传和恢复:QUIC 协议支持更快速的数据包重传机制,减少了因数据包丢失而等待重传的时间,从而提高了整体的数据传输效率。
-
连接迁移:QUIC 支持无缝的连接迁移功能,即使用户的网络环境发生变化(例如,从 Wi-Fi 切换到移动网络),也不会影响已经建立的连接,减少了重新建立连接的需要。
特点:
(1)实现了快速握手功能(QUIC基于UDP,UDP是面向无连接的,不需要握手和挥手,比TCP快)
(2)集成了TLS加密功能
(3)多路复用,彻底解决TCP中队头阻塞的问题(单个“流”是有序的,可能会因为丢包而阻塞,但是其他流不会受到影响)
————————————————
总结
HTTP1.1的缺点:安全性不足和性能不高;
HTTP2.0完全兼容HTTTP1.0,是“更安全的HTTP,更快的HTTPS”,头部压缩,多路复用等技术充分利用了带宽,降低了延迟。
HTTP3.0的底层支撑协议QUIC基于UDP实现,又含TCP的特点,实现了又快又可靠的协议。
————————————————
css:
6.四次挥手
TCP四次挥手是TCP协议用来终止一个已经存在的连接的过程。这个过程保证了双方都能够完全地关闭连接。
1. 第一次挥手:客户端发送FIN
- **发起者**:客户端
- **动作**:客户端决定关闭连接,发送一个FIN(结束标志位)报文给服务器。
- **目的**:告诉服务器,客户端已经没有数据发送了。
2. 第二次挥手:服务器回应ACK
- **发起者**:服务器
- **动作**:服务器收到客户端的FIN报文后,发送一个ACK(确认序号)报文作为回应。
- **目的**:告诉客户端,它的结束请求已经收到了,但服务器可能还有数据需要处理和发送。
3. 第三次挥手:服务器发送FIN
- **发起者**:服务器
- **动作**:服务器完成了它剩余的数据处理和发送后,发送一个FIN报文给客户端。
- **目的**:告诉客户端,服务器方面也准备好关闭连接了。
4. 第四次挥手:客户端回应ACK
- **发起者**:客户端
- **动作**:客户端收到服务器的FIN报文后,发送一个ACK报文作为回应。
- **目的**:确认收到了服务器的结束请求,同意关闭连接。
完成挥手
- **最后步骤**:客户端发送ACK报文后,等待一段时间(称为TIME_WAIT)以确保服务器收到了其ACK报文,然后最终关闭连接。服务器在收到客户端的ACK报文后也关闭连接。
四次挥手的原因
TCP是一个全双工的协议,意味着数据传输是双向的。因此,每个方向的关闭都需要独立完成。客户端和服务器各自发送FIN来终止它们各自的发送方向的连接。这就是为什么需要四次挥手而不是三次挥手来终止TCP连接的原因。
简而言之,四次挥手的过程确保了数据能够完全发送完毕,同时双方都同意关闭连接,从而优雅地结束会话。
7.tcp三次握手相关问题
三次握手就是建立tcp连接时候,需要客户端和服务器一共发送三个包;
主要作用:确认双方的接收和发送能力是否正常,指定自己的初始化序列号微后面的可靠性传送做准备;
过程:
-
第一次握手:客户端向服务器发送一个SYN(同步序列编号)报文来发起一个连接请求。此时不包含ACK信息,因为还没有开始数据传输。
-
第二次握手:服务器回应客户端的SYN报文,发送一个SYN报文作为应答,并附带一个ACK。这个ACK的值设置为客户端的初始化序列号加1(ISN(c)+1),表示服务器已经接收到客户端的SYN,并期待接收客户端下一个数据段的序列号起始于ISN(c)+1。
-
第三次握手:客户端再次发送ACK报文给服务器,这个ACK的值设置为服务器的初始化序列号加1(ISN(s)+1),确认服务器的SYN已接收,并通知服务器客户端准备就绪,可以开始数据传输。此时,连接建立,双方进入established状态。
-
注:
ACK
用于确认接收到的数据。每当TCP传输一个数据段(segment),接收方需要向发送方发送一个ACK
来确认已经成功接收到这个数据段。为什么不是二次?
如果是两次握手,发送端可以确定自己发送的信息能对方能收到,也能确定对方发的包自己能收到,但接收端只能确定对方发的包自己能收到 无法确定自己发的包对方能收到
这段话提到的是,如果TCP连接建立只采用两次握手而不是三次握手,可能会导致一些问题,尤其是在网络条件不理想的情况下。让我们逐步解析这个问题:
为什么需要三次握手?
TCP的三次握手协议是为了可靠地建立一个双向通信连接设计的。这个过程确保了双方都明确知道另一方已准备好接收和发送数据。这三步分别是:
-
客户端发送SYN:客户端向服务器发送一个SYN(同步序列编号)报文来发起连接。
-
服务器回应SYN-ACK:服务器接收到SYN后,回复一个SYN-ACK(同步和确认)报文。
-
客户端发送ACK:客户端收到SYN-ACK后,发送一个确认(ACK)报文。
两次握手存在的问题
如果只有两次握手:
-
客户端发送SYN:客户端向服务器发送一个SYN报文来发起连接。
-
服务器回应SYN-ACK:服务器接收到SYN后,回复一个SYN-ACK报文,同时建立连接。
在这种情况下,如果客户端因为网络阻塞或其他原因发送的SYN报文延迟到达服务器,客户端可能会认为第一个请求失败了,然后再次尝试发送一个新的SYN报文。如果只需两次握手,服务器每收到一个SYN报文就建立一次连接,那么延迟的SYN报文到达时,服务器会错误地认为这是一个新的连接请求,从而为已经过时的连接请求分配资源。
三次握手如何解决这个问题
三次握手通过要求客户端对服务器的SYN-ACK进行确认(即第三次握手中的客户端发送ACK),确保了只有当双方都确认连接请求时,连接才最终建立。这意味着即使有延迟到达的SYN报文,服务器也不会为它们分配新的连接资源,除非客户端针对那个特定的SYN-ACK再次确认。这样,就避免了因为过时的连接请求而浪费服务器资源的问题。
总之,三次握手通过一个额外的确认步骤,提高了TCP连接的可靠性,确保了双方都准备好进行数据通信,同时避免了网络延迟导致的资源浪费。
8.css的基本单位 —百分比用过吗—参考那个元素的百分比
绝对长度单位是固定的,用任何一个绝对长度表示的长度都将恰好显示为这个尺寸。
相对长度单位规定相对于另一个长度属性的长度。相对长度单位在不同渲染介质之间缩放表现得更好。
一、固定单位:
1、px 像素通常在不定义显示缩放比例的情况下,
1px对应显示器屏幕上的一个像素点,对于高清屏则对应更多。它做不到自适应的效果。
早些时候pc端页面开发基本都使用像素这个单位
二、相对单位
1、%(百分比)浏览器根据其父级元素的样式来计算值。父元素改变的时候,子元素大小自动改变。
2、em:相对于父元素的字号大小来计算值,当元素自身有字号大小时,则按照元素自身字号大小来计算值。通常情况下浏览器默认字号大小为16px,则2em = 32px
3、rem:rem(root em)是相对于根目录字号大小进行计算。一个页面有且只有一个根目录html。
4、vw:vw(viewpoint width)视口宽度,可以理解为整个屏幕宽为100vw,那么1vw = 视口宽度的1%,可以达到屏幕自适应。
5、vh:vh(viewpoint height)视口高度,可以理解为整个屏幕高为100vh,那么1vh = 视口高度的1%,可以达到屏幕自适应。
6、vmin:取vw和vh中较小的那一个的值。将窗口最小的一边分为100份,每1vmin是视图窗口最小的一边的1/100
7、vmax:取vw和vh中较大的那一个的值。将窗口最大的一边分为100份,每1vmax是视图窗口最大的一边的1/100
9.有一个盒子宽度是50%。 这是参考哪个盒子 要是绝对定位呢 参考那个
在CSS中,一个元素的宽度百分比是相对于其父元素的宽度计算的。也就是说,如果你有一个元素的宽度设置为50%,那么它的宽度将会是其父元素宽度的50%。
当元素是绝对定位(`position: absolute;`)时,它的宽度百分比计算依旧是相对于其最近的非静态定位(也就是`position`不是`static`)的祖先元素。如果这样的祖先元素不存在,则会相对于初始包含块(通常是`<html>`元素)计算。
举个例子:
- 如果一个绝对定位的元素(子元素)内部没有任何定位不是`static`的祖先元素,那么它的宽度百分比将基于浏览器窗口(或者更精确地说,是视口)的宽度。
- 如果这个绝对定位的元素有一个父元素或更高层的祖先元素是非静态定位的(比如说`position: relative;`、`position: absolute;`或`position: fixed;`),那么它的宽度百分比就会基于那个非静态定位的祖先元素的宽度。
因此,具体参考的是哪个盒子,取决于元素的定位和其祖先元素的定位属性。
10.两栏布局 左边100px 右边占满
flex布局
grid布局
左侧float
12.js都有哪些常用的数据类型呢 。对数据进行判断有哪些方式 instanceof :true false typeof 区别基. Nsbsun obf
值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function)
其中typeof返回的类型都是字符串形式,需注意!!!!! 只能检查基本数据类型
alert(typeof "helloworld") ------------------>"string"
一般变量用typeof
已知对象类型用instanceof
通用方法Object.prototype.toString.call()
13. let const区别。他们和var的区别 暂时性死区是什么?
var可以预解析和重复定义 函数作用域,let const不行 都是块级作用域
const必须初始化
暂时性死区是指在块作用域内,在变量声明之前访问该变量会导致 ReferenceError 错误的现象。这是因为在进入作用域时,变量虽然已经被声明,但是在声明前的区域(即暂时性死区)内,尝试访问这个变量会触发错误。
暂时性死区的行为主要涉及到 let 和 const 关键字声明的变量
14.promise的使用方法
是解决异步编程的一个解决方案,解决多个异步方法串行的问题 ,比如说回调函数
其实就是一个容器,他用来存储未来才会发生的事情
接受一个函数一个函数有两个形参 一个是resolve 成功的回调一饿哥事reject
有三种状态;resolved rejected pending
有两个重要的api
Promise.all :
与Promise.race()不同,Promise.all() 方法要求传入的所有Promise都必须解决(fulfilled)才能得到结果,否则,只要有一个Promise被拒绝(rejected),整个新的Promise就会被拒绝。
使用Promise.all() 可以同时发起多个异步操作,然后等待它们全部完成。这在需要同时获取多个资源并等待全部资源准备好时非常有用。
———————————————————————————————————————————————
promise.race
Promise.race() 方法允许我们同时发起多个异步操作,并在其中一个操作解决(fulfilled)或拒绝(rejected)时得到结果。它的语法如下: js Promise.race([promise1, promise2, ...])
其中,promise1、promise2等为Promise对象数组。新的Promise的状态将与第一个解决或拒绝的Promise的状态相同。
考虑这样一个场景,我们需要从多个数据源获取数据,但只关心最快返回的结果。这时,Promise.race() 就派上用场了
———————————————————————————————————————————————
································································
15.浏览器的同源策略
协议端口域名有一个不同就不符合同源策略
16.怎么解决跨域
- CORS(主流的解决方案,推荐使用)
- JSONP(有缺陷的解决方案,只支持GET请求)
- 本地用webpack代理 或者用手脚架代理
在Webpack的配置文件中,可以通过配置devServer.proxy选项来设置代理。代理服务器会拦截前端发送的请求,并将请求转发到目标服务器。在转发请求时,代理服务器会修改请求的域名、端口等信息,以实现跨域请求。目标服务器接收到代理服务器转发的请求,并返回响应结果。代理服务器将响应结果返回给前端应用程序。
可以在根目录下建立一个vue.config.js的文件:
module.exports = {
devServer: {
// https://www.baidu.com/company/getall
proxy: { // 配置跨域
'/api': { // 请求相对路径以/api开头的, 才会走这里的配置
target: 'https://www.baidu.com/', // 需要代理的地址
secure: false, // 如果是不是https接口,可以不配置这个参数
changeOrigin: true, // 允许跨域
pathRewrite: {
'^/api': '', // 路径重写,将前缀/apis转为"/",也可以理解为"/apis"代替target里面的地址
// 如果本身的接口地址就有"/api"这种通用前缀,也就是说https://www.exaple.com/api,就可以把pathRewrite删掉,如果没有则加上
},
},
},
},
};
axios请求的代码:
axios({
url: '/api/company/getall'
})
- 线上用nginx服务器部署在线上的时候才用它
nginx反向代理: 浏览器去访问的时候会直接访问nginx, nginx会去访问资源服务器获取数据.
nginx反向代理一般都是在上线时使用, 一般都是在服务器中下载配置好nginx,在nginx.config.js中配置 其他的我不太了解了
17. bind apply call的区别
改变函数运行时候的上下文。第一个参数this指向 di二个参数是函数接受的参数
Call接收参数列表。apply参数数组 立即执行,临时改变
Bind 参数列表 返回一个新函数 需要的时候再进行调用,永久改变 a组 b永
18.浏览器是多进程的,每个tab页都是一个进程 ——js单线程 ——为啥呢
Js的单线程与它的用途有关,作为浏览器语言,JavaScript的主要用途是与用户互动以及操作DOM,这决定了它只能是单线程
;要不然就会带来很复杂的同步问题,比如:假如js是多线程,如果一个线程要修改某个DOM,而另外一个线程要删除这个DOM,此时浏览器就不知道该如何操作了,一脸茫然;所以为了避免复杂性,从诞生开始就是单线程。
浏览器是多线程的,浏览器为每个标签页开启了独立的渲染进程,每个进程之间的资源(CPU,内存等)和行为(UI,逻辑等)互不共享,所以即使某个标签页奔溃了也不会影响其他标签页。
19.node js的垃圾回收机制 讲解一下
20.浏览器的垃圾回收机制
1.标记清除
这个算法,分标记清楚两个阶段,标记就是为所有的活动对象做一个标记,清除阶段就是把没有标记(非活动对象)销毁
首先对所有的内存进行标记,然后从根对象遍历,还是被上下文变量使用就清除标记,然后清理所有带有标牌的变量,销毁并且回收他们所占用的空间,最后垃圾回收程序做一次内存清除。d
到那时他有一个缺点就是会存在很多内存碎片。需要通过标记整理策略进行解决。
标记清除算法的优点是:对比引用计数算法,标记清除算法最大的优点是能够回收循环引用的对象,它也是v8引擎使用最多的算法。
2.引用计数
当对象被引用的次数是0,那就进行回收,但是循环引用的时候,两个对象都至少被引用了一次,因此导致内存泄漏
(不再用到的内存,没有及时释放,就叫做内存泄漏。因为不用的内存用改被垃圾回收机制回收,但是某种原因,他没有被回收,就叫做内存泄漏)
引用计数算法缺点:
- 无法回收循环引用的对象;
- 空间开销比较大;
21.平时用node 做一些什么东西呢。用过中间件没。讲一下中间件的作用、
vue:
22.vue数据绑定的过程
23.vue3 数据绑定升级 用了一个升级 为啥优化
因为vue2.0只能劫持对象属性,无法监控数组下标的变化,导致通过数组下标添加的元素不能实时响应。
为了解决这个问题。经过vue内部处理之后,可以使用push pop shift unshift splice sort reverse 进行hack处理,所以其他数组属性也是监测不到,有一定的局限性。痛殴递归+遍历data对象来实现数据的监控,如果有属性值是对象的话,还需要深度遍历。
Vue3不仅可以代理对象还可以代理数组,也可以代理动态添加的属性
因为object。definepProperty只能劫持对象属性,从而需要对每个对象的属性进行遍历,
24.v-for 为啥使用一个key值呢。key是随意设置的还是有要求
key 是 v-for 指令中的一个重要属性,它用于识别节点的标识,从而能更高效地更新虚拟 DOM 中的节点。通常情况下,在 v-for 中使用 key 可以开启 Vue 的性能优化,提高渲染的效率。
当 Vue 重新渲染节点时,它会比较新旧两个节点的 key 值,如果相同则表示这个节点没有发生变化,可以直接复用老节点的状态,省去创建和销毁节点的过程。如果 key 值不同,则会按照一般的创建、销毁流程重新渲染节点。
在选择 key 值时,应该注意以下几点:
每个节点的 key 值应当是唯一的,不能重复。
key 值应当基于数据的唯一标识,例如数据中的 id 字段等。这样做可以防止出现类似“删除第一个元素后,第二个元素变成了第一个元素”的问题。
如果无法确定数据的唯一标识,可以考虑使用节点索引作为 key 值(如 :key="index"),但这通常不是最优的选择,可能导致渲染效率下降。
————————————————
25.前端性能优化
1.减少请求数量
【使用缓存】
使用cach-control或expires这类强缓存时,缓存不过期的情况下,不向服务器发送请求。强缓存过期时,会使用last-modified或etag这类协商缓存,向服务器发送请求,如果资源没有变化,则服务器返回304响应,浏览器继续从本地缓存加载资源;如果资源更新了,则服务器将更新后的资源发送到浏览器,并返回200响应
【不使用CSS @import】
CSS的@import会造成额外的请求
使用@import引入CSS会影响浏览器的并行下载。使用@import引用的CSS文件只有在引用它的那个css文件被下载、解析之后,浏览器才会知道还有另外一个css需要下载,这时才去下载,然后下载后开始解析、构建render tree等一系列操作。这就导致浏览器无法并行下载所需的样式文件。
【避免使用空的src和href】
a标签设置空的href,会重定向到当前的页面地址
form设置空的method,会提交表单到当前的页面地址
2、优化资源加载
模块按需加载
在SPA等业务逻辑比较复杂的系统中,需要根据路由来加载当前页面需要的业务模块
按需加载,是一种很好的优化网页或应用的方式。这种方式实际上是先把代码在一些逻辑断点处分离开,然后在一些代码块中完成某些操作后,立即引用或即将引用另外一些新的代码块。这样加快了应用的初始加载速度,减轻了它的总体体积,因为某些代码块可能永远不会被加载
webpack 提供了两个类似的技术,优先选择的方式是使用符合 ECMAScript 提案 的 import() 语法。第二种则是使用 webpack 特定的 require.ensure
资源懒加载与资源预加载
资源延迟加载也称为懒加载,延迟加载资源或符合某些条件时才加载某些资源
资源预加载是提前加载用户所需的资源,保证良好的用户体验
资源懒加载和资源预加载都是一种错峰操作,在浏览器忙碌的时候不做操作,浏览器空间时,再加载资源,优化了网络性能
3.webpack优化
【打包公共代码】
使用CommonsChunkPlugin插件,将公共模块拆出来,最终合成的文件能够在最开始的时候加载一次,便存到缓存中供后续使用。这会带来速度上的提升,因为浏览器会迅速将公共的代码从缓存中取出来,而不是每次访问一个新页面时,再去加载一个更大的文件
webpack 4 将移除 CommonsChunkPlugin, 取而代之的是两个新的配置项 optimization.splitChunks 和 optimization.runtimeChunk
通过设置 optimization.splitChunks.chunks: "all" 来启动默认的代码分割配置项
【动态导入和按需加载】
webpack提供了两种技术通过模块的内联函数调用来分离代码,优先选择的方式是,使用符合 ECMAScript 提案 的 import() 语法。第二种,则是使用 webpack 特定的 require.ensure
【剔除无用代码】
tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块系统中的静态结构特性,例如 import 和 export。这个术语和概念实际上是兴起于 ES2015 模块打包工具 rollup
JS的tree shaking主要通过uglifyjs插件来完成,CSS的tree shaking主要通过purify CSS来实现的
【长缓存优化】
1、将hash替换为chunkhash,这样当chunk不变时,缓存依然有效
2、使用Name而不是id
每个 module.id 会基于默认的解析顺序(resolve order)进行增量。也就是说,当解析顺序发生变化,ID 也会随之改变
下面来使用两个插件解决这个问题。第一个插件是 NamedModulesPlugin,将使用模块的路径,而不是数字标识符。虽然此插件有助于在开发过程中输出结果的可读性,然而执行时间会长一些。第二个选择是使用 HashedModuleIdsPlugin,推荐用于生产环境构建
【公用代码内联】
使用html-webpack-inline-chunk-plugin插件将mainfest.js内联到html文件中
4.来减少重绘回流
防抖和节流
使用函数节流(throttle)或函数去抖(debounce),限制某一个方法的频繁触发
26.web pack 常用的loader
27.mv*框架源码
数据结构:
25.
26.不均匀的硬币 用她硬币实现一个公平双人的对局
1.css 选择器(选择第几倍的元素),nth-child(2n+1)
2.css选择非第一个子元素有哪些方法实现
(1)选择指定元素的所有指定子元素
element1 > element2
=======================
(2)如果想要递归选择所有子元素,则使用以下语法
element1 > *
3.阻止冒泡事件的三种方法
事件冒泡:比如说一个按钮的点击事件,这个事件会在这个元素所有的祖先中触发
(1)event.stopPropagation
这是阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开。
(2)$(‘.btn').click(function (even) {
alert('按钮被点击了');
return false;
})
这个方法比较暴力,他会同事阻止事件冒泡也会阻止默认事件;写上此代码,连接不会被打开,事件也不会传递到上一层的父元素;可以理解为return false就等于同时调用了event.stopPropagation()和event.preventDefault()
(3)$('.btn').click(function (even) {
even.preventDefault();
alert('按钮被点击了');
})
这是阻止默认事件的方法,调用此方法是,连接不会被打开,但是会发生冒泡,冒泡会传递到上一层的父元素;
4.如何避免表单重复提交
(1)
1.前端处理(场景:用于网络延迟情况下用户点击多次submit按钮导致表单重复提交)
👊①:通过一个标识来控制表单提交之后,再次提交会直接返回处理。
(2)
var is= false;
function(){
if(is == false){
// 提交表单后设置true
Is = true;
Return true;
}else{
Return false}
}
👊②:通过点击提交一次按钮之后,将该按钮设置为不可用处理。
function(){
Var btn = document.getElementById(‘sumbit’);
Btn.disabled = “disabled”;
//让表单可以提交
Return true;
}
👊3:
使用POST方法提交表单
默认情况下,表单使用GET方法提交。这种方法会将表单数据附加到URL中并发送给服务器。由于URL的长度限制,GET方法只能提交较小的表单数据,并且可能导致数据丢失或被恶意篡改。因此,为了避免表单重复提交,建议使用POST方法提交表单,将表单数据放在HTTP请求体中,这样更安全。
6.绝对定位水平居中
绝对定位 不能通过上下左右都设置为0, 设置 margin: auto; 样式的方式 , 设置盒子模型水平居中 ;
相对定位 的 盒子模型 , 并没有脱离标准流限制 , 仍然可以使通过设置 margin: auto; 样式的方式 令盒子水平居中 ;
👊所以:先设置 50% 的 宽度 / 高度 偏移量 , 然后再往回退 盒子一半 宽度 / 高度 的偏移量 ;
left:50%;
Margin-left:-他自己宽度的一半
👊容器尺寸未知的前提下,使用CSS3的transform属性代替margin,transform中的translate偏移的百分比值是相对于自身大小的,设置示例如下:
- .element {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%); /* 50%为自身尺寸的一半 */
-webkit-transform: translate(-50%, -50%);}
margin:0 auto;在不同场景下生效条件如下:
块级元素:给定要居中的块级元素的宽度。也就是没设置宽度就不生效
行内元素:①设置display:block;②给定要居中的行内元素的宽度。(行内元素设置成块级元素后可以对其宽高进行设置)
行内块元素:设置display:block。(如input、button、img等元素,自带宽度可以不用设置其宽度)
注:
①可以通过对块级元素设置 text-align:center;的方式来实现内联元素(如文本、图片)居中
②margin:0 auto;可以使盒子居中,text-align:center;可以使此盒子内的内联元素居中,故有时需要两者结合使用才能使得盒子及其中文本一起居中。
margin:'0 auto'; 只对块元素起作用,还要设置width属性。
注:img/input/button等自带宽度,可不设置。
————————————————
Css实现水平垂直居中:
1.flex布局。 给body(父盒子)加弹性元素display: flex; 注意一定是给父盒子加 弹性元素display: flex 导致的是子盒子的垂直居中:
2.上下左右都是0 margin:auto。当然也是要在绝对定位下 子绝父相
3.设置向上向左50%。然后往回走自己宽高的一半。可以用margin 可以用transform:translate(-50%,-50%)。子绝父相