【web前端性能优化】文件加载与执行过程中的优化点、图片的懒加载和预加载、重绘与回流、浏览器存储

学习笔记:

一、加载和执行过程中的优化点

理解浏览器端HTML、CSS、JS的加载过程,学习掌握CSS、JS加载过程中的优化点。

在这里插入图片描述
HTML渲染过程中的一些特点。

  • 顺序执行,并发加载
  • 是否阻塞
  • 依赖关系
  • 引入方式

顺序执行,并发加载
HTML加载是根据词法分析顺序执行的,遇到引入文件并发加载,但不同浏览器会有不同的并发上限。

是否阻塞

CSS阻塞:

  • CSS阻塞页面的渲染
  • CSS阻塞JS的执行,但不阻塞JS的加载

JS阻塞:

  • JS阻塞页面的渲染
  • JS不阻塞资源的加载(预加载)
  • JS顺序执行,阻塞后续JS逻辑的执行(单线程保证依赖关系)

依赖关系

  • 页面渲染依赖于CSS的加载
  • JS执行顺序的依赖关系
  • JS逻辑对于DOM节点的依赖关系

引入方式

  • 直接引入
  • defer
  • async
  • 异步动态引入JS

加载和执行过程中的一些优化点

  1. CSS样式表置顶
  2. 用link代替import
  3. JS脚本置底
  4. 合理使用JS的异步加载能力

二、图片的懒加载

在做web前端开发的时候,特别是一些大型的电商网站,需要加载很多图片,但浏览器并行加载资源的能力是有限的,这就需要我们在不影响用户体验的前提下解决这个问题,从而提升用户体验。图片的懒加载可以解决这个问题。

懒加载:只有进入可视区域的资源才会被加载。

图片的懒加载带来的好处

  • 减少无效资源的加载(按需加载)
  • 并发加载的资源过多会阻塞JS的加载,影响网站的正常使用(若图片和静态资源在一个CDN,浏览器并发度的限制会降低用户体验)

懒加载的实现原理

当图片没有进入可视区域,img的src并不是这个图片真正的src,它只是一个占位符,它真正的url被存放在img标签的data-url(自定义)属性上,因为真正的url并没有放在src,所以不会去向服务器请求响应的资源,监听scroll事件,当图片进入到可视区域,将img的src赋值为data-url,这时src的变化会触发图片的请求。(getBoundingClientRect用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性)

三、图片的预加载

什么是预加载以及预加载的优点

  • 预加载指的是图片等静态资源在使用之前的提前请求。
  • 当资源使用到时能直接从缓存中加载,提升用户体验。
  • 页面展示的依赖关系维护
  • 适用于对图片实时性要求比较高的场景

预加载原理
为了提升用户体验,在预加载资源加载完返回complete事件之后才会进行最终渲染。

预加载的实现方式

方式一
使用img标签加载,设置display:none,缓存图片

<img src="http://pic26.nipic.com/1.jpg" class="image-item" style="display: none" /> 

方式二
使用JS对象Image, 会提前缓存图片,直接从缓存中读取

var image = new Image();
image.src = 'http://pic26.nipic.com/1.jpg';

方式三
使用XMLHttpRequest来实现。利用XMLHttpRequest对象异步请求图片资源(和AJAX一样),可能会存在跨域问题,优点是可以控制预加载的过程(有封装的接口和方法)。

var xhr;
if(XMLHttpRequest){
    xhr=new XMLHttpRequest();
}else{
    xhr=new ActiveXObject();
}
xhr.open("POST","http://pic26.nipic.com/1.jpg",false);   
xhr.send();
xhr.onreadystatechange=function(res){
    //这里的函数异步执行
    if(xhr.readyState == 4 && xhr.status == 200){
        console.log(res);
    }else{
    	console.log("Request was fail: " + xhr.status);
    }
};

方式四
推荐使用第三方库preload.js来处理前端预加载资源的业务,提供的api也简单易用。

// 使用preload.js库
// false决定着使用html标签的方式去加载图片,不使用的话就走XMLHttpRequest方式去加载图片
var queue = new createjs.LoadQueue(false);

queue.on("complete", handleComplete, this);

queue.loadManifest([
    { id: "myImage", src: 'http://pic26.nipic.com/20121213/6168183_004444903000_2.jpg' },
    { id: "myImage2", src: 'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=1069058874,714751845&fm=27&gp=0.jpg' }
])

function handleComplete() {
    var image = queue.getResult("myImage");
    document.body.appendChild(image);
}
--------------------- 
作者:写代码的我 
来源:CSDN 
原文:https://blog.csdn.net/ASD850861363/article/details/78698356 

四、重绘与回流

负责javaScript解析的线程和负责UI渲染的线程是互斥的,频繁触发重绘与回流会导致UI频繁渲染,最终导致JS变慢。所以CSS不仅影响渲染,而且还阻塞JavaScript脚本的执行。

什么是回流

当render tree中的一部分(或全部)因为元素的大小尺寸、布局、隐藏等改变而需要重新构建render tree。这就称为回流。
当页面布局和几何属性改变时就需要回流(CSS改变时触发回流)。所以应该尽量减少触发回流的CSS的改变。

