统计web性能优化的问题

323 阅读10分钟

前端的重要性

前端是用户体验,用户体验即是价值的体现。产品的性能、产品的开发者,产品的体验者,产品性能都属于前端开发者的范围内

首先需要一个平台去检测您的网页性能如何

首先需要一个检测结果去判断您的网页性能,评测出性能好或者不好,有了评测结果的细则,才能够知道性能的问题处在哪里,才能够针对性的进行优化

好的网站有哪些优势:

  • 内容有吸引力
  • 访问速度快
  • 支持频繁的用户互动
  • 可以在各处浏览无障碍

业务场景

一般用户反应是页面卡。但是因为设备不同、浏览器兼容、网络快慢、产品设计等原因,开发或者研发很少能复现。如果我们无法去复现用户页面卡的问题,那么我们就很难针对性的去处理,只能去撒网式的去处理。

提升网页性能优化的几个方法:

减少http请求的次数

image.png

我么您可以通过调试工具去查看请求链接的个数和请求文件的大小。

https比http慢很多

image.png

把绝对路劲改成相对路径

使用相对路径替代绝对路径,相对路径不需要再去解析域名,减少了请求次数。以图片举例* <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的原理图:

image.png

可以粗略的理解是:

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文件,然后才会从上到下开始解析:如下图:

image.png

使用字体图标替代图片图标

我们一开始都是用雪碧图,但是自从iconfront图标出现之后,雪碧图几乎就淘汰了。

iconfront是图标库。

需要svg的格式图片进行处理后才可以,我的用的是阿里巴巴图标库,地址如下:

iconfront图标库

图片的优化

因为浏览器的并发限制: 因为图片是属于异步加载的,是可以同时加载多张,但是浏览器是有并发的上线的,一次只能是多少张同时进行请求。 当上一轮的请求在加载时,下一轮的请求才会继续。

  • 首先肯定是把图片进行一个压缩
  • 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 标签,即不需要再为新增的元素绑定事件,也不需要为删除的元素解绑事件。

如果事件在父标签身上,当我们增加了子元素,那么会自动给这个子元素加上该有的事件。