客户端和服务器端的交互处理
当用户在地址栏中输入网址,到最后看到页面,中间都经历了什么 ?
1.URL地址解析
A: URI / URL / URN
URI(Uniform Resource Identifier / 统一资源标志符) URL(Uniform Resource Locator / 统一资源定位符) URN(Uniform Resource Name / 统一资源名称)
B:一个完整URL的组成部分和实际意义
- 协议:http 、 https 、 ftp
- 域名:顶级域名、一级域名、二级域名、常用域名的性质
- 端口号:80 、443 、 21 、 端口号范围
- 请求资源路径名称:伪URL
- 问号参数
- HASH值
C:特殊字符加密和解密
- encodeURI / decodeURI
- encodeURIComponent / decodeURIComponent
- escape / unescape
- ......
2.DNS域名解析
A:DNS域名解析是什么?
- 发布站点时配置域名解析
- 网址访问进行DNS域名反解析
B:DNS Prefetch 即 DNS 预获取
- 减少DNS的请求次数
- 进行DNS预获取
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//static.360buyimg.com">
<link rel="dns-prefetch" href="//misc.360buyimg.com">
<link rel="dns-prefetch" href="//img10.360buyimg.com">
<link rel="dns-prefetch" href="//img11.360buyimg.com">
<link rel="dns-prefetch" href="//img12.360buyimg.com">
......
- 缓存时间在1分钟左右
3.建立TCP连接(三次握手)
- 第一次握手:由浏览器发起,告诉服务器我要发送请求了
- 第二次握手:由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧
- 第三次握手:由浏览器发送,告诉服务器,我马上就发了,准备接受吧
4.发送HTTP请求
A:HTTP请求报文
- 起始行
- 请求头(首部)
- 请求主体
B:强缓存 和 协商缓存
- 强缓存 ( Cache-Control 和 Expires )
- 协商缓存 ( Last-Modified 和 Etag )
5.服务器得到并处理请求
A:WEB(图片)服务器和数据服务器
-
Tomcat
-
Nginx
-
Apache
-
IIS
-
......
B:HTTP响应报文
- 响应状态码
- 200 / 201 / 204
- 301 / 302 / 304 / 307
- 400 / 401 / 404
- 500 / 503
- 响应头(首部)
- 响应主体
6.客户端渲染页面
A:浏览器渲染页面的步骤
- 解析HTML,生成DOM树,解析CSS,生成CSSOM树
- 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
- Layout(回流): 根据生成的渲染树,计算它们在设备视口(viewport)内的确切位置和大小,这个阶段是回流
- Painting(重绘): 根据渲染树以及回流得到的几何信息,得到节点的绝对像素
- Display:将像素发送给GPU,展示在页面上
总结一句话:CSS 不会阻塞DOM树的解析,但是会阻塞DOM树的渲染
B:DOM的重绘和回流
- 重绘:元素样式的改变(但宽高、大小、位置等不变)
- 回流:元素的大小或者位置发生了变化(当页面布局和几何信息发生变化的时候),触发了重新布局,导致渲染树重新计算布局和渲染
- 注意:回流一定会触发重绘,而重绘不一定会回流
C:前端性能优化之:避免DOM的回流
- 放弃传统操作dom的时代,基于vue/react开始数据影响视图模式
- 分离读写操作 (现代的浏览器都有渲染队列的机制)
- 样式集中改变
- 缓存布局信息
- 元素批量修改
- 动画效果应用到position属性为absolute或fixed的元素上(脱离文档流)
- CSS3硬件加速(GPU加速)
- 牺牲平滑度换取速度
- 避免table布局和使用css的javascript表达式
7.断开连接(四次挥手)
- 第一次挥手:由浏览器发起,发送给服务器,我请求报文发送完了,你准备关闭吧;
- 第二次挥手:由服务器发起,告诉浏览器,我接收完请求报文,我准备关闭,你也准备吧;
- 第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完毕,你准备关闭吧;
- 第四次挥手:由浏览器发起,告诉服务器,我响应报文接收完毕,我准备关闭,你也准备吧;
A:Connection: Keep-Alive 保持TCP不中断
前端性能优化汇总
1.减少HTTP请求次数和请求的大小
- 文件合并压缩
- 雪碧图 css sprite
- 图片base64
- 尽量使用字体图标
- 图片懒加载
- 音视频取消预加载
- 在客户端和服务器端进行信息交互的时候,对于多项数据我们尽可能基于JSON格式来进行传送(JSON格式的数据处理方便,资源偏小)
- 开启服务器端的gzip压缩
- ......
2.建立缓存机制
- DNS缓存
- 数据缓存(例如:本地存储)
- 强缓存 和 协商缓存(304)
- 离线存储
- 做CDN加速
- ......
3.代码上的优化
- 减少DOM的重绘和回流
- 在JS中尽量减少闭包的使用
- 在JS中避免“嵌套循环”和“死循环”
- 尽可能使用事件委托
- 尽量减少CSS表达式的使用(expression)
- CSS选择器解析规则是从右向左解析
- 页面中的数据获取采用异步编程和延迟分批加载
- 尽可能实现JS的封装(低耦合高内聚),减少页面中的冗余代码
- 尽量减少对于filter滤镜属性的使用
- 在CSS导入的时候尽量减少使用@import导入式
- 使用window.requestAnimationFrame(JS中的帧动画)代替传统的定时器动画
- 减少递归的使用,避免死递归,避免由于递归导致的栈内存嵌套
- 基于SCRIPT调取JS的时候,可已使用 defer或者async 来异步加载
- 避免使用with语句
- ......