如何从请求、传输、渲染3个方面提升Web前端性能

什么是WEB前端呢?就是用户电脑的浏览器所做的一切事情。我们来看看用户访问网站,浏览器都做了哪些事情:

输入网址 –> 解析域名 -> 请求页面 -> 解析页面并发送页面中的资源请求 -> 渲染资源 -> 输出页面 -> 监听用户操作 -> 重新渲染。

通过上面的路径可以看出浏览器分为请求、传输、渲染三部分来实现用户的访问,本文就从这三个部分来浅析如何提升WEB前端性能。

请求
浏览器为了减少请求传输,实现了自己的缓存机制。浏览器缓存就是把一个已经请求过的Web资源拷贝一份副本存储在浏览器中,当再次请求相同的URL时,先去查看缓存,如果有本地缓存,浏览器缓存机制会根据验证机制(Etag)和过期机制(Last-Modified)进行判断是使用缓存,还是从服务器传输资源文件。具体流程如下图所示:


浏览器的请求有些是并发的,有些是阻塞的,比如:图片、CSS、接口的请求是并发;JS文件是阻塞的。请求JS的时候,浏览器会中断渲染进程,等待JS文件加载解析完毕,再重新渲染。所以要把JS文件放在页面的最后。

JS也可以通过两种方式由阻塞改成并行:一种是通过创建script标签,插入DOM中;另一种是在Script标签中增加async属性。

每种浏览器对同一域名并发的数量有限制,IE6/7是2,IE9是10,其他常见的浏览器是6,所以减少资源请求数量和使用多域名配置资源文件,能大大提高网站性能。

减少资源请求数量的方法,大致有以下几种:

1、通过打包工具,合并资源,减少资源数量。就是开发版本是很多个资源文件,部署的时候,按类合并成几个文件来输出。在实现模块管理的同时,实现统一输出。

2、CSS中,使用css sprite减少图片请求数量。

3、通过延迟加载技术,在用户无感知的情况下请求资源。

4、通过服务器配置,实现一次请求,返回多个资源文件,如淘宝CDN那样。

除了减少请求数量,也可以使用CDN镜像,来减少网络节点,实现快速响应。使用了CDN的请求,会根据用户所处的地理位置,找寻最近的CDN节点,如果请求是新的,则从资源服务器拷贝到节点,然后再返回给客户端。如果请求已经存在,则直接从节点返回客户端。

通过上面我们了解的缓存机制,如果我们部署上线的时候,是需要刷新缓存的。普通缓存通过强刷就能改过来,而CDN缓存则需要通过改变URL来实现。同时我们不可能要求用户按着Ctrl来刷新,所以通过打包工具,在部署的时候,统一更改URL是最有效的方式。而不常变更的库文件,比如echart、jquery,则不建议更改。

在这里小编建了一个前端学习交流扣扣群:132667127,我自己整理的最新的前端资料和高级开发教程,如果有想需要的,可以加群一起学习交流

传输
从服务器往客户端传输,可以开启gzip压缩来提高传输效率。

Gzip有从1-10的十个等级。越高压缩的越小,但压缩使用的服务器硬件资源就越多。根据实践,等级为5的时候最均衡,此时压缩效果是100k可以压缩成20k。

渲染
浏览器在加载了html后,就会一边解析,一边根据解析出来的结果进行资源请求,并生成DOM树。而加载完毕的CSS,则被渲染引擎根据生成好的DOM树,来生成渲染树。等所有资源解析完毕计算好layout后,向浏览器界面绘制。随着用户操作,JS会修改DOM节点或样式,重新绘制和重新排列。重新绘制指的是绘制DOM节点对应的渲染节点,重新排列是指重新计算这些节点在浏览器界面的位置。很显然,重排是非常耗性能的。我们要做的是减少重排的次数。

生成DOM树的时候,我们可以通过减少DOM节点来优化性能。最初都是用table布局,节点深度和数量相当复杂,性能很差。同样CSS作为层叠样式表,层级也不可太深,不然遍历的成本很高。另外CSS的expression属性相当耗性能,能不用则不用。动画效果能用CSS写的就不用JS写,渲染引擎不一样,性能损耗也不一样。

