浏览器打开页面的过程
- 解析 URL
- DNS 解析
<link rel="dns-prefetch" href="//yourwebsite.com">
浏定览器并不保证一会去解析域名,可能会根据当前的网络、负载等状况做决定 - 建立 TCP/IP 链接
<link rel="preconnect" href="//sample.com"> 或跨域 <link rel="preconnect" href="//sample.com" crossorigin>
- HTTP 请求和响应
缓存:
- service worker 缓存
- 强缓存/协商缓存
- http/2 push 缓存
- 页面渲染
页面渲染的步骤
- 解析 HTML 标签并构建 DOM 树
- 解析 CSS 标签并构建 CSSOM 树
- 将 DOM 与 CSSOM 合并成一个渲染树
- 根据渲染树来布局,计算每个节点的几何信息
- 将各个节点绘制到屏幕上
HTML 解析、JavaScript 加载与执行、CSS 加载与使用
HTML 解析的过程:
HTML 解析过程中的 CSS
- 遇到外链的 css 时,网络进程会请求对应的资源,渲染进程继续解析 html
- 遇到内联的 css 时?
HTML 解析过程中的 Javascript
当解析过程中遇到内联脚本或者 js 资源,渲染进程会被挂起,等待 js 资源加载并执行完毕后,再继续进行解析;
将 script 标签放在 body 底部;defer、async
根据标准规范,在 JavaScript 中可以访问 DOM。因此当遇到 JavaScript 后会阻塞 DOM 的解析。于此同时,为避免 CSS 与 JavaScript 之间的竞态,CSSOM 的构建会阻塞 JavaScript 的脚本执行。总结起来就是 —— JavaScript 会阻塞 DOM 构建,而 CSSOM 的构建又回阻塞 JavaScript 的执行。
JavaScript 会阻塞 DOM 构建,而 CSSOM 的构建又回阻塞 JavaScript 的执行。
- 构建 CSSOM 的时机?再构建的过程中会不会阻塞?
- 是否是等待 js 加载并执行完之后再继续解析?如果是立即执行的,那么遇到
document.getElementById()
这样的代码该怎么办? - 服务器返回优化:stream response?无刷新、无 JavaScript 的页面更新?BFF?
display: none
并非是删除 DOM ,改变 DOM 树,而是改变渲染树;
资源加载和 readyState
readyState:loading ---> interactive(解析 html 完成,但依然在加载资源) -----> complete(资源加载完毕)
DOMContentLoaded:事件在 interactive 之后 complete 之前触发,即除异步脚本之外的资源都已加载完毕
JavaScript 运行优化
-
requestAnimationFrame
:下一次重绘之前执行 -
requestIdleCallback
:浏览器渲染线程空闲时的回调 - Passive event listeners:
{passive: true}
不需要等待事件处理回调代码运行完,直接在触发时就渲染相应的 DOM 操作