3.28 & 3.29

3.28 & 3.29

浏览器合成层是什么,它为什么能作为性能优化的手段?

浏览器合成层(Composite Layer)是浏览器渲染流水线中的一个关键概念,它通过分层和独立处理页面元素来提升渲染性能。以下是详细解释:


1. 什么是合成层?

合成层是浏览器将页面的一部分(如DOM元素)分离为独立的位图图层(bitmap layer),这些图层会被GPU单独光栅化和缓存。最终,浏览器通过**合成器(Compositor)**将这些图层按正确顺序合并(Composite)成最终屏幕图像。


2. 合成层如何形成?

浏览器会根据特定规则将元素提升为合成层(通常由CSS属性触发):

  • 显式触发will-change: transform/opacitytransform: translateZ(0)等。
  • 隐式触发position: fixedvideo/canvas元素、硬件加速的动画等。

3. 为什么合成层能优化性能?

a. 减少重绘(Repaint)范围

  • 修改一个合成层内的元素(如动画)时,仅重绘该图层,无需重绘整个页面。
  • 示例:一个按钮的动画只需更新按钮所在的图层,其他部分保持不变。

b. 避免布局(Layout)和光栅化(Raster)

  • 合成层的变换(如transformopacity跳过布局和绘制阶段,直接由GPU处理(在合成线程完成,不阻塞主线程)。
  • 传统渲染路径:Layout → Paint → Composite → Display。
    合成层优化路径:Composite → Display(跳过前两步)。

c. 硬件加速(GPU加速)

  • 合成层交由GPU处理,比CPU更擅长并行计算图形操作(如矩阵变换、透明度混合)。

d. 减少渲染流水线阻塞

  • 主线程任务(JavaScript、样式计算等)与合成器线程并行工作,动画更流畅。

4. 实际优化场景

  • 动画优化:对移动/淡入淡出的元素使用transformopacity,使其成为合成层。
  • 减少层爆炸:避免过度创建合成层(每个层消耗内存),合理使用will-change
  • 滚动性能:对固定定位(position: fixed)元素启用合成层,避免滚动时重绘。

5. 注意事项

  • 内存开销:每个合成层占用GPU内存,层过多会导致内存压力(尤其在移动端)。
  • 过度优化反作用:滥用will-changetranslateZ(0)可能适得其反。

总结

合成层通过将页面元素隔离为独立图层,利用GPU加速和减少重绘范围来优化性能,尤其在动画和交互频繁的场景下效果显著。但需平衡层数和内存消耗,通过Chrome DevTools的Layers面板可直观分析合成层。

解释一下TLS和SSL

TLS(Transport Layer Security,传输层安全协议)和SSL(Secure Sockets Layer,安全套接层)是用于加密网络通信的协议,确保数据在传输过程中不被窃取或篡改。以下是它们的核心概念、区别及工作原理:


1. 基本概念

  • SSL
    由网景公司(Netscape)于1990年代开发,最初用于保护HTTP通信(即HTTPS)。主流版本包括SSL 2.0和SSL 3.0,但均因严重安全漏洞被废弃。
  • TLS
    是SSL的标准化升级版,由IETF(互联网工程任务组)制定。TLS 1.0基于SSL 3.0改进,后续版本(TLS 1.1、1.2、1.3)逐步增强安全性。
    当前广泛使用的是TLS 1.2和TLS 1.3(TLS 1.0/1.1已淘汰)。

2. TLS与SSL的关系

  • TLS是SSL的继承者,两者功能类似,但TLS更安全、高效。
  • 由于历史习惯,人们仍常将TLS称为“SSL”(如SSL证书、SSL握手等),但实际使用的协议是TLS。

3. 核心功能

两者均提供以下安全特性:

  1. 加密:通过对称加密(如AES)保护数据传输的隐私性。
  2. 身份认证:通过数字证书验证服务器(或客户端)身份,防止中间人攻击。
  3. 完整性校验:通过MAC(消息认证码)或HMAC确保数据未被篡改。

4. 工作原理(以TLS为例)

① 握手阶段(Handshake)

  1. 客户端Hello
    • 客户端向服务器发送支持的TLS版本、加密套件(Cipher Suites)列表、随机数(Client Random)。
  2. 服务器Hello
    • 服务器选择TLS版本和加密套件,发送数字证书、随机数(Server Random)。
  3. 密钥交换
    • 客户端验证证书合法性(如CA签发、域名匹配),生成预主密钥(Pre-Master Secret),用服务器公钥加密后发送。
  4. 生成会话密钥
    • 双方通过Client Random、Server Random和Pre-Master Secret生成相同的会话密钥(用于后续对称加密)。

② 加密通信阶段

  • 使用握手阶段协商的对称密钥(如AES)加密应用层数据(如HTTP请求/响应)。

5. TLS vs SSL 关键区别

特性 SSL TLS
协议版本 SSL 2.0/3.0(已废弃) TLS 1.0 → 1.3(1.2/1.3为主流)
安全性 漏洞多(如POODLE攻击) 更安全(如禁用弱加密算法)
密钥生成 基于MD5/SHA-1(不安全) 使用更安全的HMAC-SHA256等
握手效率 较慢(RSA密钥交换) TLS 1.3支持0-RTT(减少延迟)

6. 为什么TLS取代SSL?

  • 安全缺陷:SSL 3.0易受POODLE等攻击,TLS修复了这些漏洞。
  • 标准化:TLS由IETF维护,更适应现代安全需求(如前向保密、强加密算法)。
  • 性能优化:TLS 1.3简化握手过程,减少延迟。

7. 实际应用

  • HTTPS:网站加密(如https://)实际使用TLS协议。
  • API/邮件/SMTP:现代加密通信均依赖TLS(如STARTTLS)。
  • 证书类型:俗称的“SSL证书”实际是“TLS/SSL证书”,如Let’s Encrypt颁发的证书。

8. 如何检查协议版本?

  • 浏览器地址栏点击锁图标 → 查看连接详情。
  • 使用命令行工具:
    1
    
    openssl s_client -connect example.com:443 -tls1_2  # 指定TLS版本测试
    

总结

TLS是SSL的现代化替代协议,提供更强的安全性和性能。尽管术语“SSL”仍被广泛使用,但实际部署中应禁用SSL,优先使用TLS 1.2或1.3。理解它们的区别有助于配置安全的网络服务(如Nginx/Apache的SSL/TLS设置)。

tcp拥塞控制

TCP拥塞控制(Congestion Control)是TCP协议的核心机制之一,用于动态调整发送速率以避免网络拥塞,同时公平共享带宽资源。其核心目标是在高吞吐量低延迟之间取得平衡,防止网络因过载而崩溃。以下是详细解析:


1. 为什么需要拥塞控制?

  • 背景:互联网是共享资源,当多个TCP连接竞争带宽时,若无控制会导致路由器缓冲区溢出(丢包),引发全局吞吐量下降(拥塞崩溃)。
  • 核心矛盾:发送方无法直接感知网络状态,需通过隐式反馈(如丢包、延迟)推断拥塞。

2. 拥塞控制的核心机制

TCP通过四个主要算法实现拥塞控制,现代Linux内核默认使用CUBIC算法(旧版本可能用Reno)。

① 慢启动(Slow Start)

  • 目的:快速探测可用带宽。
  • 规则
    • 初始拥塞窗口(cwnd)通常为1-10个MSS(最大报文段大小)。
    • 每收到一个ACK,cwnd 指数增长cwnd += MSS → 每RTT翻倍)。
  • 终止条件
    • 到达慢启动阈值(ssthresh,初始值较高)。
    • 发生丢包(超时或重复ACK)。

② 拥塞避免(Congestion Avoidance)

  • 目的:平稳接近网络容量,避免激进增长引发丢包。
  • 规则
    • cwnd 线性增长(每RTT增加1个MSS:cwnd += MSS/cwnd)。
    • 持续探测直到检测到拥塞(丢包)。

③ 快速重传(Fast Retransmit)

  • 触发条件:收到3个重复ACK(表明报文丢失但后续数据仍能到达)。
  • 行为
    • 立即重传丢失的报文,无需等待超时。
    • 进入快速恢复阶段。

④ 快速恢复(Fast Recovery)

  • 目标:在快速重传后避免重置cwnd,维持吞吐量。
  • 规则
    • ssthresh设为当前cwnd/2
    • cwnd = ssthresh + 3*MSS(补偿已确认的重复ACK)。
    • 每收到一个新ACK,cwnd += MSS
    • 当丢失报文的所有ACK到达后,退出快速恢复,进入拥塞避免阶段。

3. 关键参数与行为

  • 拥塞窗口(cwnd:发送方限制未确认数据量的动态窗口(单位:字节或MSS)。
  • 慢启动阈值(ssthresh:从慢启动切换到拥塞避免的临界值。
  • 丢包判定
    • 超时重传(RTO):最严重拥塞信号,直接重置cwnd=1,重启慢启动。
    • 重复ACK:触发快速重传/恢复,对cwnd影响较小。

4. 经典算法对比

算法 特点 适用场景
Reno 基础算法,快速恢复阶段线性增长。 早期网络,已逐步淘汰。
CUBIC 使用三次函数控制cwnd增长,对高带宽延迟积(BDP)网络更公平。 现代Linux默认(>2.6.19)。
BBR 基于带宽和延迟测量(而非丢包),避免缓冲区膨胀。 Google推出的抗拥塞算法。

5. 拥塞控制的演进

  • 传统依赖丢包:如Reno/CUBIC,将丢包视为拥塞信号(可能误判)。
  • 现代混合方法:如BBR(Bottleneck Bandwidth and Round-trip propagation time):
    • 主动测量网络带宽和RTT,动态调整发送速率。
    • 减少对丢包的依赖,尤其适合高速长距离网络(如卫星链路)。

6. 实际影响与调优

  • 高延迟网络(如卫星):传统算法(如CUBIC)可能效率低下,BBR更优。
  • 数据中心内部:低延迟需求可能禁用拥塞控制(如RDMA)。
  • 手动调参:可通过sysctl调整内核参数(如tcp_congestion_control=cubic)。

7. 示例:TCP拥塞控制状态机

1
2
3
4
5
6
7
(连接建立)
慢启动(cwnd指数增长) → 超时? → cwnd=1, 重启慢启动
  ↓ 达到ssthresh
拥塞避免(cwnd线性增长) → 重复ACK? → 快速重传 → 快速恢复
  ↓ 丢包(超时)
重置cwnd=1, ssthresh=cwnd/2

总结

TCP拥塞控制通过动态调整发送窗口(cwnd)来适应网络状态,其核心思想是**“探测-反馈-调整”**。理解其机制有助于优化高延迟或高吞吐场景(如视频流、云计算),而现代算法(如BBR)正推动拥塞控制从被动响应转向主动测量。

解释一下cors

CORS(Cross-Origin Resource Sharing,跨源资源共享)是一种基于HTTP头的安全机制,用于允许或拒绝浏览器在不同源(Origin)之间访问资源的权限。它解决了浏览器的**同源策略(Same-Origin Policy)**的限制,是实现跨域请求的标准方案。


1. 为什么需要CORS?

同源策略的限制

浏览器出于安全考虑,默认禁止网页从一个源(Origin)向另一个源发起跨域请求(如AJAX、Fetch)。同源的定义是:

  • **协议(Protocol)**相同(如http/https
  • **域名(Domain)**相同(如example.com
  • **端口(Port)**相同(如80/443

如果三者任一不同,则属于跨源请求,浏览器会拦截响应(除非目标服务器明确允许)。


2. CORS的工作原理

CORS通过HTTP请求头响应头协商跨域权限,分为两种请求类型:

① 简单请求(Simple Request)

满足以下条件时,浏览器直接发送请求(无需预检):

  • 方法为GETPOSTHEAD
  • 请求头仅包含:
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(仅限text/plainmultipart/form-dataapplication/x-www-form-urlencoded

流程:

  1. 浏览器直接发送跨域请求,并在请求头中添加:
    1
    
    Origin: https://your-site.com
    
  2. 服务器响应时需包含:
    1
    
    Access-Control-Allow-Origin: https://your-site.com  // 或 *(允许任意源)
    

② 预检请求(Preflight Request)

不满足简单请求条件时(如使用PUTDELETE或自定义头),浏览器会先发送一个OPTIONS请求预检权限。

流程:

  1. 浏览器发送OPTIONS请求,包含:
    1
    2
    3
    
    Origin: https://your-site.com
    Access-Control-Request-Method: PUT      // 声明实际请求的方法
    Access-Control-Request-Headers: X-Custom-Header  // 声明自定义头
    
  2. 服务器响应需明确允许:
    1
    2
    3
    4
    
    Access-Control-Allow-Origin: https://your-site.com
    Access-Control-Allow-Methods: GET, POST, PUT      // 允许的方法
    Access-Control-Allow-Headers: X-Custom-Header    // 允许的头
    Access-Control-Max-Age: 86400  // 预检结果缓存时间(秒)
    
  3. 预检通过后,浏览器才会发送真实请求。

3. 关键HTTP头部

请求头(由浏览器自动添加)

  • Origin:声明请求来源(如https://your-site.com)。
  • Access-Control-Request-Method:预检时声明实际请求方法(如PUT)。
  • Access-Control-Request-Headers:预检时声明自定义头(如Authorization)。

响应头(由服务器设置)

  • Access-Control-Allow-Origin:允许的源(如*https://your-site.com)。
  • Access-Control-Allow-Methods:允许的HTTP方法(如GET, POST)。
  • Access-Control-Allow-Headers:允许的自定义头(如X-API-Key)。
  • Access-Control-Allow-Credentials:是否允许携带Cookie(需前端设置withCredentials: true)。
  • Access-Control-Max-Age:预检结果的缓存时间。

4. 常见场景与解决方案

场景1:前端跨域访问API

  • 问题:前端部署在https://frontend.com,请求https://api.com/data被浏览器拦截。
  • 解决:API服务器响应头需包含:
    1
    
    Access-Control-Allow-Origin: https://frontend.com
    

场景2:携带Cookie的跨域请求

  • 前端
    1
    2
    3
    
    fetch('https://api.com/data', {
      credentials: 'include'  // 发送Cookie
    });
    
  • 后端
    1
    2
    
    Access-Control-Allow-Origin: https://frontend.com  // 不能为 *
    Access-Control-Allow-Credentials: true
    

场景3:自定义请求头

  • 前端
    1
    2
    3
    
    fetch('https://api.com/data', {
      headers: { 'X-API-Key': '123' }
    });
    
  • 后端
    1
    
    Access-Control-Allow-Headers: X-API-Key
    

5. CORS与JSONP的区别

特性 CORS JSONP
原理 通过HTTP头部协商权限 利用<script>标签跨域加载JS
支持方法 所有HTTP方法(GET/POST/PUT等) 仅GET
安全性 更安全(服务器可控) 易受XSS攻击
现代性 主流方案(推荐) 逐渐淘汰

6. 服务器配置示例

Node.js(Express)

1
2
3
4
5
6
7
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'https://frontend.com');
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT');
  res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
  res.header('Access-Control-Allow-Credentials', 'true');
  next();
});

Nginx

1
2
3
4
5
location / {
  add_header 'Access-Control-Allow-Origin' 'https://frontend.com';
  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
}

7. 注意事项

  • 安全性:避免滥用Access-Control-Allow-Origin: *,应严格限制允许的源。
  • 预检请求:复杂请求会触发OPTIONS,可能增加延迟(可通过Access-Control-Max-Age缓存优化)。
  • 错误排查:使用浏览器开发者工具查看Network中的CORS相关头。

总结

CORS是浏览器与服务器协作实现跨域访问的标准机制,通过HTTP头部协商权限。正确配置CORS可兼顾安全性与灵活性,而错误配置可能导致功能失效或安全风险。现代Web开发中,CORS已成为跨域通信的首选方案。

ajax请求的方式有哪些?

AJAX(Asynchronous JavaScript and XML)是一种在浏览器中通过JavaScript发起异步HTTP请求的技术,无需刷新页面即可与服务器交换数据。以下是常见的AJAX请求方式及其详细说明:


1. 原生JavaScript方式

① XMLHttpRequest (XHR)

最基础的AJAX实现,兼容所有现代浏览器。

1
2
3
4
5
6
7
8
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true); // 异步请求
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(JSON.parse(xhr.responseText));
  }
};
xhr.send();
  • 特点
    • 支持所有HTTP方法(GET/POST/PUT/DELETE等)。
    • 需手动处理状态码(readyStatestatus)和响应数据。

2. Fetch API

现代浏览器原生支持的更简洁的AJAX方案,基于Promise。

① 基本用法

1
2
3
4
5
6
7
fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) throw new Error('Network error');
    return response.json(); // 解析JSON响应
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

② 带参数的POST请求

1
2
3
4
5
6
7
8
fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ key: 'value' }), // 请求体
})
.then(response => response.json());
  • 特点
    • 更简洁的链式调用(Promise)。
    • 默认不携带Cookie,需显式设置credentials: 'include'
    • 需手动处理错误(非2xx状态码不会自动触发catch)。

