挑战一轮大厂后的面试总结 (含六个方向) - 浏览器 篇

在去年末开始换工做,直到如今算是告了一个段落,断断续续的也面试了很多公司,如今回想起来,那段时间经历了被面试官手撕,被笔试题狂怼,悲伤的时候差点留下没技术的泪水。javascript

这篇文章我打算把我找工做遇到的各类面试题(每次面试完我都会总结)和我本身复习遇到比较有意思的题目,作一份汇总,年后是跳槽高峰期,也许能帮到一些小伙伴。css

先说下这些题目难度,大部分都是基础题,由于这段经历给个人感受就是,无论你面试的是高级仍是初级,基础的知识必定会问到,甚至会有必定的深度,因此基础仍是很是重要的。html

我将根据类型分为几篇文章来写:前端

面试总结:javascript 面试点汇总(万字长文)(已完成) 【强烈你们看看这篇,面试中 js 是大头】vue

面试总结:nodejs 面试点汇总(已完成)html5

面试总结:浏览器相关 面试点汇总(已完成)java

面试总结:css 面试点汇总(已完成)node

面试总结:框架 vue 和工程相关的面试点汇总(已完成)jquery

面试总结:非技术问题汇总(已完成)css3

我会抓紧时间把未完成的总结补全的~

这篇文章是对 浏览器 相关的题目作总结,欢迎朋友们先收藏在看。

先看看目录

目录

介绍下缓存

全部的性能优化中,缓存是最重要也是最直接有效的,毕竟如今都这么忙,可等不了网页转菊花。

缓存分为强缓存和协商缓存,看下流程图

cache

缓存机制相关的字段都是在请求和响应头上

强缓存

强缓存,在缓存有效期内,客户端直接读取本地资源。

强缓存返回的状态码是 200

Expires

http1.0 中使用,表示资源失效的具体时间点 Expires:Sat, 09 Jun 2018 08:13:56 GMT ,如果访问器和本地时间不一致,可能就会出现问题,在如今 http1.1中换成了 max-age ,为了兼容也能够加上。

Cache-control

指定指令来实现缓存机制,多个指令间逗号分隔,常见的指令有如下几个,完整的可点击下文中的 mdn 链接查看

max-age: 强缓存的有效时间,单位秒 max-age=30672000

no-cache:使用缓存协商,先与服务器确认返回的响应是否被更改。

no-store:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源,可用于关闭缓存。

public :代表响应能够被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存,即便是一般不可缓存的内容(例如,该响应没有max-age指令或Expires消息头)。

private :代表响应只能被单个用户缓存,不能做为共享缓存(即代理服务器不能缓存它)。私有缓存能够缓存响应内容。

强缓存

强缓存,在缓存有效期内,客户端直接读取本地资源。

强缓存返回的状态码是 200

Expires

http1.0 中使用,表示资源失效的具体时间点 Expires:Sat, 09 Jun 2018 08:13:56 GMT ,如果访问器和本地时间不一致,可能就会出现问题,在如今 http1.1中换成了 max-age ,为了兼容也能够加上。

协商缓存

协商缓存,关键在于协商,在使用本地缓存以前,须要先跟服务器作个对比,服务器告知你的资源可用,是最新的,那就能够直接取本地资源,反之,服务器返回最新的资源给客户端,客户端收到后更新本地资源。

状态码:

  • 若本地资源是最新的,那么返回 304 (考点!)
  • 若比对后,须要从服务器获取最新资源,那就是正常的 200
Last-modified If-Modified-Since

采用资源最后修改时间来判断,单位精度秒

Last-Modified:服务器资源的最新更新时间 Tue, 14 Jan 2020 09:18:29 GMT

If-Modified-Since:客户端发起协商,把本地记录的文件更新时间传给服务器,服务器进行判断比较

这个判断方式是 http1.0 的产物,由于时间精度是秒,若文件的更新频率在秒级之内,就会出现文件不一致。

ETag If-None-Match

为了解决上面的那个问题, http1.1 加了这组标记

ETag:服务器根据内容生成惟一的字符串标识

