面试准备ing
- 参考文档
- DOM特性1
- HTML5特性2
- JavaScript以函数对象为核心,函数又称为
first-calss objects
,first-class citizens
- JS基础面经巩固
-
路由原理,为什么要使用路由3,有hash为什么还要history?
路由用于设定访问路径,并将路径和组件映射起来。路由的本质就是建立url和页面之间的映射关系。
- hash
URI4 中的 fragment 用来标识次级资源,https://domain/index#L18
,L18是fragment的值。fragment 的改变不会触发浏览器刷新页面,但是会生成浏览历史。- 单页面路由,通过
location.hash
操作URI的fragment,可通过HashChange
事件监听fragment
变化 - HTML锚点,页面内定位,将页面滚动到该锚点的位置
- fragment会被谷歌浏览器忽略,使用hash的应用SEO效果不友好
- 支持回车刷新
- 对低版本支持度更好
- 单页面路由,通过
- history
- hash本来是做页面内定位的,如果将其用于路由,原来的锚点功能就不能使用了。history模式不仅可以在url放参数,还可以将数据存放在一个特定的对象中。
- 回车刷新错误
- 切换,
go
、back
、forward
- 修改历史状态
- 不会刷新路由
- 前端路由出现面向的需求
- 路由就是根据不同的url地址来展示不同的页面或内容的功能
- hash
-
hook为什么不可以出现在控制语句中,为什么要用链表或者数组,用别的数据结构可以吗?
Vue3 Hooks函数实现原理
- 将各个生命周期的函数挂载或者注册到组件实例上,等到组件运行到某个时候,再去组件实例上把对应的生命周期的函数取出来执行,其生命周期的执行过程和
Vue Scheduler
相关。 createHook
是一个闭包函数,通过闭包获取组件实例相关状态,其底层是调用injectHook
函数。挂载过程是同步的,但是onMounted
函数执行是异步的,通过异步执行 onMounted 能够确保所有的节点已经全部挂载完毕。
// packages/runtime-core/src/apiLifecycle.ts export function injectHook(type, hook, target) {if(target) {// 把各个生命周期的Hooks函数挂载到组件实例上,并且是一个数组,因为可能你会多次调用同一个组件的同一个生命周期函数const hooks = target[type] || (target[type] = [])// 把生命周期函数进行包装并且把包装函数缓存在__weh上const wrappedHook =hook.__weh ||(hook.__weh = (...args: unknown[]) => {if (target.isUnmounted) {return}// 当生命周期调用时 保证currentInstance是正确的setCurrentInstance(target)// 执行生命周期Hooks函数const res = args ? hook(...args) : hook()unsetCurrentInstance()return res})// 把生命周期的包装函数绑定到组件实例对应的hooks上hooks.push(wrappedHook)// 返回包装函数return wrappedHook} }
hooks
不能出现在控制语句中原因
a.hooks
为了在组件中引入状态,引入了有序表或数组
b. 函数本身不能保存状态,我们需要额外维护一个有序的表,在执行 useState 之类的 hook 时,将它们保存到这个表里,这要求每次函数组件的 hook 执行的位置相同,数量正确
- 将各个生命周期的函数挂载或者注册到组件实例上,等到组件运行到某个时候,再去组件实例上把对应的生命周期的函数取出来执行,其生命周期的执行过程和
-
网络
DNS域名解析过程:
- 检查浏览器缓存
- 检查操作系统缓存
- 检查路由器缓存
- 若无,向ISP的LDNS服务器查询
- 若无,向根域名服务器请求解析
CDN工作原理:
- DNS对域名进行解析得到IP
- 浏览器发送数据请求
- 服务器向浏览器返回响应数据
-
性能优化
懒加载:延迟加载、按需加载,在长网页中延迟加载图片数据,是一种较好的网页性能优化的方式。在滚动屏幕之前,可视化区域之外的图片不会进行加载,在滚动屏幕时才加载。
原理:使用HTML5 的data-xxx
属性来储存图片的路径,在需要加载图片的时候,将data-xxx
中图片的路径赋值给src
,这样就实现了图片的按需加载,即懒加载<script> var imgs = document.querySelectorAll('img'); function lozyLoad(){var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;var winHeight= window.innerHeight;for(var i=0;i < imgs.length;i++){if(imgs[i].offsetTop < scrollTop + winHeight ){imgs[i].src = imgs[i].getAttribute('data-src');}} } window.onscroll = lozyLoad(); </script>
预加载:将所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。
原理:使用HTML5 的data-xxx
属性来储存图片的路径,在需要加载图片的时候,将data-xxx
中图片的路径赋值给src
,这样就实现了图片的按需加载,即懒加载 -
回流与重绘
回流触发:1. 全局范围 2. 局部范围
- 页面首次渲染
- 浏览器的窗口大小发生变化
- 元素的尺寸或者位置发生变化
- 元素的字体大小发生变化
- 激活CSS伪类
- 添加或者删除可见的DOM元素
重绘:元素样式发生改变,但元素在文档流中的位置未发生改变
- color、background 、background-color、background-image 、outline 、outline-color、outline-width 、text-decoration、border-radius、visibility、box-shadow
性能提升:
- 操作低层级的DOM节点进行操作
- table布局易重新布局
- 原生css表达式
- 不要频繁操作元素的样式,更改类名
- 使用 absolute 或 fixed
display: none
隐藏元素- DOM操作放一起执行
-
防抖与节流
- 函数防抖5是指在事件被触发 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。这可以使用在一些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。
- 函数节流6是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。
-
Web Worker“多线程”技术7
- 在 HTML5 的新规范中,实现了 Web Worker 来引入 JavaScript 的 “多线程” 技术,他的能力让我们可以在页面主运行的 JavaScript 线程中加载运行另外单独的一个或者多个 JavaScript 线程;
- Web Worker 提供的多线程编程有以下几个特点
1. 主程序线程和 Worker 线程之间,Worker 线程之间不会共享任何作用域或资源
2. 通信方式:基于事件监听机制的message
3. 对于 JavaScript 语言,Web Worker 只是浏览器(宿主环境)提供的一个能力/API
4. Web Worker 的实现为前端程序带来了后台计算的能力,可以实现主 UI 线程与复杂计运算线程的分离,从而极大减轻了因计算量大而造成 UI 阻塞而出现的界面渲染卡、掉帧的情况,并且更大程度地利用了终端硬件的性能;
-
用户访问网址浏览器执行的过程
- 域名查询DNS,本设备->路由器缓存->ISP网络服务商->根节点
- 浏览器做出界面响应
- DOM Tree解析、CSS Tree解析【如遇到JS脚本节点,停止HTML和DOM构建->执行请求得到的JS脚本】
- JS请求,DOM停止解析
- 对DOM + CSS Tree生成布局,执行JS操作布局
- 监控事件队列,一次只能处理其中的一个事件(响应界面交互)【此时才进行事件队列的创建】
- 浏览器事件、网络事件、用户事件、计时器事件
-
函数声明和函数表达式
function fn{}
因为函数会有提升,声明之前调用并不会出错var fn = function() {}; fn();
函数表达式的函数名可要可不要,但是函数表达式的调用一定是在赋值之后,不然之前调用会引发错误
-
-
https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model ↩︎
-
https://developer.mozilla.org/en-US/docs/Glossary/HTML5 ↩︎
-
路由方便我们对大型应用进行集成管理,逻辑切换以及权限管理等,尤其是针对三维应用,可以借助对应的生命周期函数实现对应的切换效果,及时的关闭和销毁对应的三维实体。 ↩︎
-
Uniform Resource Identifier 统一资源标识符 ↩︎
-
按钮提交场景:防⽌多次提交按钮,只执⾏最后提交的⼀次。服务端验证场景:表单验证需要服务端配合,只执⾏⼀段连续的输⼊事件的最后⼀次,还有搜索联想词功能类似⽣存环境请⽤lodash.debounce ↩︎
-
拖拽场景:固定时间内只执⾏⼀次,防⽌超⾼频次触发位置变动。缩放场景:监控浏览器resize。动画场景:避免短时间内多次触发动画引起性能问题 ↩︎
-
https://zhuanlan.zhihu.com/p/25184390 ↩︎