引用类型变量,栈存地址,堆存值。复制变量实际上是复制地址,与原变量的指针都指向堆存的值。修改堆值,新旧变量都会改变。
****浏览器从输入地址
1、dns解析域名
*以浏览器输入www.google.com为例:
.-> .com ->google.com. -> www.google.com.
就是先先查找本地域名服务器,再到根域名服务器查找,再到com顶级域名服务器查找,以此类推。
2、tcp三次握手
3、发起http请求
4、服务器解析请求并且返回http报文
5、浏览器解析渲染页面
6、连接结束
首先我们需要通过 DNS(域名解析系统)将 URL 解析为对应的 IP 地址,然后与这个 IP 地址确定的那台服务器建立起 TCP 网络连接,随后我们向服务端抛出我们的 HTTP 请求,服务端处理完我们的请求之后,把目标数据放在 HTTP 响应里返回给客户端,拿到响应数据的浏览器就可以开始走一个渲染的流程。渲染完毕,页面便呈现给了用户,并时刻等待响应用户的操作)。
****简单说一下http2的多路复用
http1.0 频繁发起tcp三次握手,每个tcp只能处理一个请求,否则的话需要加上connection:keep-alive字段
http1.1 默认长链接,如果想支持短链接的话就connection:close,这样的话当前请求处理完会被断掉,下次再发起请求需要重新梳理链接
虽然1.1允许服用链接,但是每次只能按照次序处理一个,如果上一个处理特别慢的话,下一个也要一直等待。这被称为队头阻塞。
****回流&重绘
1.引起重绘:节点的几何属性改变 or 样式改变,不影响布局
2.引起回流:布局 or 几何属性改变(节点的位置和几何信息)
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
- 页面一开始渲染的时候(这肯定避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
回流一定重绘,重绘不一定回流
避免的方法:
CSS:
1.减少使用offset*,scroll*,client*,width, height, getComputedStyle, getBoundingClientRect这些读取属性,浏览器会强制清空队列触发回流和重绘确保返回正确的值
2.visibility 代替display:none
3.transform代替top
4.避免使用table布局
5.尽可能在dom树的末端改变样式,减少回流影响范围
6.避免设置多层内联样式
7.动画效果使用在position absolute to fixed布局上
8.避免使用css表达式
9.开启CSS3GPU硬件加速,transform,filters, opacity不会引起重绘,但是其他属性比如background-image还是会引起的
JS:
1.避免频繁重写style属性
2.避免频繁操作DOM
3.避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。
4.对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。
***npm安装机制 为啥输入nom install 就能自动安装
1、发出nom install命令
2、查询node_modules中是否已经存在模块
若存在 不再重新安装
若不存在,npm向registry查询模块压缩包的网址,下载压缩包存放到根目录的.npm里,解压压缩包到当前项目的node_modules里
****module的加载实现
1、浏览器加载
defer “渲染完再执行” 等页面dom解析完成 并且其他脚本下载完,按照先后顺序 先出现的 先下载 先执行;
async “下载完就执行” 下载完了之后终止渲染,马上来执行脚本,如果有多个,不能保证先后顺序。
2、Amd 异步 requirejs 必须提前声明
3、Cmd 异步 seajs 使用时再声明
4、Commonjs node 运行时加载同步,输出一个值的拷贝
5、Es6 编译的时候接口, 输出值的引用
****const let声明的变量
es5中 var声明的全局变量挂在全局对象的属性上,所以课哟window.x访问
Es6中 const let声明的变量在一个块级作用域(script)中
****经典题 从4444改成输出0-3
1、利用setTimeout的第三个参数
2、
****关于浏览器缓存
总的来说:
- 如果开启了Service Worker首先会从Service Worker中拿
- 如果新开一个以前打开过的页面缓存会从Disk Cache中拿(前提是命中强缓存)
- 刷新当前页面时浏览器会根据当前运行环境内存来决定是从 Memory Cache 还是 从Disk Cache中拿(可以看到下图最后几个文件有时候是从 Memory Cache中拿有时候是从Disk Cache中拿)
****BFC
块级格式化上下文,具有BFC的特性的元素,可以看成一个隔离的容器,容器里面的元素在布局上不会影响到外面的元素。也就是说BFC是一个完全封闭的盒子,盒子内部元素无论怎么摆放,都不会影响到盒子外面。
只要触发以下任意一条,就视为具有BFC:
1、body根元素
2、float除了none以外的值
3、position:absolute /fixed
4、overflow 除了visible(hidden/auto/scroll)
5、display:inline-block/table-cell/flex
特性:
1、同一个方向上的margin会重叠,采用大的那个
2、浮动,文字环绕
****opacity, visibility, display 都是让元素不可见,区别
1、display:元素从渲染树消失,不占空间,不能点
2、visibility:hidden 元素不会从渲染树消失,还占用空间,只是不可见,不能点击
3、opacity:0 不会让元素从渲染树消失,只是不可见,占用空间,能点击
1 & 3 不可继承
display: none 修改元素会造成文档回流, 读屏器不会读取元素内容, 性能消耗较大.
visibility: hidden 修改元素只会造成本元素的重绘, 读屏器会读取元素内容, 性能消耗较少.
opacity: 0 修改元素会造成重绘, 性能消耗较少.
****为什么在发送数据埋点的时候一般都使用1x1的gif图片
1、用image天然支持跨域,无跨域问题
2、gif对比png jpg 1x1像素字节更少,几乎无
3、执行过程无阻塞 只要new Image即可,无需插入到dom中
4、比发get请求性能更好
5、图片请求不占用ajax限额
****箭头函数和正常的函数有什么区别
箭头函数其实是不同函数的简写,可以更优雅的定义一个对象,区别如下:
1、箭头函数没有自己的this,定义在哪this就指向哪里,而不是在哪调用就指向哪里
2、不能用arguments 可以用rest代替
3、不可以使用yield命令,因此不可使用generator函数
3、不能new:没有this因此不能apply&call;并且没有prototype,不能把构造函数的prototype赋值给实例的__proto__
****es6转成es5的实现思路是什么
1、es6代码字符串转成es6 AST
2、es6 AST转成es5 AST
3、es5 AST 转成es5代码
一般是用babel,如果不用工具人工写的话 就是使用各种polyfill
****为什么普通 for 循环的性能远远高于 forEach 的性能,请解释原因
for循环没有任何额外的调用栈和上下文,而forEach不是普通的 for 循环的语法糖,还有诸多参数和上下文需要在执行的时候考虑进来,这里可能拖慢性能;
****react 父子组件的生命周期执行顺序:
父组件willMount->子组件willMount->父组件didMount ->子组件didMount
****http2的特性
1、二进制分帧
2、多路复用
3、服务器推送
4、头部压缩
****解决弹层滚动穿透:
1、如果不需要滑动的话就 直接禁用弹层所在父容器的onTouchMove事件
node.addEventListener(“touchMove”,e.preventDefault,false)
2、body 加:fixed+overflow:hidden 注意计算scrollTop的值
****CSR SSR
CSR:
缺点:1、首屏加载慢:三次http请求(加载html/加载js/api请求数据) ;2、单页应用的seo能力几乎为0(搜索引擎只认识html,不认识js)
SSR:缺点:1、性能;2、项目复杂度增加
同构:一套react代码在服务端运行一遍生成html完成页面结构,在浏览器端也运行一遍生成js用于事件绑定,(react-dom 然后用webpack打包成js)
***浏览器渲染UI过程:
1、浏览器获取HTML文件,然后对文件进行解析,形成DOM Tree
2、与此同时,进行CSS解析,生成Style Rules
3、接着将DOM Tree与Style Rules合成为 Render Tree
4、接着布局(Layout)阶段,即为每个节点分配一个应出现在屏幕上的确切坐标
5、随后调用GPU进行绘制(Paint),遍历Render Tree的节点,并将元素呈现出来
注:1、浏览器会从又向左解析css选择器,性能更好,能筛掉大部分不符合规范的节点,节省失败查找的时间