上面说的是解析渲染的过程,我们再接着说说用户交互操作的过程。用户操作就会导致重绘和重排,重排一定会引起重绘,而重绘不一定会引起重排。到底怎样会引起重排呢?简单的定义,DOM结构的变化,以及DOM样式中几何属性的变化,就会导致重排。几何属性顾名思义,就是宽、高、边框、外补丁、内补丁等俗称盒模型的属性。同时还有offset之类的边距属性。

重排是最耗能的,减少重排的方法有:

1、如果需要多次改变DOM,则先在内存中改变,最后一次性的插入到DOM中。

2、同上一条,如果多次改变样式,合成一条,再插入DOM中。

3、由于position的值为absoute和fixed时候,是脱离文档流的,操作此类DOM节点,不会引起整页重排。所以动画元素设置position使其脱离文档流。

4、当DOM节点的display等于none的时候,是不会存在于渲染树的,所以如果有比较复杂的操作,先使其display等于none,等待所有操作完毕后,再将display设成block,这样就只重排两次。

5、获取会导致重排的属性值时,存入变量,再次使用时就不会再次重排。获取这些属性会导致重排:offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

以上就是浏览器如何把资源变成肉眼所见的页面的,除了上述根据浏览器流程而总结出来的性能优化,我们还需要看看javascript作为程序,需要的优化。先来看看javascript的垃圾回收机制。

Javascript的引擎会在固定的时间间隔,将不再使用的局部变量注销掉,释放其所占的内存。而闭包的存在,将使引用一直存在,无法被释放掉。全局变量的生命周期直至浏览器卸载页面才会结束。所以一般来讲,内存溢出就是由于全局变量的不释放和闭包引起。为了防止内存溢出,我们可以做的方法有:

1、业务代码放在匿名立即执行函数里面,执行完毕会立即释放掉。

2、少用全局变量,同时用完的变量手动注销掉。

3、使用回调来代替闭包访问内部属性

4、当不可避免使用闭包时,慎重的对待其中的细节。不用的时候注销掉。

5、通过浏览器自带的工具profiles,来检查内存活动情况。如果是波浪型的,说明正常。如果是倾斜式渐进上涨的,说明有内存不会被释放,需要检查相应的函数。

最后再说一点,函数里返回异步取的值,经常有人这么:

Var getList = function(){ $.ajax().then(function(data){

Return data;

}) };

Var users = getList();

毫无疑问,由于函数内的返回是异步的,所以返回只能是undefined,而不是想要的data。于是为了实现返回data,就把ajax的async属性设置成了false,由异步改为同步,来获取到data。然而最大的问题来了,同步是会中断渲染进程的,也就是请求返回的等待中,整个页面是卡死的,用户操作也不会有响应。这个问题真正的解决方案是返回promise对象,而不是把异步改成同步。

原文地址:https://blog.51cto.com/14447253/2422829

时间: 2024-10-05 23:33:20

如何从请求、传输、渲染3个方面提升Web前端性能的相关文章

django-rest framework 框架生命周期 请求模块 渲染模块 解析模块 异常模块 响应模块

一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from rest_framework.views import APIView #视图,以后都继承这个,这个也是继承views后一顿操作完善了功能 from rest_framework.response import Response #响应 from rest_framework.request impo

前端性能优化篇—资源合并与压缩减少HTTP请求

资源合并与压缩减少HTTP请求的概要 资源合并与压缩减少HTTP请求主要的两个优化点是减少HTTP请求的数量和减少请求资源的大小 http协议是无状态的应用层协议,意味着每次http请求都需要建立通信链路.进行数据传输,而在服务器端,每个http都需要启动独立的线程去处理. 这些通信和服务的开销都很昂贵,减少http请求的数量和减少请求资源的大小可有效提高访问性能 减少http的主要手段是合并CSS.合并JavaScript.合并图片.将浏览器一次访问需要的javascript和CSS合并成一个

前端性能优化-减少http请求,dns预解析,减少repaint和reflow

