每日一博 | 如何从请求、传输、渲染 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,则不建议更改。
二、传输
从服务器往客户端传输,可以开启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对象,而不是把异步改成同步。
作者:马宗泽
来源:宜信技术学院
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
OSChina 周三乱弹 —— 华佗就是这么治曹操的
Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 小小编辑推荐:《A Thousand Years》- Christina Perri 《A Thousand Years》- Christina Perri 手机党少年们想听歌,请使劲儿戳(这里) 反正朋友圈里都是这样的, @平安OSC :微信官方:我给你个大嘴巴子我 不用你打了, “脸大不是因为胖,是因为没消肿。” 你要是换完了, 貌似就不能换回来了, 大王(@罗马的王)做的实验, @罗马的王 :微信头像加了国旗就被套牢了,等国庆过了才可以换吧 有国旗还挺好看的, 中国骄傲么! @afterer :中国女排 3:0韩国,3:0 客麦隆,3:0俄罗斯,3:0 多米尼加,3:0 日本,3:2 巴西,3:0美国,横扫天下无敌手 中国姑娘呀……, 别的国家vs中国女排。 运动的话, 对自己的改变还挺大的, @for_ :衣服咋越穿越大了? 然后, 再整整牙齿, @MonroeCode :牙套摘 漂亮+1。 我就不愿意去牙科看病去, 老觉得牙科是这样的, “华佗就是这么治曹操的。” 还有比治牙更难的呢。 结婚就比治牙难多了…… @萌呆凯凯 ...
- 下一篇
首批开源 Linux 智能手机 Librem 5 已开始发货,外观神似 iPhone
正如 9 月初 Purism 公司宣布的那样,为了兑现在 Q3 开始发货的承诺,首批开源 Linux 智能手机 Librem 5 已于昨天正式交付,并已安排发货。对了,Librem 5 的价格比较“感人” —— 699 美元。 据 Phoronix 的报道,首批发货的手机具有单独打磨的外壳、所有硬件组件以及未完成的开关盖。质量方面基本上是处于 alpha/beta 阶段。不过在未来的几个月/季度中,这款注重隐私的 Linux 智能手机的质量将继续得到改进。 因为 Purism 的创始人 Todd Weaver 表示:“Librem 5 采用的是迭代发货计划,它将随着递增的迭代版本批量发货。每次迭代都会在第一版手机的快速滚动版本中改进之前的版本,包括针对上下文的第二次修改计划。” 迭代计划使得 Purism 能够收集用户的反馈并迅速对下一代手机做出改进。Librem 5 的每次迭代都会包括对硬件、机械设计和软件的更新,购买者可以自行选择希望接收的批次。从今年九月到明年年底,完整的迭代计划分为 6 个批次,分别从 A 到 F、以树木名称来命名。 初始版Batch Aspen会提供所有硬件组...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Hadoop3单机部署,实现最简伪集群