前端场景题

# 前端场景题

# 1. 10000条数据如何渲染?

方案: 看场景选择:

  1. 虚拟列表(按需渲染):只渲染可视区部分,上下可留余量
  2. 虚拟滚动(延迟加载):滚动时往已渲染列表中追加
  3. 分页

全部渲染时可以进行分片:

  1. setTimeout:延时受任务队列影响不准确
  2. requestAnimationFrame:下一次重绘前执行回调 一般一秒60帧

优化细节:每一轮插入DOM时可以先插入到创建的fragment中,使用createDocumentFragment

浅说虚拟列表的实现原理 (opens new window)

列表数据的展示优化 (opens new window)

# 2.图片懒加载的实现

intersectionObserver

图片和视频的懒加载 (opens new window)

# 3. 无感刷新token

  1. 每次请求判断token是否过期,然后刷新

  2. 响应拦截器中判断是否过期,调用接口刷新

注意:刷新过程中还有请求时会导致重复刷新,要利用一个变量标记处于刷新状态。刷新中将其余请求缓冲到一个队列,待刷新完成后再发起。

前端如何实现token的无感刷新 (opens new window)

# 4. 让你来实现一个扫码支付的功能你会怎么实现?

  1. pc请求二维码ID,根据二维码ID生成二维码展示在页面上,服务器端保存二维码ID且设置过期时间
  2. 手机扫描二维码,识别二维码ID,点击确认登录,将设备信息,token,二维码ID等发送到服务器进行验证。验证通过后服务器会设置二维码状态为已登录。
  3. pc轮询获取登录状态

注意:获取登录状态的方式除了轮询外,还有:

  1. 长轮询:服务器端阻塞请求,直到超时或二维码状态改变

  2. 扫码后pc和服务器建立websocket连接,当二维码状态改变后服务器主动通知客户端。

面试官:如何实现扫码登录功能? (opens new window)

# 5. 如何实现上拉加载,下拉刷新?

开源社区也有很多优秀的解决方案,如iscrollbetter-scrollpulltorefresh.js库等等

上拉加载:移动端分页, 判断scrollTop + clientHeight >= scrollHeight - distance

下拉刷新:

  1. 监听touchstart记录属实y坐标
  2. 监听touchmove通过下拉距离判断下拉状态
  3. 监听touchend,页面滚回顶部且刷新

面试官:如何实现上拉加载,下拉刷新? (opens new window)

# 6. 如何在移动端实现 1 px 的线?

  1. 伪元素 + transform: scale

    .b-1px-l:before {
    content: " ";
    position: absolute;
    left: 0;
    top: 0;
    width: 1px;
    bottom: 0;
    border-left: 1px solid #C7C7C7;
    color: #C7C7C7;
    transform-origin: 0 0;
    transform: scaleX(0.5);
    }
    

border-1px (opens new window)

吃透移动端1px (opens new window)

1px问题 (opens new window)

# 7. 一个网页从请求到呈现花了很长时间,如何排查?

主要从浏览器内存占用, DNS解析, 资源请求, js执行, 服务端分析。

面试题|排查网页打开慢的方法有多少种? 我总结了15个 (opens new window)

浏览器请求响应慢,该从哪些方面分析 (opens new window)

# 8. 图片加载优化,优先级

  1. 从架构的角度,将应用服务器和图片服务器分离,防止大量图片请求导致应用服务器崩溃。
  2. HTTP1.0和HTTP1.1在同一时间对同一域名下的资源请求并发数量有限制,可以使用HTTP2绕开这个限制,但是会有被进行DOS攻击的隐患。
  3. 可以为同一IP申请多个域名,请求图片时对域名进行替换,向多个域名发起请求。问题是域名改变了,浏览器缓存失效
  4. 图片压缩,小图片使用base64,对于图片格式可以进行多级处理,支持webp的浏览器可以使用webp,可以使用<picture>标签,在该标签内放置多个<source>标签引用不同格式的图片,以及放一张兜底的img标签,这样浏览器会依次检测支持的图片格式。
  5. CDN
  6. HTTP缓存
  7. 图片懒加载。**怎么做的?**封装了一个vue自定义指令,将该指令绑定到img标签上,并传入图片地址等参数。在懒加载指令的实现上,利用一个web api IntersectionObserver对象,在new对象的回调函数里遍历entries判断intersectionRatio是否大于0,大于0说明进入根元素可视区域,从而给target赋值src属性。**如果浏览器不支持该api怎么做?**直接监听页面scroll事件,通过getBoundingClientRect获取img元素,如果top值小于可是区域高度则赋值src,然后取消观察该元素。记得给scroll用节流函数包一下。
  8. 渐进式并行图片加载,结合HTTP2和JPEG图片(不是按像素存储)的特点先加载模糊的预览图,再逐渐提高清晰度。
  9. 可以给img标签添加importance="high",让浏览器优先加载

# 9. 单点登录原理(SSO)

使用场景:系统增多以后每个系统都要使用单独的账号密码进行登录,十分繁琐。

实现效果:只需登录多个系统中的一个,就可以访问其它相互信任的系统。

登录流程:

  1. 访问app系统发现没有登录,服务端返回302告诉客户端重定向到SSO进行登录。

  2. 客户端向SSO系统发起请求,SSO系统也没有登录,于是返回登录表单页面

  3. 用户填写登录账号和密码后发送到SSO,SSO服务端接收到以后生成cookie并存储,将cookie携带在set-cookie响应头,同时携带一个service ticker返回一个302响应

  4. 客户端接收到该响应后cookie被设置到SSO的域,然后重定向访问app系统,将service ticker发送给app

  5. app服务端从后台携带ST发送给SSO服务端,SSO验证ST的有效性后,将cookie保存到自己的session然后返回响应登录成功。

当用户再去访问另一个系统b时:

  1. 发送请求到b,b服务器返回302重定向到SSO

  2. b向SSO发起请求,此时SSO已经登录,返回生成的ST以及302重定向到b

  3. 客户端携带ST请求b服务端,b从后台携带ST访问SSO验证是否有效。

  4. 验证成功后在b保存cookie,在b的域写入cookie