什么是重绘
当render tree中的一些元素要更新属性,而这些属性只是影响元素的外观、风格,而不会影响布局的。比如background的改变就需要重绘。

回流必将引起重绘,而重绘不一定会引起回流。

重绘、回流对应着一些CSS属性,哪些触发重绘,哪些触发回流。

触发页面的重布局,进而触发回流的属性

  • 盒子模型相关属性会触发重布局
  • 定位、浮动也会触发重布局
  • 改变节点的内部文字结构也会触发重布局

触发回流的CSS属性有:
在这里插入图片描述
只触发重绘的属性
在这里插入图片描述

避免重绘回流的两种方法

  1. 避免使用引起重绘回流的CSS属性。(比如用translate代替top的改变,用opacity代替visibility的改变)。
  2. 将重绘、回流的影响范围限制在单独的图层内

独立图层
将频繁重绘回流的元素单独作为一个独立的图层,那么这个DOM元素的重绘回流的影响只会在这个图层中。

好处:减小了重绘回流的波及面。
坏处:大量图层重组会有很大的计算量,耗费性能。

那么,如何将DOM元素变成新的独立图层呢?

chrome创建图层的条件

  • 3D或透视变换CSS属性(perspective transform)
  • 使用加速视频解码的标签
  • 拥有3D上下文或加速的2D上下文的<canvas节点>
  • 混合插件 如flash
  • 对自己的opacity做CSS动画
  • 拥有加速CSS过滤器的元素(translate-3D、translatez)
  • 元素拥有一个包含复合层的后代节点(一个元素拥有一个子元素,该子元素在自己层里)
  • 元素拥有一个z-index较低且包含一个复合层的兄弟元素(该元素在复合层上渲染)

重绘回流的优化点总结

  1. 用translate代替top的改变(减少回流)
  2. 用opacity代替visibility(减少重绘)
  3. 不要一条条的修改DOM样式,预先定义好class,然后修改DOM的className
  4. 把DOM离线后修改。比如,先将DOM display:none; (有一次reflow),然后再修改无数多次,将它显示出来。
  5. 不要把DOM节点的属性值放在循环里,当成循环变量。
  6. 不要使用table布局
  7. 动画实现速度的选择,(频繁的回流重绘,会大量消耗CPU的资源)
  8. 对于动画新建图层(video标签、 canvas标签、也可以通过设置:will-change:transform;)
  9. 启用GPU硬件加速

五、浏览器存储
多种浏览器存储方式并存,如何选择?

cookie

  • 因为HTTP请求无状态,所以需要cookie去维持客户端状态
  • 过期时间expire
  • cookie的生成方式:
    1.http response header中的set-cookie
    2.JS可以通过document.cookie来读写cookie
  • 仅仅作为浏览器存储(大小为4KB左右,存储能力被localStorage替代)
  • httponly。如果在cookie中设置了httponly属性,那么通过JS脚本将无法读到cookie信息,这样能有效防止XSS攻击。
  • cookie中在相关域名下面的网络损耗。(解决办法:CDN域名和主站域名要分开)

localStorage

  • HTML5专为浏览器存储设计,大小为5M左右
  • 仅在客户端使用,不和服务端进行通信。
  • 接口封装较好。
  • 浏览器本地缓存方案。(为提升首屏渲染的用户体验) ——优化点
  • API:setItem、getItem、removeItem、clear

sessionStorage

  • 会话级别的浏览器存储,大小为5M左右。
  • 仅在客户端使用,不和服务端进行通信。
  • 接口封装较好。
  • 对于表单信息的维护。(提升用户体验) ——优化点
  • API:setItem、getItem、removeItem、clear

IndexedDB

  • IndexedDB 是一种低级API,用于客户端存储大量结构化数据。该API使用索引来实现对该数据的高性能搜索。虽然 Web Storage 对于存储较少量的数据很有用,但对于存储更大量的结构化数据来说,这种方法不太有用。IndexedDB提供了一个解决方案。
  • 为应用创建离线版本
  • API:get put add delete

PWA

PWA (Progressive Web Apps) 是一种 Web App 新模型,并不是具体指某一种前沿的技术或者某一个单一的知识点,我们从英文缩写来看就能看出来,这是一个渐进式的 Web App,是通过一系列新的 Web 特性,配合优秀的 UI 交互设计,逐步的增强 Web App 的用户体验。

  • 可靠:在没有网络的环境中也能提供基本的页面访问,而不会出现“未连接到互联网”的页面。
  • 快速:针对网页渲染及网络数据访问有较好优化。
  • 融入(Engaging):应用可以被增加到手机桌面,并且和普通应用一样有全屏、推送等特性。

service worker

service worker的生命周期
在这里插入图片描述

Service Worker 是一个脚本,浏览器独立于当前网页,将其在后台运行,为实现一些不依赖页面或者用户交互的特性打开了一扇大门。在未来这些特性将包括推送消息,背景后台同步, geofencing(地理围栏定位),但它将推出的第一个首要特性,就是拦截和处理网络请求的能力,包括以编程方式来管理被缓存的响应。

service worker的优化

  1. 使用拦截和处理网络请求的能力,去实现一个离线应用。
  2. 使用service worker在后台运行同时能和页面通信的能力,去实现大规模的后台数据处理。
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值