美文网首页
性能优化(一)

性能优化(一)

作者: zwj2024 | 来源:发表于2017-06-14 10:57 被阅读104次

1.为什么JS可以放在页面的任意位置,推荐放在底部,主要原因有:

<blockquote>
1.因为浏览器渲染HTML是从上往下渲染的。
2.JS下载完成,解析运行完成才能继续加载其它内容,所以JS放在页面开始,如果网速慢或JS复杂,会造成长时间页面空白,用户体验不好。
3.JS一般会对DOM树进行操作,放在页首,DOM元素还没有加载完,一般还是要在onload等事件中运行JS,放在页尾,DOM树已经完成,可以直接运行。
</blockquote>

2.滚动加载图片(懒加载)实现原理

<blockquote>
【1】图片都用同一张图片
【2】给图片增加data-original = "img/test.jpg"的属性,保存图片的真实地址
【3】当触发某些条件时,自动改变该区域的图片的src属性为真实的地址
</blockquote>

需要参考JS中关于clientWidth offsetWidth scrollWidth style.width等的含义

**Image对象,实现图片的预下载 **
<pre>
function loadImage(url, callback) {
var img =new Image(); //创建一个Image对象,实现图片的预下载
if (img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
callback(img);
return; // 直接返回,不用再处理onload事件
}
img.onload =function () { //图片下载完毕时异步调用callback函数。
callback(img);
};
img.src = url;
}
</pre>
<blockquote>
1.obj[i].getBoundingClientRect().top < document.documentElement.clinetElement && !obj[i].isload
2.obj[i].style.cssText = "transition:1;opacity:1"
</blockquote>

<pre>
var aImages = document.images;
loadImg(aImages);
window.onscroll=function(){
loadImg(aImages);
}
function loadImg(arr){
for(var i = 0,len = arr.length;i < len;i++){
if(arr[i].getBoundingClientRect().top < document.documentElement.clientHeight && !arr[i].isLoad){
arr[i].isload = true;
arr[i].style.cssText = "transition:'';opacity:0;";
if(arr[i].dataset){
afterLoadImg(arr[i],arr[i].dataset.original);
}else{
afterLoadImg(arr[i],arr[i].getAttribute("data-original"));
}
(function(i){
setTimeout(function(){
arr[i].style.cssText = "transition:1s;opacity:1";
},16)
})(i)
}
}
}
function afterLoadImg(obj,url){
var oImg = new Image();
oImg.onload = function(){
obj.src = oImg.src;
}
oImg.src = url;
}
</pre>

3.页面的渲染过程

网页的生成过程,大致可以分成五步。
<blockquote>
HTML代码转化成DOM
CSS代码转化成CSSOM(CSS Object Model)
结合DOM和CSSOM,生成一棵渲染树
生成布局(layout)
将布局绘制(paint)在屏幕上
这五步里面,第一步到第三步都非常快,耗时的是第四步和第五步。
</blockquote>
"生成布局"(flow)和"绘制"(paint)这两步,合称为"渲染"(render)。

image.png
<blockquote>
修改DOM,修改样式表,用户事件都会导致网页重新渲染。
</blockquote>
重排和重绘对于性能的影响
<blockquote>
浏览器会尽量把所有(DOM,样式,事件变动)的变动集中在一起,排成一个队列,然后一次性执行,尽量避免多次重新渲染。

div.style.color = 'blue';
div.style.marginTop = '30px';
上面代码中,div元素有两个样式变动,但是浏览器只会触发一次重排和重绘。

如果写得不好,就会触发两次重排和重绘。
div.style.color = 'blue';
var margin = parseInt(div.style.marginTop);
div.style.marginTop = (margin + 10) + 'px';

一般来说,样式的写操作之后,如果有下面这些属性的读操作,都会引发浏览器立即重新渲染。
所以,从性能角度考虑,尽量不要把读操作和写操作,放在一个语句里面。

// bad
div.style.left = div.offsetLeft + 10 + "px";
div.style.top = div.offsetTop + 10 + "px";

