输入URL到渲染页面

【进程之间使用 IPC 通信】
flowchart
subgraph 浏览器进程
A[用户输入] --> B[处理输入信息]
B[判断是合法域名
而非搜索关键字] --> C[开始导航] end %% ========== 跨进程标注 ========== style C stroke:#f66,stroke-width:2px
而非搜索关键字] --> C[开始导航] end %% ========== 跨进程标注 ========== style C stroke:#f66,stroke-width:2px
flowchart
subgraph 网络进程
D[查找本地缓存]
D -->|无缓存| E[进入请求流程]
E --> F[DNS解析]
F --> |得到IP和port| G[等待 TCP 队列]
G --> |同域名限6个tcp连接| H[建立TCP连接]
end
%% ========== 跨进程标注 ==========
style H stroke:#f66,stroke-width:2px
- 提交文档
- 更新前进、后退状态
- 更新地址栏
- 更新web页面
flowchart
subgraph 渲染器进程
J[渲染阶段]
J --> K[构建DOM树]
K --> L[构建CSSOM树]
L --> M[布局]
M --> N[绘制]
N --> O[合成]
O --> P[展示页面]
end
为什么第二次打开网页会变快?
因为存在各类缓存
- 网站资源缓存,直接通过【强缓存】或者【协商缓存】获取
- DNS缓存,下一次获取 IP + port,更快
- 如果用户存在登录信息 cookie,下一次也不需要登录了
什么是重排(回流)、重绘?
Reflow/Repaint.
重排:浏览器计算元素的【几何属性】(位置、宽高)。影响范围大。整个渲染树。
重绘:浏览器计算元素的【视觉属性】(颜色、背景)。不影响布局。
offsetHeight 之类的获取,也会触发重排。
优化原则
- 减少范围:尽量只修改【脱离文档流】的元素
- 减少次数:使用
classList
批量修改样式 - 跳过阶段:用
transform``opacity
之类的属性,避开 【重排】【重绘】 ,直接【合成】 。
【与上面重复的,但是不同的知识分类方式】
css的角度:
- 使用 transform 和 opacity。
- 使用 classList
js技巧:
- 批量操作 dom 元素,使用
fragment
ini
// ❌ 糟糕(多次重排)
for (let i = 0; i < 100; i++) {
document.body.appendChild(document.createElement('div'));
}
// ✅ 优化(1次重排)
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
fragment.appendChild(document.createElement('div'));
}
document.body.appendChild(fragment);
- 读写分离
ini
// ❌ 糟糕(强制同步布局)
for (let i = 0; i < items.length; i++) {
items[i].style.width = box.offsetWidth + 'px'; // 读 → 写 → 读 → 写...
}
// ✅ 优化(先读后写)
const width = box.offsetWidth; // 集中读取
for (let i = 0; i < items.length; i++) {
items[i].style.width = width + 'px'; // 集中写入
}
- 使用 requestAnimation 动画
scss
function animate() {
element.style.transform = `translateX(${pos++}px)`;
requestAnimationFrame(animate); // 与浏览器刷新率同步
}
浏览器发起HTTP请求的过程

1.构建请求行 GET index.html HTTP1.1
2.查找缓存
3.准备 IP 和 端口------DNS查询
4.等待 TCP 队列,同一个域名下只能有 6 个
5.建立 TCP 连接
6.发送请求
【服务端】
1.返回响应,返回响应码 200、304、400、403、404、502 之类的
2.断开 TCP 连接, 除非设置了 Keep-Alive
其他:TCP通信图
应用层、传输层、会话层、网络层、数据链路层、物理层
其实就是一个,封装包数据 => 拆解包数据 的过程。

其他:关于重定向 302
nginx 配置,通常在废弃旧网址的时候使用。
ruby
server {
listen 80;
server_name example.com;
return 301 $scheme://www.example.com$request_uri;
}
其他:plantuml版本流程图
