Web性能问题

Posted 学无止境

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web性能问题相关的知识,希望对你有一定的参考价值。

一、提升网站性能:前端性能优化就是让网站打开速度更开,提升用户体验。

  1、减少HTTP的请求

     原因:用于HTTP请求是无状态的,所以每次请求都需要重新建立连接,这是一个复杂的过程,既消耗时间成本又消耗资源。时间成本是用户需要等待所需要的;资源成本就是由于每一个请求都需要携带数据,所以需要占用带宽;同一时间请求数超过浏览器的上限后,浏览器就会分批进行,用户的等待时间就会增加。

     方法:那么如何减少HTTP请求呢?

         ① 设置HTTP缓存:将一些常用的资源在第一次加载时缓存到本地,再次加载就会减少HTTP的请求

         ② 资源合并压缩:CSS、JS代码等都可以用响应的工具进行压缩

         ③ 雪碧图:合并CSS图片可以减少HTTP的请求

         ④ 懒加载:在某些条件下或者页面刚加载时会减少HTTP的请求

  2、资源加载的位置优化

    ① 将CSS代码放到head中:让浏览器尽快加载CSS,由于页面渲染是在CSS代码全部下载之后进行的,例如将CSS放到body中时可能在CSS还没有完全下载时页面就进行渲染,这样会使页面从无CSS到有CSS的过程,用户体验较差。

    ② 处理页面的JS文件放在head中,body中尽量不要出现<script> <style>标签,即尽量使用外部引用的JS文件

    ③ 将JS代码放到body的最底部。因为JS代码是立即执行的,有可能会阻塞页面造成页面加载缓慢,因此javascript最好放在页面最下面。但如果页面解析时就需要用到javascript,这时放到底部就不合适了

  3、资源加载的时机

    ① 异步加载script:  

      -defer:  异步加载,在html解析完成后执行。defer的实际效果与将代码放在body底部类似

      -async: 异步加载,加载完成后立即执行

    ② 模块按需加载:

      ● ES6中的import() 语法

        ◇ 带有type=”module”的<script>标签,都是异步加载,不会堵塞浏览器,页面渲染完再执行模块脚本,等同于打开了<script>标签的defer属性 。
   
           
        ◇ ES6模块允许内嵌在网页中,语法行为与加载外部脚本一致,如下:
           

 

 

      ● webpack 特定的 require.ensure

    ③ 预加载preload:浏览器提前加载指定资源,需要执行时再执行,不阻塞渲染和document的onload事件

 

 

        ◇ 在JS中创建img对象,将图片的URL设置为src属性的值

        

      注意:预加载是提前加载,而懒加载是推迟加载或者不加载,虽然都能提升网页的性能,但是懒加载可以减缓服务器的压力,而预加载会增加服务器的压力

    ④ 预读取prefetch:是link标签中rel的属性值,告诉浏览器加载下一页面可能会用到的资源,可以加速下一个页面的加载速度    

      【区分】

        preload 是告诉浏览器页面必定需要的资源,浏览器一定会加载这些资源

        prefetch 是告诉浏览器页面可能需要的资源,浏览器不一定会加载这些资源

      【不要混用】

        preload 和 prefetch 混用的话,并不会复用资源,而是会重复加载

        

    ⑤ 懒加载:也叫做资源延迟加载,延迟加载资源或符合某些条件时才加载某些资源

      如下图,利用了函数节流,当网页滚动到可视区域时才会被加载

      

 

 

 

  4、DOM操作优化

    ①  HTML Collection(HTML收集器,返回的是一个数组内容信息),document.images、document.forms 、getElementsByTagName()返回类数组对象,但是访问性能要比类数组对象差很多。遍历 HTML Collection时尽量将其 转换为数组后再遍历,尽量少访问它,比如遍历时可以将length属性、成员保存到局部变量后再使用局部变量。

    ② 减少重排与重绘

      ● 样式优化

        ◇ 避免使用CSS表达式,CSS表达式是动态设置CSS属性的强大但危险方法,它的问题就在于计算频率很快。不仅仅是在页面显示和缩放时,就是在页面滚动、乃至移动鼠标时都会要重新计算一次  

              

        ◇ 不要使用table布局,因为一个小改动可能会造成整个table重新布局。而且table渲染通常要3倍于同等元素时间

        ◇ 避免使用层级较深的选择器,或其他一些复杂的选择器,以提高CSS渲染效率

        ◇ 元素适当地定义高度或最小高度,否则元素的动态内容载入时,会出现页面元素的晃动或位置,造成回流

        ◇ 给图片设置尺寸。如果图片不设置尺寸,首次载入时,占据空间会从0到完全出现,上下左右都可能位移,发生回流

      ● 渲染层优化 

        ◇ 将动画应用到position属性为absolute/fixed(脱离文档流)的元素上。将需要多次重绘的元素独立为render layer渲染层,如设置absolute,可以减少回流带来的影响,但是在图层重组的时候会消耗大量的性能,所以要权衡利弊,有所选择。最好不要使用margin,会对四周的元素都造成位置的改变引发回流。

          ◇ 硬件加速(GPU加速)例如:transform、opacity、filter等属性可以启用硬件加速,并且不会引发重绘和回流。所以能用transform改变样式的不要用CSS样式。

        ◇ 牺牲平滑度换取速度,每秒移动一个会比移动10个像素的平滑度要好,但是引起的回流次数也多,所以当追求网站性能时就需要牺牲平滑度了

      ■ DOM优化

        ◇ 放弃传统的基于操作DOM的开发,使用VUE/React

        ◇ 减少DOM深度及DOM数量

          HTML 中标签元素越多,标签的层级越深,浏览器解析DOM并绘制到浏览器中所花的时间就越长,所以应尽可能保持 DOM 元素简洁和层级较少。      

        ◇ 批量操作DOM

          批量操作DOM,避免频繁操作DOM造成回流。使用模板字符串拼接或文档碎片

           

        ◇ 批量操作CSS样式

          通过切换class或者使用元素的style.csstext属性去批量操作元素样式

          

        ◇ DOM缓存处理

 

 

           

        ◇ DOM分离读写

          浏览器具有惰性渲染机制,连接多次修改DOM可能只触发浏览器的一次渲染。而如果修改DOM后,立即读取DOM。为了保证读取到正确的DOM值,会触发浏览器的一次渲染。因此,修改DOM的操作要与访问DOM分开进行.

          会刷新渲染队列的属性有:offsetTop offsetLeft offsetWidth offsetHeight / clientTop clientLeft clientWidth clientHeight / scrollTop scrollLeft scrollWidth scrollHeight / currentStyle getComputedStyle...

          

 

 

 

        ◇ 事件代理

          事件代理是指将事件监听器注册在父级元素上,由于子元素的事件会通过事件冒泡的方式向上传播到父节点,因此,可以由父节点的监听函数统一处理多个子元素的事件

          利用事件代理,可以减少内存使用,提高性能及降低代码复杂度

        ◇ 防抖和节流

          使用函数节流(throttle)或函数去抖(debounce),限制某一个方法的频繁触发

        ◇ 及时清理环境

          及时消除对象引用,清除定时器,清除事件监听器,创建最小作用域变量,可以及时回收内存

 

以上是关于Web性能问题的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Web性能测试

7步实现Web性能全面监控

打个总结:Web性能优化

Web性能问题

提高 ASP.NET Web 应用性能

极致Web性能:SPA性能指南