If-None-Match:客户端发起协商,把本地记录的 hash 标识传给服务器,服务器进行判断比较。

若同时存在 Last-ModifiedETag , ETag 的优先级更高。

浏览器缓存存放位置

browser-cache

可看到有两个来源:

memory cache:内存中读取

disk cache:硬盘中读取

内存固然要比硬盘读取快,为啥会有存放硬盘呢?

由于内存浏览器内存有限啊,因此浏览器会有一套机制,根据文件大小何使用频率存放不一样的位置,具体的实现取决于浏览器厂商,不过这微小对用户是无感知的。

参考文档

developer.mozilla.org/zh-CN/docs/…

了解 PWA 么

PWA(Progressive web apps,渐进式 Web 应用)运用现代的 Web API 以及传统的渐进式加强策略来建立跨平台 Web 应用程序。(来自 MDN)

先看看 PWA 有哪些核心技术,就知道它有哪些优点了

App Shell

App Shell 架构是构建 Progressive Web App 的一种方式,这种应用能可靠且即时地加载到您的用户屏幕上,与本机应用类似。

这个模型包含界面所须要的最小资源文件,若是离线缓存,能够确保重复访问都有快速响应的特性,页面可快速渲染,网络仅仅获取数据。

或者这么理解, App Shell 就相似于原生app,没网络也能够本地启动。

ServiceWork

PWA 的核心,上面说到缓存可让页面尽快加载,但必须有网络的状况下才行,没网络下还想加载网页咋办?

ServiceWork 持久的离线缓存的能力就能够实现。

Service Worker 有如下功能和特性:

  • 一个独立的 worker 线程,独立于当前网页进程,有本身独立的 worker context

  • 一旦被 install,就永远存在,除非被手动 unregister

  • 用到的时候能够直接唤醒,不用的时候自动睡眠

  • 可编程拦截代理请求和返回,缓存文件,缓存的文件能够被网页进程取到(包括网络离线状态)

  • 离线内容开发者可控

  • 能向客户端推送消息

  • 不能直接操做 DOM

  • 必须在 HTTPS 环境下才能工做

  • 异步实现,内部大都是经过 Promise 实现

js 是单线程的,ServiceWork 独立线程意味着不会阻塞js执行;可编程拦截代理请求和返回,可自定义文件缓存策略。

这些特色意味着开发者有足够的权限去操做缓存,让缓存作到优雅,效率达到极致

接下来核心是如何让设计缓存策略,

  1. 缓存优先,先查询缓存,若存在,直接返回,不存在,请求服务,更新缓存
  2. 服务端优先,不查询缓存,直接请求服务端,服务端失败才会查询缓存
  3. 稳定优先,先查询缓存,有就读取,同时请求服务端更新资源

推荐你们看看开源的 wordbox 封装的缓存策略,策略更加丰富。

代码不复杂,主要是声明周期、与js线程间通讯、api调用,就不贴上来了。

参考文档:

lavas.baidu.com/pwa/offline…

developer.mozilla.org/zh-CN/docs/…

URL 输入到渲染的过程

  1. 域名解析,找到服务地址
  2. 构建 TCP 链接,如有 https,则多一层 TLS 握手,
  3. 特殊响应码处理 301 302
  4. 解析文档
  5. 构建 dom 树和 csscom
  6. 生成渲染树:从DOM树的根节点开始遍历每一个可见节点,对于每一个可见的节点,找到CSSOM树中对应的规则,并应用它们,根据每一个可见节点以及其对应的样式,组合生成渲染树
  7. Layout(回流):根据生成的渲染树,进行回流(Layout),获得节点的集合信息
  8. Painting(重绘):根据渲染树及其回流获得的集合信息,获得节点的绝对像素。
  9. 绘制,在页面上展现,这一步还涉及到绘制层级、GPU相关的知识点
  10. 加载js脚本,加载完成解析js脚本

这是一个大体的流程,面试官会从中挑出其余点来接着问

重绘和回流(重排)

先看这图,html文档 和 css 渲染过程的图

