什么是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,则不建议更改。

二、传输

从服务器往客户端传输,可以开启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对象,而不是把异步改成同步。

作者:马宗泽

来源:宜信技术学院

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

  1. Web前端性能优化教程01:减少Http请求

    性能黄金法则 只有10%-20%的最终用户响应时间花在接收请求的HTML文档上,剩下的80%-90%时间花在HTML文档所引用的所有组件(图片,script,css,flash等等)进行的HTTP请求 ...

  2. 一个vue请求接口渲染页面的例子

    new Vue({ el:'#bodylist', data: { list: [ { "type_id": "1", "type_name" ...

  3. http、tcp及从请求到渲染的过程

    http.tcp及从请求到渲染的过程 https://blog.csdn.net/pambassador/article/details/88539478 http请求的结构内容 https://ww ...

  4. 解决Spring MVC无法接收AJAX使用PUT与DELETE请求传输的内容

    解决Spring MVC无法接收AJAX使用PUT与DELETE请求传输的内容 解决方案 在 Web.xml文件中 加入以下代码 <!--解决ajax Put与Del请求无法接收到传输的内容-- ...

  5. drf框架 - 请求模块 | 渲染模块

    Postman接口工具 官方 https://www.getpostman.com/ get请求,携带参数采用Params​post等请求,提交数据包可以采用三种方式:form-date.urlenc ...

  6. 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)

    目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...

  7. drf框架概况-resful接口规范-请求模块-渲染模块-Postman-drf请求生命周期

    drf框架 全称:django-rest- framework 知识点: """ 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码-基于restful ...

  8. 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)

    一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...

  9. 前端性能优化成神之路--SSR(服务端渲染)

    Nuxt.js的介绍 Nuxt.js概述 nuxt.js简单的说是Vue.js的通用框架,最常用的就是用来作SSR(服务器端渲染).Vue.js是开发SPA(单页应用)的,Nuxt.js这个框架,用V ...

随机推荐

  1. go 学习笔记之go是不是面向对象语言是否支持面对对象编程?

    面向对象编程风格深受广大开发者喜欢,尤其是以 C++, Java 为典型代表的编程语言大行其道,十分流行! 有意思的是这两中语言几乎毫无意外都来源于 C 语言,却不同于 C 的面向过程编程,这种面向对 ...

  2. react-navigation

    安卓端React Navigation的TabNavigator选项卡与react-native-scrollable-tab-view.FlatList一起使用,只显示第一页的内容. 解决方案: 给 ...

  3. 2019heox博客部署到coding该绕的坑-奥怪的小栈

    文章转载于:2019heox博客部署到coding该绕的坑-奥怪的小栈 这篇文章适用于初次部署和部署到github后想双线部署到coding的朋友们,我将带你们绕过一些我踏过的坑. 前言 我一开始没打 ...

  4. FileUtils工具类的使用

    import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.DirectoryFileFilter; ...

  5. 16.XML语法、CDATA、约束(DTD、Schema)讲解

    xml主要用来描述数据,比如配置文件,网络之间传输数据等,并且在android中也经常用xml来布局,,接下来便来学习xml常用的东西 1.XML语法 xml语法分为: 1.1 文档声明 必须位于文档 ...

  6. Demo小细节-2

    今天在牛客的题海中再次找虐,题目如下: public class B { public static B t1 = new B(); public static B t2 = new B(); { S ...

  7. 借助腾讯云的云函数实现一个极简的API网关

    借助腾讯云的云函数实现一个极简的API网关 Intro 微信小程序的域名需要备案,但是没有大陆的服务器,而且觉得备案有些繁琐,起初做的小程序都有点想要放弃了,后来了解到腾讯云的云函数,于是利用腾讯云的 ...

  8. 深入浅出TypeScript(3)- 函数重载和泛型

    面向对象特性中,最根本的就是面向对象的三大基本特征:封装.继承.多态.同时,TypeScript中也存在多态的使用,比如函数重载,今天我们先看一下函数重载以及泛型的概念. 什么是函数重载 简单来说,函 ...

  9. Elasticsearch 在docker和centos下的安装教程

    前言 新版本的Elasticsearch不能以root用户来运行.因此,MAC下建议使用Docker来安装. 国内各版本镜像:点击这 Centos7.4 64位 第一步 下载.tar.gz的安装包 不 ...

  10. 51nod 1020 逆序排列(dp,递推)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1020 题意:是中文题. 题解:很显然要设dp[i][j]表示 ...