3. 第三方库

① Axios

流行的基于Promise的HTTP客户端,支持浏览器和Node.js。

1
2
3
4
5
6
7
axios.get('https://api.example.com/data')
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

// POST请求
axios.post('https://api.example.com/data', { key: 'value' })
  .then(response => console.log(response.data));
  • 特点
    • 自动转换JSON数据。
    • 拦截请求和响应(Interceptors)。
    • 内置CSRF防护。
    • 取消请求(CancelToken)。

② jQuery AJAX

传统方式,适合老项目或依赖jQuery的场景。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$.ajax({
  url: 'https://api.example.com/data',
  method: 'GET',
  success: function(data) {
    console.log(data);
  },
  error: function(error) {
    console.error(error);
  }
});
  • 特点
    • 语法简单,兼容老旧浏览器。
    • 依赖jQuery,现代项目逐渐淘汰。

4. WebSocket

虽然不属于AJAX,但可实现全双工实时通信。

1
2
3
4
5
const socket = new WebSocket('wss://api.example.com/ws');
socket.onmessage = function(event) {
  console.log('Received:', event.data);
};
socket.send('Hello Server!');
  • 适用场景:实时聊天、股票行情等高频数据推送。

5. 其他变体

① FormData(文件上传)

1
2
3
4
5
6
7
const formData = new FormData();
formData.append('file', fileInput.files[0]);

