HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

浅析 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:55914

评论

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

数字化时代,国内SaaS行业的发展态势

小炮

SaaS

网站开发进阶(二十五)JS实现将html表格导出为excel文件

No Silver Bullet

5月月更 表格导出

Python 操作 Excel,从 xlwings 模块开始

梦想橡皮擦

5月月更

OpenHarmony 3.1 Beta版本关键特性解析——分布式DeviceProfile

OpenHarmony开发者

OpenHarmony OpenHarmony 3.1 Release DeviceProfile

内存不超过5M,datop 在识别冷热内存及跨 numa 访存有多硬核?| 龙蜥技术

OpenAnolis小助手

cpu 内存 datop 轻量级 muma

Jeff Dean:深度学习的黄金十年

OneFlow

人工智能 深度学习 软件 硬件

云原生 on nLive:云上 Nebula Graph

NebulaGraph

数据库 图数据库 原生云

[Day36]-[二叉树]-在每个树行中找最大值

方勇(gopher)

LeetCode 二叉树 数据结构算法

云图说 | 华为云医疗智能体EIHealth,AI赋能基因组研究

华为云开发者联盟

华为云 云图说 EIHealth 医疗智能体 基因组

从研发效能的视角谈“故障复盘”

博文视点Broadview

【C语言】计算器

謓泽

5月月更

thinkphp5的消息队列详细教程

CRMEB

web前端培训Vite的原理源码解析

@零度

前端开发 vite

DevOps系列之 —— 持续规划与设计(一)敏捷项目管理理念与方法实践

若尘

DevOps 5月月更

《手写 Mybatis》第7步:SQL执行器的定义和实现

小傅哥

小傅哥 mybatis 面试经验 源码学习 手写Mybatis

动手实操丨RC522射频卡模块与IC卡完成充值消费查询的技术实现思路

华为云开发者联盟

stm32 RC522射频卡模块 IC卡 RC522

Redis 内存优化在 vivo 的探索与实践

vivo互联网技术

数据库 redis 性能优化 内存优化

Pipy for Next Web:静态内容服务与缓存加速

Flomesh

CDN加速 Pipy Headless CMS

跟我学Python图像处理丨获取图像属性、兴趣ROI区域及通道处理

华为云开发者联盟

Python OpenCV 图像处理 图像 ROI区域

What?构造的查询语句会导致堆栈溢出

华为云开发者联盟

neo4j 图数据库 堆栈溢出 查询语句 查询语言

大数据培训Flink怎样保证数据是一致性的

@零度

大数据 flink

网站开发进阶(十九)计划任务功能——信息自动弹出

No Silver Bullet

5月月更 自动弹窗

springsecurity从当前请求对象中获取用户信息

急需上岸的小谢

5月月更

OpenHarmony 3.1 Beta版本关键特性解析——ArkUI开发框架容器类API的介绍与使用

OpenHarmony开发者

OpenHarmony ArKUI 3.0 OpenHarmony 3.1 Release

面试突击44:volatile 有什么用?

王磊

Java Java面试题 java常见面试题

MongoDB 入门教程系列之一:开发环境搭建以及 Node.js 和 Java 的读写访问

汪子熙

数据库 mongodb 分布式 分布式数据库mongodb 5月月更

维权思考

成周

ONES 收购 SegmentFault 思否,共建高质量开发者社区

万事ONES

项目管理 程序员 研发管理 ONES

WebAssembly技术_加载ffmpeg在Web端调用解码

DS小龙哥

5月月更

多平台快速开发的UI框架

源字节1号

Java培训 判空的新写法

@零度

java8 JAVA开发 判空写法

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