前端性能优化的概念
-
web 性能概述
Web 性能其实就是 ** 页面性能 **,一个页面的性能如何,与页面是否能够疾速加载,是否容许用户疾速开始与之交互,滚动和动画是否晦涩等问题无关。
-
为什么要进行性能优化呢?
在构建 web 站点的过程中,任何一个细节都有可能影响网站的访问速度,如果不理解性能优化常识,很多不利网站访问速度的因素会造成累加,从而重大影响网站的性能,** 导致网站访问速度变慢,用户体验低下,最终导致用户散失 **。
# 一个例子引入为什么优化
当代前端有两大驱动的开发模式,别离是以 DOM 为驱动的传统开发模式和以数据为驱动的 MVVM 开发模式。
这里就以 DOM 为驱动的传统开发模式来介绍吧,次要解说的是优化的必要性,这里先不深刻探索前端优化的具体方面。
-
话不多说,举个例子:
<body> <div id="container"></div> <!-- script 脚本放在最初面也是一种优化,这样动态页面能够马上进去 --> <script> // 因为一万次输入,始终加载不出页面,js 阻塞了。为什么?怎么优化 for (var count = 0; count < 1000; count++) { document .getElementById('container') .innerHTML += '<span> 我是一个小测试 </span>'; } </script> </body>
- 解释一下这一段代码
这一段代码在 html 的 body 里写了一个盒子 div,其 id 为 container,上面应用 script 标签写了一段 JavaScript 代码,这一段 JavaScript 代码是一段 DOM 的操作,其要循环执行一万次,document.getElementById('container').innerHTML += '<span> 我是一个小测试 </span>';
办法介绍 (为了还没学习 DOM 的前端新人们):getElementById() 办法可返回对领有指定 ID 的第一个对象的援用。
而 innerHTML 属性设置或返回表格行的开始和完结标签之间的 HTML。
所以 dom 操作执行的就是获取 id 为 container 的那一段 HTML,并为其增加上一万个<span> 我是一个小测试 </span>
。
取得下图成果:
失去一个充斥一万个“我是一个小测试”的页面
DOM 操作下 <span> 我是一个小测试 </span>
也全副增加进了 div 盒子里。
这段代码要实现的是,在 div 盒子里增加 10000 句话,所以写了一个 for 循环,在 for 循环里。进行 DOM 操作,找到节点,增加元素,进行一万次,完满实现!
- 可是你真的认为能那么轻易的出的来吗?
必定出不来!
除非你电脑性能比我的好,而且就算能进去也很慢。
给你们看看实在成果!
不信能够复制代码,本人运行一遍~~
# 为什么会呈现这样的问题
## 简略介绍页面显示
- 页面由三个文档形成,HTML,CSS,和 JavaScript 脚本。
渲染引擎外部的 HTML 解析器(HTMLParser)模块,将 HTML 字节流转换为 DOM 构造。造成了 DOM 树,css 解析执行 基于 DOM 树 树生成 css 渲染树(CSSOM 树),遍历这颗渲染树。于是呈现了动态页面。
- js 作为专为浏览器设计的脚本语言,其的作用就算负责页面的交互和操作页面,就像下面 代码的 DOM 操作,为页面增加了 10000 个 span。
代码注意事项
- HTML 文档执行时,是依照前后程序来执行的,下面代码中,咱们把 JavaScript 代码放到 了最初面也是一种优化,最初执行 JavaScript 代码能把工夫都让给页面渲染,让用户 先看到页面,交互后产生。当然这里放前面的次要起因是:要对 div 盒子进行操作,首 先要有这个 div 盒子,要是 JavaScript 代码放最后面先运行,这个时候 div 都还没有运 行进去,取得的结点对象都是空,何谈退出 10000 个 span。
为什么会耗时
咱们逐渐剖析
- 次要耗时间的局部在 JavaScript 代码上,JavaScript 的下载和执行会 阻塞 用户界面的绘制和其余资源的下载,这里有一个 10000 次的 for 循环,是因为 10000 次的 for 循环耗时导致页面慢到出不来吗?显然不是,事实上就算是 10000 次的循环也能在 1ms 内进行完。
- for 循环里的 DOM 操作,外面有查找和批改 DOM 树,这是个十分耗时的中央,操作 DOM 导致 DOM 树结构或者几何属性(宽度,高度,间距等)产生了变动,就会触发 重排和重绘。
- DOM 和 JavaScript 是 2 个独立的性能,只通过 API 作为桥梁连贯,用 JavaScript 操作 DOM 时要两头跑一遍,这就 十分耗时,再回头看结尾代码,在 for 循环里查找了一万次指定 ID 的对象,且还在 DOM 和 JavaScript 两头跑了一万次,可想而知,最终页面呈现要花费多少工夫!
-
这里得出,消耗工夫的点在 DOM 的操作上,所以要在这方面进行优化。
优化计划
该怎么优化呢?
- DOM 树节点操作耗时,那就将其放出 for 循环,使其只进行一次。
// 查找元素,能够先提出来, 这样就不必每次循环都查找一遍
let oContainer=document.getElementById('container');
for (var count = 0; count < 10000; count++) {oContainer.innerHTML += '<span> 我是一个小测试 </span>';}
- span 元素的写入 DOM 树也耗时间,在 for 循环里要执行一万次,那就将写入 DOM 树缩小为一次
// 查找元素,能够先提出来, 这样就不必每次循环都查找一遍
let oContainer=document.getElementById('container');
let content='';
for (var count = 0; count < 10000; count++) {content += '<span> 我是一个小测试 </span>';}
// 写入也放进去
oContainer.innerHTML +=content;
// 这样就秒出了,耗时间的 DOM 操作,从一万次变到 1 次
这时候,通过优化,输入一万个 <span> 我是一个小测试 </span>
的页面就能疾速的显示了。
扩大例子
间接看代码:
<div id="container"></div>
<script>
// 怎么优化? 这里来回跑了 4 次
let container=document.getElementById('container');
container.style.width='100px';
container.style.height='200px';
container.style.border='10px solid red';
container.style.color='red';
</script>
这该怎么进行优化呢?
将四次操作变为一次
知识点提醒:cssText 属性批量操作款式,classList 是一种更不便的拜访元素的类列表的办法。
- 解决方案一:
// 计划一
let container=document.getElementById('container');
container.style.cssText = "width:100px; height: 200px;border:10px solid red;color:red";
- 解决方案二:
// 计划二
<style>
.reveal{
width:100px;
height: 200px;
border:10px solid red;
color:red;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
let container=document.getElementById('container');
// 应用.reveal(把这一些个款式先放到渲染树上,而后间接启用), 只须要在 js 和 DOM 树之间跑一遍就行了
container.classList.add('reveal');//reveal 只是个名字
// 应用 classList.add
</script>
# 最初总结
这里只是浅谈了前端性能的问题,具体的方面还有很多,须要多去理解学习,浏览相干的书籍,例如高性能 JavaScript,在进行开发时多留神本人的编码方式,特地是前端新人们,编码的同时留神性能。这是十分重要的。
感激浏览,如有倡议或有余的中央请在上面评论提出。