layout

页面是采用流式布局来绘制,左到右,上到下,那么一个节点的空间属性如果发生了变化,那么会影响到其余节点的空间布局,须要从新收集节点信息,在进行绘制,这就是回流的过程。

重绘指的是对元素的外观作处理,好比颜色、背景、阴影等。

因此回流必定触发重绘。

触发回流的场景

获取位置信息或者修改几何属性,以下:

  • 添加或删除可见的DOM元素
  • 元素的位置发生变化
  • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
  • 内容发生变化,好比文本变化或图片被另外一个不一样尺寸的图片所替代。
  • 页面一开始渲染的时候(这确定避免不了)
  • 浏览器的窗口尺寸变化(由于回流是根据视口的大小来计算元素的位置和大小的)
  • 获取位置信息,由于须要回流计算最新的值
// 获取位置信息相关属性
- offsetTop offsetLeft offsetWidth offsetHeight 相对于父级容器的偏移量
- scrollTop scrollLeft scrollWidth scrollHeight 相对于父级容器滚动上去的距离
- clientTop clientLeft clientWidth clientHeight 元素边框的厚度
- getComputedStyle()
- getBoundingClientRect
复制代码

回流的优化

对树的局部甚至全局从新生成是很是耗性能的,因此要避免频繁触发回流

  • 现代浏览器已经帮咱们作了优化,采用队列存储屡次的回流操做,而后批量执行,但获取布局信息例外,由于要获取到实时的数值,浏览器就必需要清空队列,当即执行回流。
  • 编码上,避免连续屡次修改,可经过合并修改,一次触发
  • 对于大量不一样的 dom 修改,能够先将其脱离文档流,好比使用绝对定位,或者 display:none ,在文档流外修改完成后再放回文档里中
  • 经过节流和防抖控制触发频率
  • css3 硬件加速,transform、opacity、filters,开启后,会新建渲染层

开启GPU加速的方法

开启后,会将 dom 元素提高为独立的渲染层,它的变化不会再影响文档流中的布局。

  • transform: translateZ(0)
  • opacity
  • filters
  • Will-change

说下对 http 协议的了解

http 是创建在 TCP 上的应用层协议,超文本传送协议。

是单向的短连接,目前有 http1.0 http 1.1 http2.0

http1.0 :客户端的每次请求都要求创建一次单独的链接,在处理完本次请求后,就自动释放链接。 http1.1 :能够在一次链接中处理多个请求,而且多个请求能够重叠进行,不须要等待一个请求结束后再发送下一个请求 http2.0 :可支持多路复用,一个 tcp 可同时传输多个 http 请求,头部数据还作了压缩

面试官问这个通常是更关注对 tcp 的理解

tcp

tcp 是传输层协议,它的特色是:三次握手和四次挥手。

三次握手的目的是为了防止已经失效的链接请求报文段忽然又传到服务端,而产生错误,因此要创建可靠的链接发送数据

三次握手创建链接过程:

  1. 客户端发送位码为syn=1,随机产生数据包到服务器,服务器由SYN=1知道客户端要求创建联机(客户端:我要链接你)
  2. 服务器收到请求后要确认联机信息,向A发送ack number=(客户端的seq+1),syn=1,ack=1,随机生成数据包(服务器:好的,你来连吧)
  3. 客户端收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ack是否为1,若正确,客户端会再发送ack number=(服务器的seq+1),ack=1,服务器收到后确认seq值与ack=1则链接创建成功。(客户端:好的,我来了)

四次挥手断开链接的过程:

  1. 客户端发送请求给服务端,申请主动断开链接,进入等待状态,不在往服务端发送数据,可是接收数据(客户端:我要断开链接了)
  2. 服务端收到后,告知客户端知道了,服务端进行等待状态,不在接收数据,可是能够继续发送数据(服务端:好,我知道了,可是要等一等)
  3. 客户端收到服务端的告知后,进入下一阶段的等待。(客户端:好,我等)
  4. 服务端完成剩余数据的发送后,告知客户端能够断开了,服务端不接收和读取数据(服务端:你能够断开了)
  5. 客户端收到后,告知服务端,已收到,而后释放连接(客户端:好的,我断开连接了)
  6. 服务端收到后,也释放连接