fetch('https://api.example.com/upload', {
  method: 'POST',
  body: formData, // 自动设置 multipart/form-data
});

② Server-Sent Events (SSE)

服务器单向推送数据(如新闻更新)。

1
2
3
4
const eventSource = new EventSource('https://api.example.com/stream');
eventSource.onmessage = (event) => {
  console.log('New event:', event.data);
};

对比总结

方式 优点 缺点 适用场景
XHR 兼容性强,支持所有HTTP方法 代码冗长,回调地狱风险 老旧浏览器兼容
Fetch 原生Promise,语法简洁 需手动处理错误和JSON解析 现代浏览器项目
Axios 功能全面,拦截器支持 需额外引入库 复杂请求/企业级应用
jQuery AJAX 简单易用 依赖jQuery,性能开销 遗留jQuery项目
WebSocket 全双工实时通信 非HTTP协议,需服务端支持 实时应用(如聊天室)

最佳实践建议

  1. 现代项目首选:使用FetchAxios(推荐Axios,因其错误处理更友好)。
  2. 文件上传:结合FormDataFetch/Axios
  3. 实时数据:考虑WebSocketSSE
  4. 兼容性:老旧项目可用XHR或jQuery,但建议逐步迁移。

通过选择合适的方式,可以高效、安全地实现前后端数据交互。

Licensed under CC BY-NC-SA 4.0
最后更新于 Mar 29, 2025 06:07 UTC