写点什么

浅析 Web 前端性能优化

  • 2020-02-14
  • 本文字数:2699 字

    阅读完需:约 9 分钟

浅析Web前端性能优化

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


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


通过上面可以看出浏览器分为三部分来实现用户的使用,我们就从这三个部分来浅析如何提升 WEB 前端性能。


一、 请求


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


1506321631051056382.png


浏览器的请求有些是并发的,有些是阻塞的。图片、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 对象,而不是把异步改成同步。


本文转载自宜信技术学院网站。


原文链接:http://college.creditease.cn/detail/143


2020-02-14 18:55818

评论

发布
暂无评论
发现更多内容

知识点:操作系统异常的分类

王坤祥

操作系统 异常

百度联合发布全球最大中文自然语言处理数据共建计划“千言”

百度大脑

人工智能 百度 nlp 百度大脑

3D渲染集群,你了解多少?

华为云开发者联盟

容器 华为云 集群 3D渲染 3D模型

从“人居美学”的理念出发,木莲庄酒店很不一样

InfoQ_967a83c6d0d7

ARTS 挑战打卡第十二周(200727-200802)

老胡爱分享

ARTS 打卡计划

一行代码实现简易服务器并共享文件

王坤祥

Python 共享文件

linux入门系列12--磁盘管理之分区、格式化与挂载

黑马腾云

Linux centos 编辑器 linux运维 vi/vim

SpreadJS 纯前端表格控件应用案例:货运代理客户服务平台

葡萄城技术团队

linux入门系列13--磁盘管理之RAID、LVM技术

黑马腾云

Linux centos raid lvm 磁盘挂载

linux入门系列14--ssh服务及主机远程管理

黑马腾云

Linux centos linux运维 红帽认证

Python中的global关键字的用法以及如何设置项目级的Global变量

陈磊@Criss

一键超频 双C Carry,普通用户如何挖潜英特尔十代酷睿?

E科讯

七夕情人节,程序员的表白方式简直太秀了!

程序员生活志

程序员 七夕

【程序员自救指南】一个证书,让我哄好了小师妹

华为云开发者联盟

网络安全 浏览器 华为云 SSL证书 安全证书

正向代理与反向代理

王坤祥

nginx 反向代理 代理 正向代理与反向代理 Proxy

linux入门系列11--Centos7网络服务管理

黑马腾云

Linux centos 网络配置 运维工程师

工作就是解决一个又一个问题

escray

学习 面试

ARTS 挑战打卡第十三周(200803-200809)

老胡爱分享

ARTS 打卡计划

高效程序员的45个习惯:敏捷开发修炼之道(5)

石云升

敏捷开发 熵增 用代码沟通

英特尔大小核试水 将推出8+8+1架构酷睿处理器

E科讯

兼具艺术情怀和舒适旅居体验,木莲庄做了什么

InfoQ_967a83c6d0d7

3.7亿条保单数据怎么分析?这个大数据平台有绝招

华为云开发者联盟

大数据 hadoop 数据湖 FusionInsight Kyligence

linux入门系列15--文件传输之vsftp服务

黑马腾云

Linux centos linux操作 linux运维

SpreadJS 纯前端表格控件应用案例:PtLims云平台

葡萄城技术团队

7. Jackson用树模型处理JSON是必备技能,不信你看

YourBatman

json Jackson ObjectMapper 树模型

SpreadJS 纯前端表格控件应用案例:立信智能审计云平台(SACP)

葡萄城技术团队

SpreadJS 纯前端表格控件应用案例:实验室信息化管理系统

葡萄城技术团队

乘风人脸识别来了,企业能得到什么?

ToB行业头条

人工智能 人脸识别 百度大脑

Python实现一个计时功能的装饰器

王坤祥

Python 装饰器

大数据思维与运用

石云升

大数据 数据建模 数据驱动

LeetCode题解:20. 有效的括号,for循环replace,JavaScript,详细注释

Lee Chen

大前端 LeetCode

浅析Web前端性能优化_行业深度_马宗泽_InfoQ精选文章