UDP

传输层的另一个协议 UDP 称为用户数据报协议,无链接的传输协议。

UDP 是报文的搬运工,不须要创建彻底可靠的连接,不保证数据的可靠性,由于协议控制项比较少,且报文头部简单,报文体积相对要小,速度上相比更快,实时性更高,好比电话会议、多媒体数据流等场景就采用 UDP

介绍下 https

http 报文传输过程当中是明文的,能够经过抓包的方式看到报文内容,这就暴露一个安全问题,易被劫持篡改。

为了解决这个问题,就有了 TLS ,https = http + TLS

TLS:安全传输层协议,用于在两个通讯应用程序之间提供保密性和数据完整性,该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。

TLS 利用非对称加密演算来对通讯方作身份认证,以后交换对称密钥做为会谈密钥(Session key),所以 https 分为两个阶段

  1. 经过非对称加解密确认对方身份是否合法,若合法生成会话密钥。(这一步是核心)
  2. 报文的在发送前,先用会话密钥进行对称加密,在传输。

TLS 握手

步骤以下:

  1. 客户端请求服务端创建SSL连接,服务端并向客户端发送一个随机数 randomC 和 CA 机构颁发的证书(注:CA相关下面详细介绍)
  2. 客户端对证书进行验证,验证经过后,生成一个随机数 randomS ,用公钥对 randomS 加密 ,同时用 randomS 生成一段签名,发送给服务端
  3. 服务端接收到后,用私钥对秘文解密,用解密后的 key 生成签名,并与客户端传来的签名进行比较,检验经过后,而后生成一个随机数 randomP ,并用私钥加密,还有随机数生成的 hash 值,一并发给客户端。
  4. 客户端用公钥解密,并校验 hash 值经过后,两端利用 randomC randomS randomP 经过必定的算法生成 session key,后续的报文将经过 session key 对称加密进行传输。

对前端来讲,毕竟偏向于理论,因此建议你们根据步骤画一画流程图,更利于理解记忆。

CA 证书

上面第一步讲到 CA证书,假如没有证书验证这一环节,那么公钥在传输过程极有可能被中间人拦截,来个狸猫换太子,将服务端的公钥换成它本身的公钥,返回给客户端,这么一来,就彻底起不到加密的做用了,也就是中间人攻击。

因此就须要一个验证的机制,保证公钥是来自服务端的,没有被篡改的,CA证书就出场了。

CA证书,是由 CA 机构颁发的一个凭证,里面关键的信息有,签名算法、签名hash算法、颁发者、有效期、公钥、指纹,这个两个算法就表示对称阶段和非对称阶段采用的算法,公钥就是服务端的公钥,在申请的时候,企业须要上传公钥给CA机构,重点是这个指纹,这个指纹是由 CA 机构经过私钥对一段签名加密生成的。

因此经过验证证书是否合法,就知道公钥是否被篡改,那么怎么验证合法呢?

天然是经过证书的指纹。

在浏览器和我的PC中,都预装了顶级的 CA 机构证书和公钥,因此浏览器获取到证书后,经过内置的公钥对指纹进行解密获得签名,而后浏览器也根据一样的规则生成一段签名,两段签名进行比较,验证经过,那么这个证书中公钥就是可信的。

那么这样一来是否是就能够彻底避免了中间人攻击呢?

毕竟顶级的 CA 证书是内置的,仍是有一种方式,你们是否还记得咱们用,咱们是能够用 Fiddle 对 https 进行抓包的,那 Fiddle 算不算中间人呢 ?

Fiddle 之因此能拦截成功是由于,咱们在抓包以前,在咱们本身手机安装一份来自 Fiddle 的证书,也就是客户端本身信任了第三方来源的证书,这么一来客户端天然能解析出 Fiddle 转发出来的报文啦。

因此只要不随意信任第三方证书,基本上是不会发生中间人攻击的。