前端性能优化方法: 一 . 减少http请求 (1)通过合并图片,减少请求,俗称css sprites(css精灵)css sprites (2)lazyload懒加载,在需要的时候再加载 1.定义:懒加载也称为延迟加载,图片需要用到的时候再去价值 2.用法:就是重写对象的get方法,当系统调用get方法再去加载对象 3.优点:(1)对象的实例化在getter方法中,各司其职,降低耦合性:(2)真正需要资源时,再去加载,系统的内存占用率会减小 (3)压缩/合并css和js 二 .减少repain

web请求响应过程与python主流三大web框架

web请求流程: 首先一个浏览器通过http协议发送一个请求,到我们的服务器,首先是wsgiref接收这个请求,并且解析这个请求中的数据,并将这个数据全部解析成一个env的大字典,wsgiref封装的就是socket连接和数据解析的功能,解析之后得到数据,就能知道浏览器的请求是什么,然后拿着请求类型和urls中的路由与视图函数映射关系获取到到低是要哪个视图,匹配成功之后,再到views.py的具体的视图中去,执行这个具体的特定的视图函数,这个视图函数在执行的过程中,需要首先到templates中

CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率

当场景中有比较复杂的模型时,条件渲染能够加速对复杂模型的渲染. 条件渲染(Conditional Rendering) 当我们能够断定一个模型被其他模型挡住(因此不会被Camera看到)时,我们就可以跳过对此模型的渲染.这就是条件渲染的根本. 那么如何去判断?方法就是用一个简单的包围盒(比如一个立方体)去渲染一下,看看fragment是不是有变化(即包围盒上的某些部分通过了depth test,最终渲染到Framebuffer上了).如果没有任何一个fragment发生改变,就说明这个包围盒是被

echarts通过ajax向服务器发送post请求,servlet从数据库读取数据并返回前端

1.echarts的官网上的demo,都是直接写死的随机数据,没有和数据库的交互,所以就自己写了一下,ok,我们开始一步一步走一遍整个流程吧. 就以官网最简单的那个小demo来做修改吧.官网上的小demo的效果图如下:(很熟悉,有没有) 2.按照echarts的使用方法新建一个echarts.html文件.为ECharts准备一个具备大小(宽高)的Dom(讲的有点细,熟悉的朋友直接跳过) <!DOCTYPE html> <head> <meta charset="u

基于http请求的web接口性能测试总结

基于http请求的web接口性能测试总结 压测的目的:对于Web接口压测的目的最终是要在对数据库造成压力的情况下观察压测服务器的cpu是否达到预警值.memory是否发生激变甚至泄露.响应结果的error率以及数据库服务器读写方面的情况是否正常等等情况. 测试环境的准备 我们要准备压测服务器和压力机,并建立二者之间的联系. 压测服务器 用来提供服务的,也就是我们的测试服务器,上面发布的是压测分支,我们首先要基于压测基准分支拉一个压测分支并push到远端,然后把开发的代码合到压测分支上再push到

web前端安全 XSS跨站脚本 CSRF跨站请求伪造 SQL注入

web安全,从前端做起,总结下web前端安全的几种技术: 1,XSS XSS的全称是Cross Site Scripting,意思是跨站脚本,XSS的原理也就是往HTML中注入脚本,HTML指定了脚本标记 XSS攻击分成两类,一类是来自内部的攻击,主要指的是利用程序自身的漏洞,构造跨站语句. 另一类则是来自外部的攻击,主要指的自己构造XSS跨站漏洞网页或者寻找非目标机以外的有跨站漏洞的网页.如当我们要渗透一个站点,我们自己构造一个有 跨站漏洞 的网页,然后构造跨站语句,通过结合其它技术,如社会工

web平台大数据请求传输性能处理

在XMLHttpRequest请求中使用ArrayBuffer方式,和后端服务器进行二进制的传输交互. 在项目中发现随着用户增长,部分前端功能,请求的数据量越来越大,传统的josn的方式,在下载.序列化时非常慢,因此尝试使用二进制+压缩的方式提升性能. 服务端Java代码: 实体类: public class ByteTest implements Serializable{ private static final long serialVersionUID = 407387312621541