前端的重要性
前端是用户体验,用户体验即是价值的体现。产品的性能、产品的开发者,产品的体验者,产品性能都属于前端开发者的范围内
首先需要一个平台去检测您的网页性能如何
首先需要一个检测结果去判断您的网页性能,评测出性能好或者不好,有了评测结果的细则,才能够知道性能的问题处在哪里,才能够针对性的进行优化
好的网站有哪些优势:
- 内容有吸引力
- 访问速度快
- 支持频繁的用户互动
- 可以在各处浏览无障碍
业务场景
一般用户反应是页面卡。但是因为设备不同、浏览器兼容、网络快慢、产品设计等原因,开发或者研发很少能复现。如果我们无法去复现用户页面卡的问题,那么我们就很难针对性的去处理,只能去撒网式的去处理。
提升网页性能优化的几个方法:
减少http请求的次数
我么您可以通过调试工具去查看请求链接的个数和请求文件的大小。
https比http慢很多
把绝对路劲改成相对路径
使用相对路径替代绝对路径,相对路径不需要再去解析域名,减少了请求次数。以图片举例* <img src="https://www.zhongyin.net.cn/img/1.png">
这个是完整的图片地址,相对路径是<img src="/img/1.png">
。
cnd对性能优化的作用
网络是有轨迹的,我们通过当地上网,去连接很远地方的服务器时,时间就长了,如果我们的附近有一个服务器,那么会加快我们的加载速度,而cdn就是解决这个问题的。
举一个例子说明cdn的作用:
以前买火车票大家都只能去火车站买,后来我们买火车票就可以在楼下的火车票代售点买了。
百度对cdn的解释是:
CDN的全称是Content Delivery Network,即内容分发网络。
CDN是构建在现有网络基础之上的智能虚拟网络
,依靠部署在各地的边缘服务器
,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容
,降低网络拥塞,提高用户访问响应速度和命中率
。
如果要说清楚cdn是什么的话,就要从一下几个方面的知识入手:
1,服务器与互联网
服务器与网络的链接,其实就是服务器的贷款,这个就是比较固定了,就是买了多少带宽,你就有多快的速度。
2, 运营商之间的互联互通
移动的网和联通的网,如果要共享信息,那么就需要到一个数据交互中心的服务器上进行数据的更换。如果都是北京的用户只是使用不同的网络,而数据交互中心服务器在湖南,那么就数据交互路程就会变的特别的远。这个就是运营商之间的互联互通。
3,cdn的介绍
它将储存在目标服务器的资源缓存在了离终端较近的节点服务器中,等下次再获取时,就直接从节点服务器上获取。 这样就大大降低了请求获取资源的时间。
使用负债均衡:
CDN会通过负载均衡技术,将用户的请求定向到最合适的缓存服务器上去获取内容。 比如说,北京的用户,我们让他访问北京的节点,深圳的用户,我们让他访问深圳的节点。通过就近访问,加速用户对网站的访问,进而解决Internet网络拥堵状况,提高用户访问网络的响应速度。
cnd就是选择最近的节点:
互联不互通、区域ISP地域局限、出口带宽受限制等种种因素都造成了网站的区域性无法访问。CDN加速可以覆盖全球的线路,通过和运营商合作,部署IDC资源,在全国骨干节点商,合理部署CDN边缘分发存储节点,充分利用带宽资源,平衡源站流量。阿里云在国内有500+节点,海外300+节点,覆盖主流国家和地区不是问题,可以确保CDN服务的稳定和快
cdn的原理图:
可以粗略的理解是:
1,用户发起请求
2,本地dns解析是否有缓存,如果没有往下执行,如果有则返回。
3,以阿里云为例,会访问阿里云的cdn调度中心,阿里云的调度中心会把最近的阿里云服务器的节点ip分配给用户
4,用户获取到最近的服务器节点。这个节点服务器就是cdn。
阿里云在全国有500个节点
减少dns解析提升网页加载速度
浏览器在加载网页时会对网页中的域名进行解析缓存。
dns解析缓存,当用户点击链接跳转时直接从缓存里获取解析结果,无需再进行dns解析,这样可以减少用户的等待时间,提升性能。
- 京东首页关于cdn中dns的解析:
<link rel="dns-prefetch" href="//static.360buyimg.com"/>
css和js在页面的位置
一般是css文件放到页面的头部,从一开始就加载就加载css文件,这样等加载到html文件的时候,就可以看到被css修饰过的内容。
js文件一般是放入到页面的底部,因为js是单线程,会阻止页面的加载,会影响页面的显示效果。
以谷歌浏览器为例,我们会看到页面的加载顺序,其实从一开始加载的就是html文件,然后才会从上到下开始解析:如下图:
使用字体图标替代图片图标
我们一开始都是用雪碧图,但是自从iconfront图标出现之后,雪碧图几乎就淘汰了。
iconfront是图标库。
需要svg的格式图片进行处理后才可以,我的用的是阿里巴巴图标库,地址如下:
图片的优化
因为浏览器的并发限制: 因为图片是属于异步加载的,是可以同时加载多张,但是浏览器是有并发的上线的,一次只能是多少张同时进行请求。 当上一轮的请求在加载时,下一轮的请求才会继续。
- 首先肯定是把图片进行一个压缩
- jpeg图片压缩,叫做有损压缩。一般对于需要高清还原的图片就不用jpg最好是用png的。
- png的图片,是无损的高清图片,它的特点是透明的无背景的图片。
- gif的图片也是支持透明度的、动画图片。不过他并不是高清图片。
- webp图片将上述图片优点与一身,既可以支持高清、动画、透明、文件下。缺点是:ios支持的不太好。
在网上找到了一些压缩的工具:
熊猫压缩
智图压缩
suqoosh压缩
compressor压缩
使用雪碧图
为什么使用雪碧图?
首先浏览器的并发是有限制的,以chrome为例,它的并发量是6个。所以要减少图片请求的次数,如果一张雪碧图上有10个小图,可以理解为本该是10个小图有10次请求,如果合并成一张雪碧图的话一张就够了。
雪碧图的原理:
同一个地址的图片,浏览器只会请求一次,如果地址相同,浏览器只会从缓存中读取。因为计算玩的就是内存,所以访问的地址是一定会在内存进行保存的。
懒加载
图片懒加载其实就是一开始不加载图片,而是把图片的地址保存在某一个位置,例如保存在data-src的属性里,然后等页面到达某一个位置时,在把这个地址放入到图片的src的属性里边。
代码如下:
function lazyload() {
let viewHeight = document.body.clientHeight //获取可视区高度
let imgs = document.querySelectorAll('img[data-src]')
imgs.forEach((item, index) => {
if (item.dataset.src === '') return
// 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置
let rect = item.getBoundingClientRect()
if (rect.bottom >= 0 && rect.top < viewHeight) {
item.src = item.dataset.src
item.removeAttribute('data-src')
}
})
}
// 可以使用节流优化一下,节流是可以简单的处理了这个的性能问题,但也不是处理的很好的。
window.addEventListener('scroll', lazyload)
不过懒加载有一个不好的地方是:
就是每次加载的时候都是需要去计算举例,其实这个计算也会耗电性能。
有一个方法是可以实现这一种的:
IntersectionObserver 不过它有一些兼容性的问题,尤其是在ie6,7,8上。
预加载
这个是指我们可以使用css的background和js控制图片预先加载。就是页面的某些地方可能需要用到一些图,不过这些图一开始不在用户的视线范围之内,但是当页面加载完毕后,即使这些图片不在加载范围之内也会进行加载。当这些图片出现在用户的视线范围之内时,页面会从缓存里边获取这些图片。
与懒加载的区别: 懒加载是图片到某一个位置时进行图片的加载。 而预加载是当页面加载完毕后,不管它有没有出现在可视窗口被人看见,它都会加载。它的优点:当出现可视出口时不需要再加载而是直接从缓存里获取图片。
响应式图片(pictrue和媒询)
- 媒询:
就是通过浏览器宽度的不同的,加载不同的图片。如下代码是浏览器宽度小于750和大于750时加载不同的图片。 所以媒询是可以对页面的加载起到一定的优化作用的。
媒询是可以优化图片的,是属于优化图片的一种方式。
@media screen and (max-width:750px) {
h1{
background: url(/1.png);
}
}
@media screen and (min-width:750px) {
h1{
background: url(/2.png);
}
}
- pictrue 的方式和媒询是比较相似的:
优点:当图片不符合加载的宽度时,图片是不会加载的。只有当图片符合宽度图片才会被加载。
缺点:写起来比较麻烦
如下代码:
<picture>
<source srcset="https://www.zhongyin.net.cn/img/html5_join/course/fz/banner.png" media="(min-width:1200px)">
<!--图片在宽度小于1200px的时候显示出来-->
<source srcset="https://www.zhongyin.net.cn/img/html5_join/course/fz/theory-one.png" media="(max-width:1200px)">
<img src="https://www.zhongyin.net.cn/img/html5_join/course/fz/theory-one.png" alt="">
</picture>
小图替代大图,等都加载后手动加载大图
这个其实是增加用户的体验效果。
原理:
一开始加载一个非常小的图标,等图片加载成功了再把加载的地址赋值到img标签的src属性上。
骨架屏其实就是一种小图替代大图的方式。
使用css3替代图片
某一些图片可以用css的样式来替代,可以是css3的背景图,也可以是其他的。
如果能够用css3或者css来替代的就用css来替代,这样会更容易。
提取公共库来减少代码的冗余
多余的代码就会是多余的文件。如果把冗余的代码放入到一个文件里边的话,那么就会减少请求的次数。
例如公共文件,可以把使用相同的代码放入到一个文件中。
减少重排重绘
浏览器渲染的过程:
第一步:解析HTML生成DOM树。
第二步:解析CSS生成CSSOM规则树。
第三步:解析JS,操作 DOM 树和 CSSOM 规则树。
第四步:将DOM树与CSSOM规则树合并在一起生成渲染树。
第五步:遍历渲染树开始布局,计算每个节点的位置大小信息。
第六步:浏览器将所有图层的数据发送给GPU,GPU将图层合成并显示在屏幕上。
重排
当改变 DOM 元素位置或大小时,会导致浏览器重新生成渲染树,这个过程叫重排。
重绘
当重新生成渲染树后,就要将渲染树每个节点绘制到屏幕,这个过程叫重绘。不是所有的动作都会导致重排,例如改变字体颜色,只会导致重绘。记住,重排会导致重绘,重绘不会导致重排 。
重排和重绘这两个操作都是非常昂贵的,因为 JavaScript 引擎线程与 GUI 渲染线程是互斥,它们同时只能一个在工作。
什么操作会导致重排?
- 添加或删除可见的 DOM 元素
- 元素位置改变
- 元素尺寸改变
- 内容改变
- 浏览器窗口尺寸改变
如何减少重排重绘?
- 用 JavaScript 修改样式时,最好不要直接写样式,而是替换 class 来改变样式。
- 如果要对 DOM 元素执行一系列操作,可以将 DOM 元素脱离文档流,修改完成后,再将它带回文档。推荐使用隐藏元素(display:none)或文档碎片(DocumentFragement),都能很好的实现这个方案。
使用事件委托
使用事件委托能极大的减轻我们的工作量,同时也能提高页面的性能。
优点:
-
可以减小内存消耗 使用事件委托可以大量节省,减少事件的定义
-
可以动态绑定事件
有时我们需要动态增加或移除页面中的元素 使用事件委托就没有这么麻烦了,无论是增加还是减少 ul 标签中的 li 标签,即不需要再为新增的元素绑定事件,也不需要为删除的元素解绑事件。
如果事件在父标签身上,当我们增加了子元素,那么会自动给这个子元素加上该有的事件。