什么状况会触发 options 请求

options 一般用于,在跨域请求前发起预检请求,以检测请求是否被服务器接受。

跨域请求中分为简单请求和预检请求两种,符合如下条件可视为简单请求:

  • 使用的 HTTP method 是 GET POST HEAD
  • content-type 是 text/plain mutipart/form-data application/x-www-form-urlencode 三种之一
  • 请求头只能包含这些
- Accept
- Accept-Language
- Content-Language
- Content-Type (须要注意额外的限制)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
复制代码

除去简单请求外,其余请求就会先触发预检请求。

常见的,好比使用

  • content-Type 为 application/xml 或 text/xml 的 POST 请求
  • 设置自定义头,好比 X-JSON、X-MENGXIANHUI 等

预检请求返回的头部报文中有

Access-Control-Allow-Origin: 服务器可接受的请求来源

Access-Control-Request-Method: 服务器实际请求所使用的 HTTP 方法

Access-Control-Request-Headers: 服务器实际请求所携带的自定义首部字段。

客户端基于从预检请求得到的信息来判断,是否继续执行跨域请求。

注意:跨域请求若想发送 cookie 信息,须要服务端设置 resp.setHeader("Access-Control-Allow-Credentials","true"); 客户端设置 withCredentials: true

参考资料: cloud.tencent.com/developer/n…

http有哪些常见请求头

直接看图

rquest-head

response-head

报文提交 Content-Type 的几种区别

Content-Type 字段来获知请求中的消息主体是用何种方式编码

Content-Type: application/json : json 字符串 Content-Type: application/x-www-form-urlencoded : & 将 key=value 进行拼接, jquery 默认使用这个 Content-Type: multipart/form-data : 经常使用于文件上传

关于前端安全防范

主要有两类 XSS CSRF

XSS

跨站脚本攻击,攻击者将一段可执行的代码注入到网页中,如连接、输入框,分为持久形和临时性的,持久性的是恶意代码被存储到数据库里,会形成持久的攻击;临时性的是仅在当前被工具页面上生效;

防范的方式是对与网页上获取的内容要作转义处理。

CSRF

跨站请求伪造,构造一个钓鱼网站,利用站点对浏览器的信任,从而欺骗用户,发起请求进行恶意操做。

用户在浏览器登陆后,站点是信任浏览器的,但浏览器是无法知道请求是不是用户自愿发起的,站点信任后,所发起的请求浏览器都是信任的。

那么用户是已登陆的状况下,钓鱼站点中发起跨域请求,跨域标签或者 form 表单,就会把用户的认证信息 cookies 带上,从而到达伪造用户身份进行攻击。

防范方式:

  1. 服务端校验 Referer ,但某些浏览器可能能够修改 Referer
  2. 随机 token ,每访问页面就生成一个 token ,页面中的请求把这个 token 带上,服务端对 token 进行校验。注意这个 token 不能存储在 cookie 中

关于 xss csrf 网上有很详细的介绍,不过核心原理仍是比较简单的。

了解 CORB

第一次听到有点懵,由于是 CORS ,回来查了资料才明白。

CORB 是一种判断是否要在跨站资源数据到达页面以前阻断其到达当前站点进程中的算法,下降了敏感数据暴露的风险。是站点隔离的一种实现机制,针对跨域标签,保护站点资源。

当跨域请求回来的数据 MIME type 同跨域标签应有的 MIME 类型不匹配时,浏览器会启动 CORB 保护数据不被泄漏,被保护的数据类型只有 html xml json

MIME type

MIME 是一个互联网标准,扩展了电子邮件标准,使其能够支持更多的消息类型。常见 MIME 类型如:text/html text/plain image/png application/javascript ,用于标识返回消息属于哪种文档类型。写法为 type/subtype。 在 HTTP 请求的响应头中,以 Content-Type: application/javascript; charset=UTF-8 的形式出现,MIME type 是 Content-Type 值的一部分

这篇文章写的很是详细,建议你们直接查看 Cross-Origin Read Blocking (CORB)

