一、HTML
1.H5新增的语义化标签
1. 新增布局标签
标签名 | 语义 | 单/双标签 |
---|---|---|
header | 整个页面,或部分区域的头部 | 双 |
footer | 整个页面,或部分区域的底部 | 双 |
nav | 导航 | 双 |
article | 文章、帖子、杂志、新闻、博客、评论等 | 双 |
section | 页面中的某段文字,或文章中的某段文字(里面文字通常里面会包含标题) | 双 |
aside | 侧边栏 | 双 |
main | 文档的主要内容 (WHATWG没有语义,IE不支持),几乎不用 | 双 |
hgroup | 包裹连续的标题,如文章主标题、副标题的组合(W3C将其删除) | 双 |
关于
article
和section
:
article
里面可以有多个section
。section
强调的是分段或分块,如果你想将一块内容分成几段的时候,可使用section
元素。article
比section
更强调独立性,一块内容如果比较独立、比较完整,应该使用article
元素。
2.新增状态标签
新增状态标签
- meter 标签
语义:定义已知范围内的标量测量。也被称为gauge
(尺度),双标签,例如:电量、磁盘用量等。
常用属性如下:
属性 | 值 | 描述 |
---|---|---|
high | 数值 | 规定高值 |
low | 数值 | 规定低值 |
max | 数值 | 规定最大值 |
min | 数值 | 规定最小值 |
optimum | 数值 | 规定最优值 |
value | 数值 | 规定当前值 |
- progress 标签
语义:显示某个任务完成的进度的指示器,一般用于表示进度条,双标签,例如:工作完成进度等。
属性 | 值 | 描述 |
---|---|---|
max | 数值 | 规定目标值。 |
value | 数值 | 规定当前值。 |
3.新增文本标签
- 文本注音
标签名 | 语义 | 单/双标签 |
---|---|---|
ruby | 包裹需要注音的文字 | 双 |
rt | 写注音,rt标签写在ruby的里面 | 双 |
html
<ruby>
<span>魑魅魍魉</span>
<rt>chī mèi wǎng liǎng </rt>
</ruby>
4.新增多媒体标签
- 视频标签
<video>
标签用来定义视频,它是双标签。
属性 | 值 | 描述 |
---|---|---|
src | URL地址 | 视频地址 |
width | 像素值 | 设置视频播放器的宽度 |
height | 像素值 | 设置视频播放器的高度 |
controls | - | 向用户显示视频控件(比如播放/暂停按钮) |
muted | - | 视频静音 |
autoplay | - | 视频自动播放 |
loop | - | 循环播放 |
poster | URL地址 | 视频封面 |
preload | auto / metadata / none | 视频预加载,如果使用autoplay,则忽略该属性。 |
要想开启自动播放,必须开启视频静音, 但是有的时候开了自动播放,也开了视频静音,但是还是有声音,这是因为媒体参与度的问题即浏览器会自动记录你打开这个网友的操作习惯如果你经常打开这个网页播放视频 那么会让你自动播放视频且不静音
chorme媒体参与度查询地址:chrome://media-engagement/
html
<video>
<source src="URL地址" type="video/mp4">
<source src="URL地址" type="video/webm">
该浏览器不支持HTML5视频标签。
</video>
- 音频标签
<audio>
标签用来定义音频,它是双标签。
属性 | 值 | 描述 |
---|---|---|
src | URL地址 | 音频地址 |
controls | - | 向用户显示音频控件(比如播放/暂停按钮) |
autoplay | - | 音频自动播放 |
muted | - | 音频静音 |
loop | - | 循环播放 |
preload | auto / metadata / none | 音频预加载,如果使用autoplay,则忽略该属性。 |
html
<audio>
<source src="URL地址" type="audio/mp3">
<source src="URL地址" type="audio/wav">
该浏览器不支持HTML5音频标签。
</audio>
2.什么是BFC
- 解释
块级格式化上下文的简称,主要用于解决margin坍塌,让内部元素不受外部干扰 - 如何开启
- 设置float
- 设置position为absolute或fixed
- 设置行内块display:inline-block
- 设置overflow不为默认的visible
二、CSS
1.css中选择器的优先级
!important>行内>id>class>标签
2.居中的方案
1. position:absolute
top:50%;
left:50%;
transform(-50%,-50%)
2. display:flex;
justify-content:center;
align-items:center;
3. display:grid;
justify-content:center;
align-items:center;
3.px、em、rem、rpx(移动端适配方案)
- px:是绝对单位,不会随着页面改变而进行适配
- em:相对单位,1em等于当前字体大小。例如:当前字体大小为14px,则1em=14px。em会集成父元素字体大小。
- rem:也是相对单位,1rem相当于HTML根元素字体大小,大小不会继承
- rpx ( responsive pixel)响应单位 rpx是微信小程序独有的、解决屏幕自适应的尺寸单位可以根据屏幕宽度进行自适应,不论大小屏幕,规定屏幕宽为750rpx通过 rpx 设置元素和字体的大小,小程序在不同尺寸的屏幕下,可以实现自动适配 1rpx = 0.5px=1物理像素
4.隐藏一个元素的方法
- display:none
- visibility:hidden
- opcity:0
5.画一条0.5px的线
transform:scale(0.5)
区别:
-
display:none 元素不会被渲染;
-
visibility:hindden,元素被隐藏但是元素会被渲染,元素占用空间
-
opcity:0 本质上是透明度为0,但是元素还是会被渲染,元素占用空间
-
diplay和visibility的元素不会触发绑定事件,而opcity会触发
6.position的值
- static:默认值,静态定位,按照正常流布局
- relative:相对定位,元素相对自身正常位置的偏移,仍占据原始空间。
- absolute:绝对定位:元素相对于最近的已定位的元素偏移,不占据空间。
- fixed:固定定位,元素相对于视窗固定位置,不占据空间
7.画三角形
给定一个宽度和高度都是0的元素,其border的任何值都会直接相交。
.triangle {
width: 0;
height: 0;
border-top: 50px solid skyblue;
border-right: 50px solid transparent;
border-left: 50px solid transparent;
}
8.设置一个元素的背景颜色,背景颜色会填充哪些区域?
content+padding+border 除了margin
9.box-sizing的作用,如何使用?
改变盒子模型,也就是说决定了你的width是取决于border还是content
三、JavaScript
1.防抖与节流
防抖
js
function debounce(fn, delay) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
//使用
var handle = debounce(function(width){
console.log(width)
},1000)
window.onresize=function(){
handle(document.documentElement.clienWidth)
}
节流:非立即执行
js
function throttle(fn, delay) {
let timer = null;
return function (...args) {
//如果存在计时器那么直接返回 不做任何处理
if (timer) {
return;
}
//如果不存在计时器,那么开启一个计时器
timer = setTimeout(() => {
//当计时器结束之后执行
fn.apply(this, args);
//将计时器清空否则永远不会结束
timer = null;
}, delay);
};
}
节流:立即执行一次
js
function throttle(fn, delay) {
let timer = null
return function (...args) {
if (!timer || Date.now() - timer >= delay) {
fn.apply(this, args)
timer = Date.now()
}
}
}
2.promise
1. 实例对象的属性
- pending 未决定的
- rersolved / fulfilled 成功
- rejectd 失败
2. 结果值
- resolve
- reject
3. API
- Promise.all方法
- 返回一个新的promise,只有所有的promise都成功才成功,否则失败(执行到有一个失败会直接return 所以不存在多个失败)
- 按顺序执行下来的
js
let p1= new Promise ((resolve,reject)=>{
resolve('ok')
})
let p2 = Promise.resolve('success')
let p3 =Promise.resolve('okk')
const results = Promise.all([p1,p2,p3])
console.log(results)
- Promise.race方法
- 返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态。
- 不是按顺序执行,是看谁先返回状态。
js
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, 1000)
})
let p2 = Promise.reject('error1')
const results = Promise.all([p1, p2])
console.log(results)
3.localStorage和SessionStorage
LocalStorage可跨浏览器窗口和选项卡间共享。就是说如果在多个选项卡和窗口中打开了一个应用程序,而一旦在其中一个选项卡或窗口中更新了LocalStorage,则在所有其他选项卡和窗口中都会看到更新后的LocalStorage数据。
但是,SessionStorage数据独立于其他选项卡和窗口。如果同时打开了两个选项卡,其中一个更新了SessionStorage,则在其他选项卡和窗口中不会反映出来。
4.数组去重
js
//方法一:filter
funcion myUniq(arr){
return arr.filter((item,index,arr)=>{
return index ===arr.indexOf(item)
})
}
//方法二:set方法
function myUniq(arr){
return [new Set(...arr)]
}
5.判断数据类型
js
function getType (target) {
// typeof 返回一个表达式的数据类型的字符串,
// 返回结果为javascript中的基本数据类型,
// 包括:number、boolean、string、object、undefined、function等6种数据类型。
var type =typeof target
if(type !='object'){
return type
}else{
//这时候可以使用instanceof---》原理就是通过去判断prototype上是否有他的原型
//var set = new Set()
//console.log(Object.prototype.toString.call(set))--->[object Set]
//我们只需要Set 通过slice方法切割 不会改变原数据
//要求返回的是小写字母那么调用toLowerCase方法
return Object.prototype.toString.call(target).slice(8,-1).toLowerCase()
}
}
6.逆序标签内的元素
html
<body>
<div>
<span>1</span>
<i>2</i>
<strong>3</strong>
</div>
<script>
var div = document.getElementsByTagName('div')[0]
Element.prototype.reverseNodes = function () {
var children = this.children
var length = children.length
for (var i = length - 1; i >= 0; i--) {
this.appendChild(children[i])
}
}
div.reverseNodes()
</script>
</body>
7.数组的基础方法
js
1.push():在数组最后面添加元素
// this.letters.push('aaa')
// this.letters.push('aaaa', 'bbbb', 'cccc')
2.pop(): 删除数组中的最后一个元素
// this.letters.pop();
3.shift(): 删除数组中的第一个元素
// this.letters.shift();
4.unshift(): 在数组最前面添加元素
// this.letters.unshift()
// this.letters.unshift('aaa', 'bbb', 'ccc')
5.splice()作用: 删除元素/插入元素/替换元素
// 删除元素: 第二个参数传入你要删除几个元素(如果没有传,就删除后面所有的元素)
// 替换元素: 第二个参数, 表示我们要替换几个元素, 后面是用于替换前面的元素
// 插入元素: 第二个参数, 传入0, 并且后面跟上要插入的元素
// splice(start)
// splice(start):
// this.letters.splice(1, 3, 'm', 'n', 'l', 'x')
// this.letters.splice(1, 0, 'x', 'y', 'z')
5.sort()
// this.letters.sort()
6.reverse()
// this.letters.reverse()
8.怎么判断两个对象相等?
js
function isObjectEqual(a, b) {
// 先判断传入的两个对象是否指向同一内存地址
if (a === b) return true;
// 获取两个对象键数组
let aKeys = Object.keys(a);
let bKeys = Object.keys(b);
// 判断两个数组的长度是否一样长
if (aKeys.length !== bKeys.length) return false;
// 遍历对象的键值
for (let key of aKeys) {
// 判断属性在b中是否存在
if (!b.hasOwnProperty(key)) return false;
// 获取a和b的当前属性值
const valueA = a[key];
const valueB = b[key];
// 如果当前属性值是对象,递归进行比较
if (typeof valueA === 'object' && typeof valueB === 'object') {
if (!isObjectEqual(valueA, valueB)) {
return false;
}
} else if (Array.isArray(valueA) && Array.isArray(valueB)) {
// 如果当前属性值是数组,比较数组元素
if (!arrayEquals(valueA, valueB)) {
return false;
}
} else if (valueA !== valueB) {
// 普通属性值的比较
return false;
}
}
return true;
}
// 辅助函数,用于比较两个数组是否相等
function arrayEquals(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
for (let i = 0; i < arr1.length; i++) {
if (arr1[i] !== arr2[i]) return false;
}
return true;
}
9.如何判断空对象?
js
reflect.ownKeys(obj).length===0
10.0.1+0.2为什么不等于0.3?
js中的number类型的数据都是双精度浮点型保存在内存中的,ieee754标准,由于0.1转化为2进制是一个无限循环的,但是内存保存的位数有限,所以这里会造成第一次精度丢失,在0.1+0.2时,在执行加操作时要对阶,0.1的阶数比0.2小,所以0.1的尾数为要右移,所以这里也会造成精度丢失.
怎么解决?
方法一: (0.1+0.2).toFixed(1)//四舍五入保留一位小数
方法二:利用一个很小的误差数值进行比较: Number.EPSILON
11.'=='和全等的区别
都是比较运算符,
- 全等是严格相等运算符,比较两个对象的值是否完全相等,包括变量的值和类型.
- ==宽松相等运算符,先将变量进行类型转换(valueOf或者toString)在比较两个对象的值
1全等1 true
1等于1 true
1全等'1'false
1等于'1'true
12.如果将一个多维数组降维?
js
//flat方法可以传递指定递归深度,但是会忽略空位
function flatArr(arr){
return arr.flat(Infinity).map(item=>item===undefined?"":item)
}
13.如何获取当前日期
js
// 创建一个 Date 对象
var currentDate = new Date();
// 获取年、月、日、时、分和秒
var year = currentDate.getFullYear();
var month = currentDate.getMonth() + 1; // 月份从 0 开始,需要加 1
var day = currentDate.getDate();
var hours = currentDate.getHours();
var minutes = currentDate.getMinutes();
var seconds = currentDate.getSeconds();
14.如何遍历对象的属性
js
//方法一:
for in
//方法二:
Object.keys()
//方法三:
Object.entries()
//方法四:
Reflect.ownKeys()
//方法五:
Object.getOwnPropertyNames()
15.什么是伪数组
一个含有length和索引属性的对象,但构造器不是Array。常见的有arguments,HTMLCollection对象和NodeList对象. 但不能使用数组的基础方法。
怎么转换为真实数组?
- Array.from
- Array.prototype.slice.call()// 这里的slice是特殊用法
- Array.prototype.concat.apply([], arr)
16.变量提升是什么?与函数提升的区别
- 变量提升就是在预编译期间会将变量声明提升至其作用域的最顶端,在变量赋值之前访问都是undefined。
- 而函数声明方式创建的函数会提升整个函数体。
- 函数声明的优先级高于变量提升,且不会被同名变量声明时覆盖
17.什么是作用域链?如何延长?
在js中查找一个变量或者函数时,首先会从当前的执行期上下文对象中查找,如果当前的执行期上下文对象不存在,就会向上层的执行期上下文中查找,知道找到该变量或者全局上下文为止。这个查找的过程中的上下文对象组成的链表结构就是作用域链。
-
通过闭包可以延长
-
with 语句(不推荐使用):with 语句允许代码在一个指定的对象中创建一个新的作用域,这个对象可以是任何对象。with 语句会将指定的对象添加到作用域链的前端,使得可以直接访问该对象的属性和方法,从而延长了作用域链。但是由于 with 语句可能导致一些意外的行为和性能问题,通常不推荐使用。
jsvar obj = { x: 10, y: 20 }; with (obj) { console.log(x + y); // 可以直接访问 obj 中的属性 }
18.dom节点的attribute和property
-
Attributes(属性) 是 HTML 元素在 HTML 标记中定义的内容,它们作为字符串形式存储在 HTML 标签中,
-
Properties(属性值) 是 DOM 元素在 JavaScript 中表示的属性,它们代表了 HTML 元素的当前状态。例如,在 JavaScript 中你可以直接访问和修改元素的属性值,比如:
jsvar input = document.getElementById('myInput'); var typePropertyValue = input.type; // 获取元素的属性值 input.value = 'Hello'; // 设置元素的属性值
19.什么是事件冒泡,它是如何工作的?如何阻止?
当点击一个元素触发某种事件时,会自下而上逐渐触发父级同类事件。
e.stopPropagation来阻止
20.如何让事件先冒泡后捕获?
根据事件的顺序
js
element.addEventListener('click', eventHandler1, true); // 捕获阶段
element.addEventListener('click', eventHandler2, false); // 冒泡阶段
21.new操作符做了哪些事情
- 创建一个空对象
- 将空对象的原型指向构造函数的原型
- 改变this的指向
- 对构造函数有返回值的判断
22.eval()是什么
eval可以接受一个字符串str 作为参数,并把这个参数作为脚本代码来执行
23.实现一个once函数,传入函数参数只执行一次
通过闭包解决
js
function Once(fn){
let flag = false
return function(...args){
if(!flag){
return fn(...args)
}
}
}
24.控制一次加载一张图片,加载完后再加载下一张
用onload解决
js
// 图片地址数组
const imageUrls = ['image1.jpg', 'image2.jpg', 'image3.jpg'];
let currentIndex = 0;
function loadNextImage() {
// 创建一个新的 Image 对象
const img = new Image();
// 设置图片的 src 属性为当前要加载的图片地址
img.src = imageUrls[currentIndex];
// 监听图片加载完成事件
img.onload = function() {
// 图片加载完成后执行的操作
console.log(`Image ${currentIndex + 1} loaded`);
// 增加索引,准备加载下一张图片
currentIndex++;
// 如果还有未加载的图片,继续加载下一张
if (currentIndex < imageUrls.length) {
loadNextImage();
}
};
}
// 开始加载第一张图片
loadNextImage();
25.如何去除字符串首位空格?
trim()
26.null等于undefined输出什么,null全等于undefined输出什么
- 在ECMAScript规范中,规定了在进行相等比较时,null 和 undefined 会被视为相等。
- null全等于undefined为false
27.字符串转化为数字的方法
- 位运算符 +
- Number()
- parseInt()
- parseFloat()
28.{}和[]的valueOf和toString的结果是什么?
-
toString 方法:
- 当对象需要被转换为字符串时,JavaScript 会调用 toString 方法。
- 默认情况下,Object 类的 toString 方法返回一个字符串,其中包含对象的 [object Object] 表示。
-
valueOf 方法:
- 当对象需要被转换为原始值(非字符串)时,JavaScript 会调用 valueOf 方法。
- 默认情况下,Object 类的 valueOf 方法返回对象本身。
{}对象的valueof返回对象本身,[]返回的也是对象本身
{}对象的toString方法返回字符串"[object Object]"
[]对象的toString方法返回空字符串""
四、Vue
1.vue3升级了什么
- 性能提升
- 打包大小减少
- 渲染和更新速度加快
- 内存减少
- 源码的升级
- 重写虚拟Dom和Tree-shaking
- 使用proxy代替defineProperty实现响应式
- 拥抱TypeScript
- vue3可以更好的支持TypeScript
- 新的特性
-
组合式API :composition API
-
新的内置组件
- fragment
- teleport
- suspense
-
其他改变
- 新的生命周期
- data选项始终被声明为一个函数
-
2.ref与reactive
- 从定义数据角度对比:
- ref用来定义:基本类型数据。
- reactive用来定义:对象(或数组)类型数据。
- 备注:ref也可以用来定义对象(或数组)类型数据, 它内部会自动通过
reactive
转为代理对象。
- 从原理角度对比:
- ref通过
Object.defineProperty()
的get
与set
来实现响应式(数据劫持)。 - reactive通过使用Proxy来实现响应式(数据劫持), 并通过Reflect操作源对象内部的数据。
- ref通过
- 从使用角度对比:
- ref定义的数据:操作数据需要
.value
,读取数据时模板中直接读取不需要.value
。 - reactive定义的数据:操作数据与读取数据:均不需要
.value
。
- ref定义的数据:操作数据需要
3.vue的响应式原理
1.vue2
- 实现原理:
- 对象类型:通过
Object.defineProperty()
对属性的读取、修改进行拦截(数据劫持)。 - 数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。
- 对象类型:通过
JavaScript
Object.defineProperty(data, 'count', {
get () {},
set () {}
})
- 存在问题:
- 新增属性、删除属性, 界面不会更新。
- 直接通过下标修改数组, 界面不会自动更新。
2. vue3
- 实现原理:
- 通过Proxy(代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
- 通过Reflect(反射): 对源对象的属性进行操作。
JavaScript
new Proxy(data, {
// 拦截读取属性值
get (target, prop) {
return Reflect.get(target, prop)
},
// 拦截设置属性值或添加新属性
set (target, prop, value) {
return Reflect.set(target, prop, value)
},
// 拦截删除属性
deleteProperty (target, prop) {
return Reflect.deleteProperty(target, prop)
}
})
为什么不直接 return target[prop] 因为这种方法内部的原理是Object.defineProperty如果重复写了两个则会直接报错,而用Reflect.defineProperty不会报错 会返回true or false
4.vue3的生命周期
beforeCreate
=>setup()
created
=>setup()
beforeMount
=>onBeforeMount
mounted
=>onMounted
beforeUpdate
===>onBeforeUpdate
updated
=======>onUpdated
beforeUnmount
==>onBeforeUnmount
unmounted
=====>onUnmounted
注意:
1.如果在setup里面写需要引入,且使用形式是调用回调函数例如 onBeforeMount(()=>{ 内容})
2.如果组合式API和配置项形式的都写,那么组合式API的写法比配置项的更快一步
5.什么是虚拟DOM?
一个描述UI的javaScript对象。
6.watch和computed的区别
- 执行顺序:进入页面首先执行computed再执行watch
- watch不会产生新的值。
- computed具有缓存
7.v-for不适用key的后果
如果没有提供key,vue无法跟踪每个元素的身份,只能用一种最简单的更新策略,替换整个dom节点。会导致性能下降
8.v-show和v-if的区别
- v-show是通过css的display:block/none来控制元素的隐藏与显示的
- v-if是控制dom是否需要渲染
9.keep-alive
被 keep-alive缓存的组件不会触发销毁钩子函数,而是触发 deactivated 和 activated 钩子函数。
五、计算机网络
1.什么是同源策略
浏览器同源策略,用于限制一个origin的文档或者他加载的脚本如何能与另一个源的资源进行交互。他能帮助阻拦恶意文档和减少可能被攻击的媒介。
同源指的是:协议、域名、端口号
2.如何解决跨域问题?
当协议 域名 端口号 三者只要有一个不一样的时候就会出现跨域问题。
JSONP(JSON with Padding):
-
JSONP 是一种利用 script 标签的跨域解决方案,通过动态创建 script标签,以回调函数的形式加载数据。服务器返回的数据需要包装在回调函数中,客户端通过回调函数处理数据。缺点是只支持 GET 请求,且容易受到安全风险。
-
CORS(Cross-Origin Resource Sharing):CORS 是一种更现代、更安全的跨域解决方案,通过在服务器设置相应的 HTTP 头部来实现。服务器通过设置 Access-Control-Allow-Origin 头部指定允许访问的源,可以是单个域、多个域、或者使用通配符 * 允许所有源访问。CORS 支持简单请求(GET、POST、HEAD)和预检请求(OPTIONS)。
js// 服务器端设置 CORS 头部示例(Node.js) const express = require('express'); const app = express(); app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); next(); }); app.get('/data', (req, res) => { res.json({ message: 'Hello, CORS!' }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); });
-
代理服务器:在同源的服务器上设置一个代理服务器,将跨域请求发送到目标服务器,然后将响应返回给客户端。客户端只与同源的代理服务器通信,避免了跨域问题。
-
WebSocket:使用 WebSocket 进行跨域通信,WebSocket 不受同源策略的限制。在服务器端实现 WebSocket 服务,客户端使用 WebSocket API 进行通信。
-
跨文档消息(Cross-document Messaging):使用 window.postMessage 方法在窗口之间传递数据。在发送消息的窗口中监听 message 事件,接收消息的窗口通过 event.origin 验证消息源。
3.http和https的区别
- https再http的基础上添加了ssl协议,对数据进行加密和身份验证,https比http安全。
- http的默认端口号是80 https的默认端口是443
4.三次握手是什么? 如果变为两次握手会怎样
- 客户端发送 SYN(同步)包:
- 服务器回应 SYN-ACK 包:
- 客户端发送 ACK 包
在三次握手中,如果某一步失败或超时,连接就不会建立。这种设计有助于防止已经失效的连接请求达到服务器,从而提高了连接的可靠性。
如果变为两次握手则无法确定双方都已同意建立连接,无法防止失效的连接,难以实现连接重用
5.什么是cdn?
是一种分布式网络架构,作用是加速互联网内容的传递。主要功能是将网站或应用的静态资源分布再全球各地的边缘服务器。
六、性能优化
1.做过哪些前端性能优化相关的事情?
- 减少网络请求
- 使用图片压缩、文件压缩等方式减少文件体积
- 懒加载、预加载
- 利用浏览器缓存机制
- 减少dom结构的层级
2.要加载大量图片怎么优化?
- 对图片进行压缩
- 懒加载
3.列表无线滚动,数据越来越多,页面卡顿,如何解决?
- 分页
- 虚拟列表减少dom元素
4.for(let i =0;i<1000000;i++){console.log(i)}如何优化?
放到Web workers中执行,避免阻塞主线程