SPA单页面应用首屏加载速度慢解决方案
减少入口文件体积(路由懒加载,只有在解析路由时才会加载组件)
静态资源本地存储【后端返回资源:采用http缓存 前端合理利用localStorage】
UI框架按需加载
避免组件重复打包
图片资源压缩(可以使用精灵图)
开启Gzip压缩(拆包后再做gzip压缩)
说说你对事件循环的理解
宏观任务:script、setTimeout、setInterval、setImmediate、I/O、UI rendering
微观任务:promise、Object.observe、MutationObserver
任务的优先级:同步代码=》promise.then=》setTimeout=》setImmediate
事件循环就是事件执行顺序的概念化
同步任务直接进入主线程,异步任务进入异步队列,主线程内的任务执行完后,会去执行异步队列中的任务,异步任务又分为宏任务和微任务,先执行微任务,在执行宏任务。这一执行过程不断重复就是事件循环
说说javascript内存泄露的几种情况
内存泄漏:由于疏忽或者错误造成程序未能释放已经不再使用的内存
意外的全局变量(严格模式进行检测【函数内部定义全局变量】)
定时器(不用的时候及时清理)
闭包(赋值为null)
事件监听(在不使用的时候取消事件监听)
大文件如何做断点续传
断点续传:在下载或者上传时,将下载或上传任务人为的划分为几部分
每一部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经或者下载的部分分开开始续上传下载未完成的部分,而没有必要从头开始上传下载,用户可以节省时间,提高速度
实现方式:
服务器端返回,告知从哪里开始
浏览器端自行处理
上传过程中将文件载服务器写为临时文件,等全部写完了(文件上传完毕),将此临时文件重命名为正式文件即可
如果中途上传中断过,下次上传的时候根据当前临时文件大小,作为在客户端读取文件的偏移量,从此位置继续读取文件数据块,上传到服务器从此偏移量继续写入文件即可
使用场景:
大文件加速上传:当文件大小超过预期大小时,使用分片上传可实现并行上传多个part,以加快上传速度
网络环境较差:建议使用分片上传,当出现上传失败的时候,仅需重传失败的part
流式上传:可以在需要上传的文件大小还不确定的情况下开始上传,这种场景监控等行业应用中比较常见
参考文献:
原生js如何实现上拉加载下拉刷新
上拉加载:本质时页面的触底加载,或者快要触底时的动作
触底公式:scrollTop + clientHeight >= offsetTop
下拉刷新:本质是页面本身置于顶部时,用户下拉时需要触发的动作,主要分为三个步骤:
- 监听原生touchstart事件,记录其初始位置的值,e.touches[0].pageY;
- 监听原生touchmove事件,记录并计算当前滑动的位置值与初始位置值的差值,大于0表示向下拉动,并借助CSS3的translateY属性使元素跟随手势向下滑动对应的差值,同时也应设置一个允许滑动的最大值;
- 监听原生touchend事件,若此时元素滑动达到最大值,则触发callback,同时将translateY重设为0,元素回到初始位置。
说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别
设备像素:
设备像素(device pixels),又称为物理像素
指设备能控制显示的最小物理单位,不一定是一个小正方形区块,也没有标准的宽高,只是用于显示丰富色彩的一个“点”而已
可以参考公园里的景观变色彩灯,一个彩灯(物理像素)由红、蓝、绿小灯组成,三盏小灯不同的亮度混合出各种色彩
从屏幕在工厂生产出的那天起,它上面设备像素点就固定不变了,单位为pt
css像素:
设备独立像素:
设备独立像素(Device Independent Pixel):与设备无关的逻辑像素,代表可以通过程序控制使用的虚拟像素,是一个总体概念,包括了CSS像素
在javaScript中可以通过window.screen.width/ window.screen.height 查看
比如我们会说“电脑屏幕在 2560x1600分辨率下不适合玩游戏,我们把它调为 1440x900”,这里的“分辨率”(非严谨说法)指的就是设备独立像素
一个设备独立像素里可能包含1个或者多个物理像素点,包含的越多则屏幕看起来越清晰
至于为什么出现设备独立像素这种虚拟像素单位概念,下面举个例子:
iPhone 3GS 和 iPhone 4/4s 的尺寸都是 3.5 寸,但 iPhone 3GS 的分辨率是 320x480,iPhone 4/4s 的分辨率是 640x960
这意味着,iPhone 3GS 有 320 个物理像素,iPhone 4/4s 有 640 个物理像素
如果我们按照真实的物理像素进行布局,比如说我们按照 320 物理像素进行布局,到了 640 物理像素的手机上就会有一半的空白,为了避免这种问题,就产生了虚拟像素单位
我们统一 iPhone 3GS 和 iPhone 4/4s 都是 320 个虚拟像素,只是在 iPhone 3GS 上,最终 1 个虚拟像素换算成 1 个物理像素,在 iphone 4s 中,1 个虚拟像素最终换算成 2 个物理像素
至于 1 个虚拟像素被换算成几个物理像素,这个数值我们称之为设备像素比,也就是下面介绍的dpr
dpr:dpr(device pixel ratio),设备像素比,代表设备独立像素到设备像素的转换关系,在JavaScript中可以通过 window.devicePixelRatio 获取
ppi:ppi (pixel per inch),每英寸像素,表示每英寸所包含的像素点数目,更确切的说法应该是像素密度。数值越高,说明屏幕能以更高密度显示图像
小结:
无缩放情况下,1个CSS像素等于1个设备独立像素
设备像素由屏幕生产之后就不发生改变,而设备独立像素是一个虚拟单位会发生改变
PC端中,1个设备独立像素 = 1个设备像素 (在100%,未缩放的情况下)
在移动端中,标准屏幕(160ppi)下 1个设备独立像素 = 1个设备像素
设备像素比(dpr) = 设备像素 / 设备独立像素
每英寸像素(ppi),值越大,图像越清晰
参考文献:
- https://developer.mozilla.org/zh-CN/docs/Glossary/CSS_pixel
- https://hijiangtao.github.io/2017/07/09/Device-Viewport-and-Pixel-Introduction/
谈谈你对BFC的理解
BFC就是一个块级容器,它会隔离外部,让盒子里面的元素不影响外面的元素,也就是在搭建页面的时候,不影响外面的布局。
为什么要知道BFC?
因为在页面的时候可能会发现,为什么会高度塌陷,为什么边距不是我想要的等系列问题
当内部元素使用浮动的时候,外面盒子计算不到高度,就会导致高度塌陷
如果两个块级盒子都设置了margin值,两个盒子相邻的那一边的maragin会重叠,比如第一个盒子设置margin:10px,第二个盒子设置为20px,他们之间的边距不是30px,而是20px,那么这时候我们就需要使用BFC来解决这些问题
BFC特性
1、属于同一个BFC的两个相邻容器的上下margin会重叠(重点)
2、计算BFC高度时浮动元素也参于计算(重点)
3、BFC的区域不会与浮动容器发生重叠(重点)
4、BFC内的容器在垂直方向依次排列
5、元素的margin-left与其包含块的border-left相接触
6、BFC是独立容器,容器内部元素不会影响容器外部元素
BFC解决的问题
解决边距重叠的问题
解决高度塌陷的问题
解决相邻盒子浮动区域重叠的问题
BFC常用功能总结
可以利用BFC解决两个相邻元素的上下margin的重叠问题
可以利用BFC解决高度塌陷的问题
可以利用BFC实现多栏布局
说说TCP为什么需要三次握手和四次挥手
三次握手:
可以阻止重复历史连接的初始化
可以同步双方的初始序列号
可以避免资源的浪费
四次挥手:
因为在关闭连接时,客户端向服务端发送FIN时,仅仅表示客户端不再发送数据了,但是还能接收数据
服务器收到客户端的FIN报文时,先回一个ACK应答报文,而服务端可能还有数据需要处理,等服务端不再发送数据时,才发送FIN,给客户端来表示同意现在关闭连接
前端性能优化的手段有哪些
前端性能优化分为两类:
1.文件加载更快:
① 让传输的数据包更小(压缩文件/图片):图片压缩和文件压缩
②减少网络请求的次数:雪碧图/精灵图、节流防抖
③减少渲染的次数:缓存(HTTP缓存、本地缓存、Vue的keep-alive缓存等)
2.文件渲染更快:
①提前渲染:ssr服务器端渲染
②避免渲染阻塞:CSS放在HTML的head中 JS放在HTML的body底部
③ 避免无用渲染:懒加载
④ 减少渲染次数:对dom查询进行缓存、将dom操作合并、使用减少重排的标签
什么是强缓存和协商缓存
强缓存是利用http请求头中的Expires和Cache-Control两个字段来进行控制,用来表示资源的缓存时间;浏览器不会像服务器发送任何请求,直接从本地缓存中读取文件并返回Status Code: 200 OK;
协商缓存是服务器用来确定缓存资源是否可用过期,向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源