跨域的解决方案

主流的有一下几种

利用跨域标签 image script 发起 get 方法的跨域请求

  1. image 标签实现
var img = new Image;
img.onload = function() {
},
img.onerror = function() {
},
img.src = options.url;
复制代码
  1. script 标签实现 这个就是常说的 JSONP 。script 会执行返回的字符串,那么能够经过约定一个参数,前端的参数指定一个全局的方法,服务端获取到全局方法后,构造一个执行函数的字符串,并把报文放入函数的参数中。浏览器接收到后以 application/javascript 的方式进行解析,就能够触发预设好的回调函数。
/* html */
let scr = document.createElement('script');
scr.src = `http://127.0.0.1:3500/xx?callback=cb`
document.getElementsByTagName('head')[0].appendChild(scr)
function cb(res){
    console.log('into');
    console.log(res);
}

/* server */ 
let data = { name: 'xiaoli' }
var str = ctx.query.callback + '(' + JSON.stringify(data) + ')';
// ctx.query = {callback:'cb'}
// str = 'cb({"name":"xiaoli"})'
ctx.body = str;
复制代码

反向代理

经常使用 nginx 作反向代理,详细配置就很少说了

CORS

这就全是服务端的工做了,主要的三个参数

Access-Control-Allow-Origin: 服务器可接受的请求来源

Access-Control-Request-Method: 服务器实际请求所使用的 HTTP 方法

Access-Control-Request-Headers: 服务器实际请求所携带的自定义首部字段。

中间层 BFF 作转换

假若有 BFF 层的话,能够在这一层作一个中转,这个就得看项目架构是否有条件了。

html的meta里设置缓存和http请求头设置缓存有什么区别吗

html 的 meta 设置的缓存策略是对于当前文档有效,用于定义页面缓存。

与http的请求参数很相像,就不重复了,详细介绍可参考 设置meta标签 清除页面缓存

history 路由和 hash 路由

hash 路由

hash 路由,在 html5 前,为了解决单页路由跳转问题采用的方案, hash 的变化不会触发页面渲染,服务端也没法获取到 hash 值,前端可经过监听 hashchange 事件来处理hash值的变化

window.addEventListener('hashchange', function(){ 
    // 监听hash变化,点击浏览器的前进后退会触发
})
复制代码

history 路由

history 路由,是 html5 的规范,提供了对history栈中内容的操做,经常使用api有:

window.history.pushState(state, title, url) 
// let currentState = history.state; 获取当前state
// state:须要保存的数据,这个数据在触发popstate事件时,能够在event.state里获取
// title:标题,基本没用,通常传 null
// url:设定新的历史记录的 url。新的 url 与当前 url 的 origin 必须是一樣的,不然会抛出错误。url能够是绝对路径,也能够是相对路径。
//如 当前url是 https://www.baidu.com/a/,执行history.pushState(null, null, './qq/'),则变成 https://www.baidu.com/a/qq/,
//执行history.pushState(null, null, '/qq/'),则变成 https://www.baidu.com/qq/

window.history.replaceState(state, title, url)
// 与 pushState 基本相同,但她是修改当前历史记录,而 pushState 是建立新的历史记录

window.addEventListener("popstate", function() {
    // 监听浏览器前进后退事件,pushState 与 replaceState 方法不会触发 
});
复制代码

js 事件的几种绑定方式

  • 在 dom 元素中直接绑定,<div class="an" onclick="aa()">aaaa</div>
  • js 中绑定 document.getElementById("demo").οnclick=function(){}
  • 添加监听事件 document.addEventListener('name',()=>{})

什么是事件委托

浏览器中的事件触发有三个阶段:

  1. 最从外层开始往里传播,即事件捕获阶段
  2. 事件抵达了目标节点,即目标阶段
  3. 从目标阶段往外层返回,即冒泡阶段

事件委托也叫事件代理,在 dom 节点中,由于有事件冒泡机制,因此子节点的事件能够被父节点捕获。

所以,在适当的场景下将子节点的事件用父节点监听处理,支持的事件 点击事件 鼠标事件监听。

