# 性能优化
先要了解从输入网址到页面加载的步骤 -> 重定向 → 拉取缓存 →DNS 查询 → 建立 TCP 链接 → 发起请求 → 接收响应 → 处理 HTML 元素 → 元素加载完成
重要性 一个网站的体验,决定了用户是否愿意去了解网站的功能;而网站的功能,决定了用户是否会一票否决网站的体验。这是改版自网络上的一句流行语,但却把网站性能这件事说的十分透彻,特别是在网站这样的项目中,如果一个用户需要超过5s才能看见页面,他会毫不犹豫地关闭它。
# 1. 网络传输层加速
缓存一般分为强缓存和协商缓存,主要区别是:使用本地缓存的时候,是否需要向服务器验证本地缓存是否依旧有效。
# 浏览器缓存
# 强缓存
主要通过 http 请求头中的 Cache-Control 和 Expire 两个字段控制
一般,我们会设置 Cache-Control 的值为“public, max-age=xxx”,表示在 xxx 秒内再次访问该资源,均使用本地的缓存,不再向服务器发起请求。
# 协商缓存
每次都向服务器验证一下缓存的有效性
# 前端缓存方案
- HTML:使用协商缓存
- CSS JS Image:使用强缓存,文件名带上 hash 值
浏览器默认的缓存是放在内存内的,但我们知道,内存里的缓存会因为进程的结束或者说浏览器的关闭而被清除,而存在硬盘里的缓存才能够被长期保留下去。很多时候,我们在 network 面板中各请求的 size 项里,会看到两种不同的状态:from memory cache 和 from disk cache,前者指缓存来自内存,后者指缓存来自硬盘。而控制缓存存放位置的,不是别人,就是我们在服务器上设置的 Etag 字段。在浏览器接收到服务器响应后,会检测响应头部(Header),如果有 Etag 字段,那么浏览器就会将本次缓存写入硬盘中。
# 资源打包压缩
网络性能优化措施归结为三大方面:减少请求数、减小请求资源体积、提升网络传输速率
gulp grunt webpack parcel
# 图片资源优化
用过ngxin的人都知道,ngxin可以把文件设置为gzip压缩格式,但是图片不要设置gzip压缩!图片不要设置gzip压缩!图片不要设置gzip压缩!
- 不要在 HTML 里缩放图像
- 使用雪碧图(CSS Sprite)- webpack-spritesmith
- 使用字体图标(iconfont)- icomoon
- 使用 WebP - 图片压缩体积大约只有 JPEG 的 2/3,并能节省大量的服务器带宽资源和数据空间
# 网络传输性能检测工具
Page Speed | PageSpeed Insights
# 使用 CDN
再好的性能优化实例,也必须在CDN的支撑下才能到达极致。
如果我们在Linux下使用命令$ traceroute targetIp 或者在Windows下使用批处理 > tracert targetIp,都可以定位用户与目标计算机之间经过的所有路由器,不言而喻,用户和服务器之间距离越远,经过的路由器越多,延迟也就越高。使用CDN的目的之一便是解决这一问题
# 2.页面渲染性能优化
# 浏览器渲染过程 webkit
浏览器的解释器,是包括在渲染引擎内的,我们常说的 Chrome(现在使用的是 Blink 引擎)和 Safari 使用的 Webkit 引擎,Firefox 使用的 Gecko 引擎,指的就是渲染引擎。而在渲染引擎内,还包括着我们的 HTML 解释器(渲染时用于构造 DOM 树)、CSS 解释器(渲染时用于合成 CSS 规则)还有我们的 JS 解释器。不过后来,由于 JS 的使用越来越重要,工作越来越繁杂,所以 JS 解释器也渐渐独立出来,成为了单独的 JS 引擎,就像众所周知的 V8 引擎,我们经常接触的 Node.js 也是用的它。
# 重排和重绘
重排(reflow):渲染层内的元素布局发生修改,都会导致页面重新排列,比如窗口的尺寸发生变化、删除或添加DOM元素,修改了影响元素盒子大小的CSS属性(诸如:width、height、padding)。
②重绘(repaint):绘制,即渲染上色,所有对元素的视觉表现属性的修改,都会引发重绘。
# 优化方式
CSS 属性读写分离
通过切换 class 或者 style.csstext 属性去批量操作元素样式
DOM 元素离线更新
将没用的元素设为不可见:visibility: hidden,减少重绘的压力
压缩 DOM 的深度:少用 DOM 完成页面样式,多使用伪元素或者 box-shadow 取代。
图片在渲染前指定大小:因为 img 元素是内联元素,所以在加载图片后会改变宽高,严重的情况会导致整个页面重排,所以最好在渲染前就指定其大小,或者让其脱离文档流。
对页面中可能发生大量重排重绘的元素单独触发渲染层,使用 GPU 分担 CPU 压力。(慎重)
# 3. JS阻塞
都知道js在加载的时候,会阻塞整个脚本的运行,我们可以把js脚本放到页面的尾部,这样页面会先加载出来,还可以通过让js脚本异步执行
# js脚本异步执行的方式
给script标签添加defer 如果有多个设置了defer的script标签存在,则会按照顺序执行所有的script;
给script标签添加async 并不会按着script在页面中的顺序来执行,而是谁先加载完谁执行。
动态创建Script标签
# 4. 负载均衡
之所以将负载均衡作为拓展内容,是因为如果是你自己搭建的个人网站,或者中小型网站,其实并不需要考虑多大的并发量,但是如果你搭建的是大型网站,负载均衡便是开发过程不可或缺的步骤。
# Nodejs处理IO密集的请求
我们都知道node的核心是事件驱动,通过loop去异步处理用户请求,相比于传统的后端服务,它们都是将用户的每个请求分配到异步队列进行处理。事件驱动的最大优势是什么?就是在高并发IO时,不会造成堵塞,对于直播类网站,这点是至关重要的,我们有成功的先例——快手,快手强大的IO高并发究其本质一定能追溯到node。
- 一般现在的企业网站都会做一个中间层,比如淘宝的双十一,可以很大的减轻负担
# pm2实现Node.js“多线程”
那些说node不行的都是指着node是单线程这一个软肋开撕,告诉你,我们有解决方案了——pm2,就是能在你的计算机里的每一个内核都启动一个node.js服务,也就是说如果你的电脑或者服务器是多核处理器(现在也少见单核了吧),它就能启动多个node.js服务,并且它能够自动控制负载均衡,会自动将用户的请求分发至压力小的服务进程上处理。
# nginx搭建反向代理
所谓代理就是我们通常所说的中介,网站的反向代理就是指那台介于用户和我们真实服务器之间的服务器,它的作用便是能够将用户的请求分配到压力较小的服务器上,其机制是轮询。听完这句话是不是感觉很耳熟,没错,在我介绍pm2的时候也说过同样的话,反向代理起到的作用同pm2一样也是实现负载均衡,你现在应该也明白了两者之间的差异,反向代理是对服务器实现负载均衡,而pm2是对进程实现负载均衡
更多内容
🎉 可以访问我的个人博客
← typescript 网络安全 →
关于评论
评论前请填好“昵称”、“邮箱”这两栏内容,否则不会收到回复,谢谢!