// good
var left = div.offsetLeft;
var top = div.offsetTop;
div.style.left = left + 10 + "px";
div.style.top = top + 10 + "px";
</blockquote>
<blockquote>
重排和重绘一般的规则是:

样式表越简单,重排和重绘就越快。
重排和重绘的DOM元素层级越高,成本就越高。
table元素的重排和重绘成本,要高于div元素
</blockquote>

九个技巧可以降低浏览器重新渲染的频率和成本&&DOM优化
<blockquote>
第一条DOM 的多个读操作(或多个写操作),应该放在一起。不要两个读操作之间,加入一个写操作。
第二条,读取某个样式是通过重排得到的,那么最好缓存结果。避免下一次用到的时候,浏览器又要重排。
第三条,不要一条条地改变样式,而要通过改变class,或者csstext属性,一次性地改变样式。
</blockquote>
<pre>
// bad
var left = 10;
var top = 10;
el.style.left = left + "px";
el.style.top = top + "px";
// good
el.className += " theclassname";
el.style.cssText += "; left: " + left + "px; top: " + top + "px;";
</pre>
<blockquote>
第四条,尽量使用离线DOM,而不是真实的网面DOM,来改变元素样式。比如,使用 cloneNode() 方法,在克隆的节点上进行操作,然后再用克隆的节点替换原始节点。
第五条,先将元素设为 display: none (需要1次重排和重绘),然后对这个节点进行100次操作,最后再恢复显示(需要1次重排和重绘)。这样一来,你就用两次重新渲染,取代了可能高达100次的重新渲染。
第六条,position属性为absolute或fixed的元素,重排的开销会比较小,因为不用考虑它对其他元素的影响。
第七条,只在必要的时候,才将元素的display属性为可见,因为不可见的元素不影响重排和重绘。另外,visibility : hidden 的元素只对重排有影响,不影响重绘。
第八条,使用虚拟DOM的脚本库,比如React等。
第九条,使用 window.requestAnimationFrame()、window.requestIdleCallback() 这两个方法调节重新渲染。
</blockquote>

参考

网页性能管理详解阮一峰
浏览器加载、解析、渲染的过程

相关文章

  • iOS性能优化 - 整理

    本文主要包含: 性能优化 - 卡顿性能优化 - 耗电优化性能优化 - APP启动优化安装包瘦身 一  性能优化 -...

  • iOS 性能优化

    ios性能优化(一)ios性能优化(二)ios性能优化(三)

  • Android性能优化 - 消除卡顿

    性能优化系列阅读 Android性能优化 性能优化 - 消除卡顿 性能优化 - 内存优化 性能分析工具 - Tra...

  • Android性能优化 - 内存优化

    性能优化系列阅读 Android性能优化 性能优化 - 消除卡顿 性能优化- 内存优化 性能分析工具 - Trac...

  • 前端性能优化(中)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(上)...

  • 前端性能优化(下)

    性能优化调研系列文章 《前端性能优化(上)》 《前端性能优化(中)》 《前端性能优化(下)》 《前端性能优化(中)...

  • Awesome Extra

    性能优化 性能优化模式 常见性能优化策略的总结 Spark 性能优化指南——基础篇 Spark 性能优化指南——高...

  • 常用的后端性能优化六种方式:缓存化+服务化+异步化等

    性能优化专题 前端性能优化 数据库性能优化 jvm和多线程优化 架构层面优化 缓存性能优化 常用的后端性能优化六大...

  • webpack 性能优化

    webpack性能优化 开发环境性能优化 生产环境性能优化 开发环境性能优化 优化打包构建速度 优化调试功能 生产...

  • 【React.js 20】React性能优化

    React性能优化 React性能优化主要分三块: React 组件性能优化 属性传递优化针对单组件性能优化,很多...

网友评论

      本文标题:性能优化(一)

      本文链接:https://www.haomeiwen.com/subject/lzjsqxtx.html