事件代理的优点:

  1. 能够减小监听器的数量,减小内存占用
  2. 对于动态新增的子节点,能够实现事件监听

关于事件捕获和事件冒泡的理解:

事件捕获:事件从外往里传播,addEventListener 最后一个参数设置成 true 就能够捕获事件,默认是 false ,监听事件冒泡。捕获是计算机处理输入的逻辑

事件冒泡:事件由内往外传播,冒泡是人类理解事件的思惟。

target与currentTarget区别

target:指的是事件流的目标阶段,获取的是被点击的元素。

currentTarget:在事件流的捕获和冒泡阶段时,是指向当前事件活动对象,只有在目标阶段的时候,二者才会相等

CSS加载问题

根据页面渲染流程可得知:

  1. css加载不会阻塞DOM树的解析;
  2. css加载会阻塞DOM树的渲染;
  3. css加载会阻塞后面js语句的执行

介绍下资源预加载 prefetch/preload async/defer

prefetch preload

都是告知浏览器提早加载文件(图片、视频、js、css等),但执行上是有区别的。

prefetch :其利用浏览器空闲时间来下载或预取用户在不久的未来可能访问的文档。<link href="/js/xx.js" rel="prefetch">

preload : 能够指明哪些资源是在页面加载完成后即刻须要的,浏览器在主渲染机制介入前就进行预加载,这一机制使得资源能够更早的获得加载并可用,且更不易阻塞页面的初步渲染,进而提高性能。 <link href="/js/xxx.js" rel="preload" as="script"> 须要 as 指定资源类型,目前可用的属性类型有以下:

audio: 音频文件。
document: 一个将要被嵌入到<frame>或<iframe>内部的HTML文档。
embed: 一个将要被嵌入到<embed>元素内部的资源。
fetch: 那些将要经过fetch和XHR请求来获取的资源,好比一个ArrayBuffer或JSON文件。
font: 字体文件。
image: 图片文件。
object: 一个将会被嵌入到<embed>元素内的文件。
script: JavaScript文件。
style: 样式表。
track: WebVTT文件。
worker: 一个JavaScript的web worker或shared worker。
video: 视频文件。
复制代码

js async 和 defer 的区别

用于js脚本预加载

async : 加载脚本和渲染后续文档元素并行进行,脚本加载完成后,暂停html解析,当即解析js脚本

defer : 加载脚本和渲染后续文档元素并行进行,但脚本的执行会等到 html 解析完成后执行

js-async-defer.png

参考资料:

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…

介绍下 viewport

<meta name="viewport" content="width=500, initial-scale=1">

这里只指定了两个属性,宽度和缩放,实际上 viewport 能控制的更多,它能表示的所有属性以下:

  • width:页面宽度,能够取值具体的数字,也能够是 device-width,表示跟设备宽度相等。
  • height:页面高度,能够取值具体的数字,也能够是 device-height,表示跟设备高度相等。
  • initial-scale:初始缩放比例。
  • minimum-scale:最小缩放比例。
  • maximum-scale:最大缩放比例。
  • user-scalable:是否容许用户缩放。

移动端300ms延时的缘由? 如何处理?

由于在之前移动端双击能够缩放或者滑动,因此为了区分是点击仍是双击,加了 300ms 的延迟。

解决方案:

  • css touch-action touch-action的默为 auto,将其置为 none 便可移除目标元素的 300 毫秒延迟 缺点: 新属性,可能存在浏览器兼容问题
  • 利用touchstart和touchend来模拟click事件,缺点有点击穿透
  • fastclick 原理: 在检测到touchend事件的时候,会经过DOM自定义事件当即出发模拟一个click事件,并把浏览器在300ms以后真正的click事件阻止掉
  • 全部版本的Android Chrome浏览器,若是设置viewport meta的值有user-scalable=no,浏览器也是会立刻出发点击事件。

Web Worker

(后续再补上)

浏览器性能监控

使用 performance.timing 这个api就能够获取到绝大部分性能相关的数据

