面试题梳理

梳理一些有趣的面试题,查漏补缺

前端优化

  • 降低请求量:合并资源,减少 HTTP 请求数,minify / gzip 压缩,webP,lazyLoad。
  • 加快请求速度:预解析 DNS,减少域名数,并行加载,CDN 分发。
  • 缓存:HTTP 协议缓存请求,离线缓存 manifest,离线数据缓存 localStorage。
  • 渲染:JS/CSS 优化,加载顺序,服务端渲染,pipeline。

click 在 ios 上有 300ms 延迟,原因及如何解决?

主要原因是 ios 有双击区域放大的功能,所以在第一次 click 后会监测 300ms 看会不会有第二次点击,但是对于只点击一次的操作会有慢了的错觉。

  1. 粗暴型,禁用缩放
  2. 利用 FastClick,其原理是: 检测到 touchend 事件后,立刻出发模拟 click 事件,并且把浏览器 300 毫秒之后真正触发的事件给阻断掉

Cookie 和 session 都可用来存储用户信息,cookie 存放于客户端,session 存放于服务器端, 因为 cookie 存放于客户端有可能被窃取,所以 cookie 一般用来存放不敏感的信息,比如 用户设置的网站主题(防止 xss 获取,可以设置 http-only 使用 https),敏感的信息用 session 存储,比如用户的登陆信息,session 可以 存放于文件,数据库,内存中都可以,cookie 可以服务器端响应的时候设置,也可以客 户端通过 JS 设置
cookie 会在请求时在 http 首部发送给客户端,

大小

cookie 一般在客户端有 大小限制,一般为 4K,

cookie,localstorage,sessionstorage 的区别

  1. 生命周期: Cookie:可设置失效时间,否则默认为关闭浏览器后失效 Localstorage:除非被手动清除,否则永久保存 Sessionstorage:仅在当前网页会话下有效,关闭页面或浏览器后就会被清除
  2. 存放数据: Cookie:4k 左右 Localstorage 和 sessionstorage:可以保存 5M 的信息
  3. http 请求: Cookie:每次都会携带在 http 头中,如果使用 cookie 保存过多数据会带来性能问题 其他两个:仅在客户端即浏览器中保存,不参与和服务器的通信
  4. 易用性: Cookie:需要程序员自己封装,原生的 cookie 接口不友好 其他两个:即可采用原生接口,亦可再次封装
  5. 应用场景: 从安全性来说,因为每次 http 请求都回携带 cookie 信息,这样子浪费了带宽,所以 cookie 应该尽可能的少用,此外 cookie 还需要指定作用域,不可以跨域调用,限制很多,但是 用户识别用户登陆来说,cookie 还是比 storage 好用,其他情况下可以用 storage,localstorage 可以用来在页面传递参数,sessionstorage 可以用来保存一些临时的数据,防止用户刷新 页面后丢失了一些参数。

webpack

介绍下 webpack 热更新原理,是如何做到在不刷新 浏览器的前提下更新页面的

  1. 当修改了一个或多个文件;
  2. 文件系统接收更改并通知 webpack;
  3. webpack 重新编译构建一个或多个模块,并通知 HMR 服务器进行更新;
  4. HMR Server 使用 webSocket 通知 HMR runtime 需要更新,HMR 运行时 通过 HTTP 请求更新 jsonp;
  5. HMR 运行时替换更新中的模块,如果确定这些模块无法更新,则触发整 个页面刷新。

ajax 和 axios、fetch 的区别

传统 Ajax ,核心使用 XMLHttpRequest 对象,多个请求之间如果有先后关系的话,就会出现回调地狱
axios 是一个基于 Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生 XHR 的封装,只不过它是 Promise 的实现版本,符合最新的 ES 规范,它本身具有以下特征: 1.从浏览器中创建 XMLHttpRequest 2.支持 Promise API 3.客户端支持防止 CSRF 4.提供了一些并发请求的接口(重要,方便了很多的操作) 5.从 node.js 创建 http 请求 6.拦截请求和响应 7.转换请求和响应数据 8.取消请求 9.自动转换 JSON 数据

fetch:优点

  1. 语法简洁,更加语义化
  2. 基于标准 Promise 实现,支持 async/await
  3. 同构方便,使用 isomorphic-fetch
  4. 更加底层,提供的 API 丰富(request, response)
  5. 脱离了 XHR,是 ES 规范里新的实现方式

缺点:
1)fetch 只对网络请求报错,对 400,500 都当做成功的请求,服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
2)fetch 默认不会带 cookie,需要添加配置项: fetch(url, {credentials: ‘include’})
3)fetch 不支持 abort,不支持超时控制,使用 setTimeout 及 Promise.reject 的实现的超时控制并不能阻止请求过程继续在后台运行,造成了流量的浪费
4)fetch 没有办法原生监测请求的进度,而 XHR 可以

大文件上传显示进度条

1
2
3
4
5
6
7
//原生获取上传进度的事件

onUploadProgress:(progressEvent) => {
let complete = (progressEvent.loaded / progressEvent.total * 100 | 0) + '%';
console.log('上传 ' + complete)
}

CommonJS 和 Es module

Module 的加载实现

CommonJS 的 require 语法是同步的,当我们使用 require 加载一个模块的时候,必须要等这个模块加载完后,才会执行后面的代码。 NodeJS 是服务端,使用 require 语法加载模块,一般是一个文件,只需要从本地硬盘中读取文件,它的速度是比较快的。但是在浏览器端就不一样了,文件一般存放在服务器或者 CDN 上,如果使用同步的方式加载一个模块还需要由网络来决定快慢,可能时间会很长,这样浏览器很容易进入“假死状态”。所以才有了后面的 AMD 和 CMD 模块化方案,它们都是异步加载的,比较适合在浏览器端使用

差异:

  • CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用;
  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!