常见的浏览器内核有哪些?

Trident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML]

Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等

Presto内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;]

Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]

CSS解析规则

浏览器会从右往左(从下向上-树形)解析CSS选择器

<style>
.header .title span { color: red; }
</style>

浏览器匹配规则如下

  1. 先找到所有的最右节点span,对于每一个span节点,向上寻找节点.title
  2. 继续找.header的节点
  3. 最后找到根元素 html 则结束这个分支的遍历

CSS加载会阻塞DOM吗

  1. CSS不会阻塞DOM的解析,但会阻塞DOM的渲染
  2. CSS会阻塞JS执行,但不会阻塞JS文件的下载

针对第一点,阐明原因

  • DOM和CSSOM通常是并行构建的,所以CSS加载不会阻塞DOM的解析
  • render树是依赖DOM树和CSSOM树的,所以它必须等到两者都加载完毕才能开始构建渲染,所以CSS加载会阻塞DOM的渲染

针对第二点,阐明原因

如果JS脚本的内容是获取元素的样式,那它就必然依赖CSS。因为浏览器无法感知JS内部到底想干什么,为避免样式获取,就只好等前面所有的样式下载完毕再执行JS。但JS文件与CSS文件下载是并行的,CSS文件会在后面的JS文件执行前先加载执行完毕,所以CSS会阻塞后面JS的执行

JS会阻塞页面渲染吗?

  1. JS会阻塞DOM的解析,因此也就会阻塞页面的加载

原因:GUI 渲染线程与 JavaScript 引擎为互斥

DOMContentLoaded与load的区别

DOMContentLoaded:仅当DOM解析完成后触发,不包括样式表,图片等资源

load:当页面上所有的DOM,样式表,脚本,图片等资源加载完毕事触发。

defer和async的区别?

  • 两者都是异步去加载外部JS文件,不会阻塞DOM解析
  • async是在外部JS加载完成后,浏览器空闲时,load事件触发前执行,标记为async的脚本并不保证按照指定他们的先后顺序执行,该属性对于内联脚本无作用
  • defer是在JS加载完成后,整个文档解析完成后,触发 DOMContentLoaded 事件前执行,如果缺少 src 属性(即内嵌脚本),该属性无法起作用

什么是浏览器的同源策略

同源策略是浏览器的一种自我保护行为。所谓的同源指的是:协议,域名,端口均要相同

但是标签不受限制,所有可能会有安全问题

<img src="..." />
<link href="..." />
<script src="..."></script>

如何解决跨域问题?

jsonp

它主要是利用script标签不受浏览器同源策略的限制,可以拿到从其他源传输过来的数据,需要服务端支持。

缺点:就是仅支持get请求,具有局限性,不安全,可能会受到XSS攻击。

跨域资源共享(CORS)

nginx反向代理

通过nginx或者服务器配置 Access-Control-Allow-Origin响应头

浏览器的缓存机制

浏览器缓存分类

分为两种:强缓存协商缓存

浏览器在向服务器请求资源时,首先判断是否命中强缓存,没命中再判断是否命中协商缓存

强缓存:浏览器在加载资源时,会先根据本地缓存资源的 expires 或者 cache-control 判断是否命中强缓存,如果命中则直接使用缓存中的资源,不会再向服务器发送请求

协商缓存:协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

强缓存

Expires: 需和Last-Modified结合使用,用于控制请求文件的有效时间。缺点:Expires 是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效

Cache-Control:主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如 Cache-Control: max-age=3600,代表着资源的有效期是 3600 秒

Cache-Control 与 Expires 一起使用时,Cache-Control优先级高

Cache-Control可配置值

字段说明
no-cache需要进行协商缓存,发送请求到服务器确认是否使用缓存。
no-store禁止使用缓存,每一次都要重新请求数据。
public可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。
private只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

协商缓存

Last-Modify/If-Modify-Since:根据文件的修改时间来判断是否缓存,缺点是文件无改动,但是文件修改时间改动,会导致缓存失效

ETag/If-None-Match:根据文件的内容hash值来判断是否缓存

Last-Modify 与 ETag 一起使用时,ETag优先级高

事件循环

JS引擎常驻于内存中,等待宿主将JS代码或函数传递给它。

也就是等待宿主环境分配宏观任务,反复等待 - 执行即为事件循环。

<img src="/static/imgs/event-loop.webp" />

Event Loop中,每一次循环称为tick,每一次tick的任务如下:

  • 执行栈选择最先进入队列的宏任务(一般都是script),执行其同步代码直至结束;
  • 检查是否存在微任务,有则会执行至微任务队列为空;
  • 如果宿主为浏览器,可能会渲染页面;
  • 开始下一轮tick,执行宏任务中的异步代码(setTimeout等回调)。

<div className="google-adsense" data-slot="5116803225" />

微任务和宏任务

ES6 规范中,microtask 称为 jobs,macrotask 称为 task

宏任务是由宿主发起的,而微任务由JavaScript自身发起。

宏任务

(macro)task,可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。

浏览器为了能够使得JS内部(macro)task与DOM任务能够有序的执行,会在一个(macro)task执行结束后,在下一个(macro)task 执行开始前,对页面进行重新渲染,流程如下:

(macro)task->渲染->(macro)task->...

宏任务包含:

script(整体代码)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)

微任务

(micro)task,可以理解是在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。

所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。

微任务包含:

Promise.then
Object.observe
MutationObserver
process.nextTick(Node.js 环境)

从输入URL到页面加载发生了什么?

  1. URL解析,判断是URL还是搜索关键字,如果是URL就开始进行DNS解析,关键字就进行搜索
  2. DNS解析到具体的IP地址
  3. 浏览器三次握手建立TCP连接,向服务端请求页面
  4. 服务端响应浏览器请求,返回HTML代码等资源
  5. TCP4次挥手断开连接
  6. 浏览器解析HTML文件,生成DOM和CSSOM,构建render树,渲染到页面

无论你是前端初学者还是有两三年的前端开发,这个网址整理了最新最全的面试题,永久免费,欢迎收藏转发!

https://interview.kelen.cc

永久免费,专门针对前端人的学习

整理好的文章和资料也不容易,如果觉得好用也可以转发给你身边的小伙伴们


黄凯伦
8 声望0 粉丝