performance

  • navigationStart :在同一个浏览器上下文中,前一个网页(与当前页面不必定同域)unload 的时间戳,若是无前一个网页 unload ,则与 fetchStart 值相等
  • unloadEventStart :前一个网页(与当前页面同域)unload 的时间戳,若是无前一个网页 unload 或者前一个网页与当前页面不一样域,则值为 0
  • redirectStart :第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,不然值为 0
  • redirectEnd :最后一个 HTTP 重定向完成时的时间。有跳转且是同域名内的重定向才算,不然值为 0

开始加载当前页面

  • fetchStart :浏览器准备好使用 HTTP 请求抓取文档的时间,这发生在检查本地缓存以前

网络传输阶段 DNS TCP

  • domainLookupStart :DNS 域名查询开始的时间,若是使用了本地缓存(即无 DNS 查询)或持久链接,则与 fetchStart 值相等
  • domainLookupEnd :DNS 域名查询完成的时间,若是使用了本地缓存(即无 DNS 查询)或持久链接,则与 fetchStart 值相等
  • connectStart :HTTP(TCP) 开始创建链接的时间,若是是持久链接,则与 fetchStart 值相等,若是在传输层发生了错误且从新创建链接,则这里显示的是新创建的链接开始的时间
  • secureConnectionStart :HTTPS 链接开始的时间,若是不是安全链接,则值为 0
  • connectEnd :HTTP(TCP) 完成创建链接的时间(完成握手),若是是持久链接,则与 fetchStart 值相等,若是在传输层发生了错误且从新创建链接,则这里显示的是新创建的链接完成的时间

读取文档阶段

  • requestStart :HTTP 请求读取真实文档开始的时间(完成创建链接),包括从本地读取缓存,链接错误重连时,这里显示的也是新创建链接的时间
  • responseStart :HTTP 开始接收响应的时间(获取到第一个字节),包括从本地读取缓存
  • responseEnd :HTTP 响应所有接收完成的时间(获取到最后一个字节),包括从本地读取缓存

解析文档阶段

  • domLoading :开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件
  • domInteractive :完成解析 DOM 树的时间,Document.readyState 变为 interactive,并将抛出 readystatechange 相关事件
  • domContentLoadedEventStart :DOM 解析完成后,网页内资源加载开始的时间,表明DOMContentLoaded事件触发的时间节点
  • domContentLoadedEventEnd :DOM 解析完成后,网页内资源加载完成的时间(如 JS 脚本加载执行完毕),文档的DOMContentLoaded 事件的结束时间,也就是jQuery中的domready时间;
  • domComplete :DOM 树解析完成,且资源也准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件
  • loadEventStart :load 事件发送给文档,也即 load 回调函数开始执行的时间,若是没有绑定 load 事件,值为 0
  • loadEventEnd :load 事件的回调函数执行完毕的时间,若是没有绑定 load 事件,值为 0

各个阶段时间段查询

DNS查询耗时 = domainLookupEnd - domainLookupStart

TCP连接耗时 = connectEnd - connectStart

request请求耗时 = responseEnd - responseStart

解析dom树耗时 = domComplete - domInteractive

白屏时间 = domloadng - fetchStart

domready时间 = domContentLoadedEventEnd - fetchStart

onload时间 = loadEventEnd - fetchStart

举几个h5的新特性

这个题有点无聊了,但仍是遇到了

  • 新增语义化标签
  • 新增api、本地存储
  • css 边框、背景、动画

对于连续的中文输入有哪些事件

输入框对于输入连续中文的时候可使用如下两个监听事件(第一次知道还有这个事件):

compositionstart:事件触发于一段文字的输入以前(相似于 keydown 事件,可是该事件仅在若干可见字符的输入以前,而这些可见字符的输入可能须要一连串的键盘操做、语音识别或者点击输入法的备选词)。

compositionend:当文本段落的组成完成或取消时,事件将被触发 (具备特殊字符的触发, 须要一系列键和其余输入, 如语音识别或移动中的字词建议)。

相关文章
相关标签/搜索