单页Web应用(single page web application,SPA)会一次性载入页面资源,利用本地计算能力渲染页面,提高页面切换速度与用户体验。由此带来了首屏加载缓慢耗时的诟病,这也是困扰前端开发工程师的一重大难题。

最近查阅了一些帖子,发现了一个极其强大的方法,其兼容性有待提高~~(但已有相关的的Polyfill方式)

按需加载

// 全部加载
import 'ccharts'// 按需加载 只加载需要使用的组件
import 'echarts/lib/component/title'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/legend'
import 'echarts/lib/chart/bar'

可以减小组件加载的大小,节省网络带宽,从而提高响应速度!

异步加载组件

首先我们可以将应用拆成多个模块组件,然后异步加载组件。配合webpack代码分割使用,达到按需加载的效果(下述只简单陈述,不做详细讲解)。

补充,webpack有三种常用的代码分割方式:

  • 入口起点:使用 entry 配置手动地分离代码。
  • 防止重复:使用 CommonsChunkPlugin 去重和分离 chunk。
  • 动态导入:通过模块的内联函数调用来分离代码。
// 同步方式
import search from '@/views/search/search.vue'
// 异步方式
const search = (resolve) => require(['@/views/search.vue'], resolve)
// ES6异步方式(推荐)
const search = () => import('@/views/search.vue')

注意,webpack中需要配置相关信息

output: {path: '/dist',filename: 'js/[name].[chunkhash].js', chunkFilename:'js/[id].[chunkhash].js'
},

注意,filename决定了bundle的名称。但是此选项不会影响那些「按需加载 chunk」的输出文件。对于这些文件,请使用 output.chunkFilename选项来控制输出。通过 loader 创建的文件也不受影响。在这种情况下,你必须尝试 loader 特定的可用选项。

懒加载

通过监听滚动条来判断是否在可视区域进行加载处理,document.documentElement.clientHeight > dom.getBoundingClientRect().top

<div class="content"><span>1</span></div>
<div class="content"><span>2</span></div>
<div class="content"><span>3</span></div>
<div class="content"><span>4</span></div>
<div class="content"><span>5</span></div>
const imageAddress = '../images/'
const viewHeight = document.documentElement.clientHeight // 可视区域的高度function $(selector) {return Array.from(document.querySelectorAll(selector))
}function lazyload () {// 获取所有要进行懒加载的图片$('.content').forEach(item => {let rect, imgSrclet index = item.querySelector('span').innerHTML// 资源已加载,避免重复加载if (item.dataset.src !== '') returnrect = item.getBoundingClientRect()// 图片一进入可视区,动态加载if (rect.bottom >= 0 && rect.top < viewHeight) {imgSrc = `${imageAddress}${index}.jpg`item.dataset.src = imgSrclet img = document.createElement('img')img.src = imgSrcitem.appendChild(img)}})
}
lazyload()
document.addEventListener('scroll', lazyload)

注意:要对已加载的资源进行标识,防止重复加载!

该方式通过监听到scroll事件后,调用目标元素(绿色方块)的getBoundingClientRect()方法,得到它对应于视口信息,再判断是否在视口之内。这种方法的缺点是,由于scroll事件密集发生(当然可以使用节流函数进行相应处理),计算量很大,容易造成性能问题!

IntersectionObserver

IntersectionObserver接口为开发者提供了一种可以异步监听目标元素与其祖先或视窗(viewport)交叉状态的手段。该API 是异步的(降低了昂贵的DOM和样式查询开销、以及CPU、GPU能源成本),不随着目标元素的滚动同步触发,对于理解元素的可见性以及实现DOM内容的预加载和延迟加载非常有用。

IntersectionObserver((entries, observer) =>{}, options)
// 观察指定目标元素
observer.observe(target);
// 停止观察指定目标元素
observer.unobserve(target);
// 停止观察全部元素
observer.disconnect();

entries为IntersectionObserverEntry对象,包含如下属性:

  • time:可见性发生变化的时间,毫秒;
  • target:被观察的目标元素,DOM节点对象;
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
  • boundingClientRect:目标元素的矩形区域的信息;
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息;
  • intersecttionRatio:目标元素的可见比例;

options为IntersectionObserverInit 对象,包含如下属性:

  • root:指定目标元素所在的容器节点(即根元素);
  • rootMargin:用来扩展或缩小rootBounds这个矩形的大小,从而影响intersectionRect交叉区域的大小;
  • threshold:决定了什么时候触发回调函数
var io = new IntersectionObserver((entries) => {entries.forEach(entry => {let {target, intersectionRatio} = entryconsole.log(target.tagName, intersectionRatio)})
}, {threshold: [0, 0.25, 0.5, 0.75, 1]
})
// 监听
io.observe($('.target'))

class名称为‘target’的元素,在可见比例为[0, 0.25, 0.5, 0.75, 1]均会执行相关回调函数!

实现懒加载:

var io = new IntersectionObserver((entries) => {entries.forEach(entry => {let {target, intersectionRatio} = entry// 目标元素的可见比例大于0if (intersectionRatio) {let index = target.querySelector('span').innerHTMLlet img = document.createElement('img')img.src = `${imageAddress}${index}.jpg`target.appendChild(img)// 取消监听,防止重复加载io.unobserve(target)}})
}, {threshold: [0]
})
// 监听
$('.content').forEach(element => {io.observe(element)
})

实例地址:https://github.com/381510688/practice/blob/master/javascript_test/lazyLoad.html

兼容性


Github上提供了相关的Polyfill方式:IntersectionObserver polyfill

参考地址:

  • https://www.w3.org/TR/intersection-observer/
  • http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html
  • https://github.com/xunleif2e/vue-lazy-component

单页应用优化--懒加载相关推荐

  1. 单页应用的优缺点,单页应用首屏加载优化、小程序首次启动速度优化

    单页应用的优缺点 单页应用,简称(Single Page Application)是指整个应用只一个HTML页面,所有的功能和交互都在这个页面完成,利用JavaScript动态改变HTML内容. 优点 ...

  2. Vue3电商项目实战-首页模块7【26-首页主体-商品区块、27-首页主体-最新专题、28-首页主体-图片懒加载】

    文章目录 26-首页主体-商品区块 27-首页主体-最新专题 28-首页主体-图片懒加载 26-首页主体-商品区块 目的: 完成商品区域展示. 大致步骤: 准备一个商品盒子组件 home-goods ...

  3. react性能优化-懒加载原理

    编译阶段的优化 开发阶段构建更快 loader的include和exclude属性 {test: /.(j|t)sx?$/,use: [{loader: "thread-loader&quo ...

  4. 浅谈Vue单页应用首屏加载速度优化方案

    心语:最不会利用时间的人,最会抱怨时间不够 趁着五一放假,刚好最近天气也是不好,.所以抽出一点时间写一点东西,也算是不辜负这个美好的假期吧!小编也祝愿大家五一快乐,玩得愉快哈 随着各大前端框架的诞生以 ...

  5. VUE单页应用首屏加载速度优化方案

    单页应用会随着项目越大,导致首屏加载速度很慢!!!以下给出在下知道的几种优化方案 使用CDN资源,减小服务器带宽压力 路由懒加载 将一些静态js css放到其他地方(如OSS),减小服务器压力 按需加 ...

  6. SPA(单页应用)首屏加载慢的优化方案

    一. 什么是首屏加载时间? 首屏加载时间是指浏览器从相应用户输入网址到首屏内容渲染完成的时间. 整个网站并不需要全部加载完成,但需要展示当前可视窗口中的内容,也就是首屏. 从用户的角度来说就是:&qu ...

  7. js实现审批流_小程序瀑布流组件:支持翻页与图片懒加载

    电商小程序中,用到瀑布流的地方非常多,每次都写一个瀑布流,重复一次逻辑,作为程序员,肯定是非常不愿意的. 瀑布流的形式都是大同小异,不同的是瀑布流中每个模块的内容,随业务而变化. 所以,我们把瀑布流框 ...

  8. swiper 定义放多少张图片_小程序瀑布流组件:支持翻页与图片懒加载

    (给前端大全加星标,提升前端技能) 作者:老人羽海 https://segmentfault.com/a/1190000022680541 电商小程序中,用到瀑布流的地方非常多,每次都写一个瀑布流,重 ...

  9. vue单页应用首屏加载速度慢如何解决

    首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间. 一.加载慢的原因 在页面渲染的过程,导致加载速度慢的因素可能如下: 网络延时问 ...

最新文章

  1. 半导体群聚、虚拟垂直、整合
  2. 计算机二级新考纲什么时候出来,有计算机二级考试(VFP)的新考纲吗?
  3. poj Shortest Prefixes ——trie树、字典树,基础!!
  4. C向Python正确传递数组的代码
  5. asponse.word 设置全局段前段后信息_一步步编写操作系统 12 代码段、数据段、栈和cpu寄存器的关系...
  6. 数字信号处理matlab版答案,数字信号处理(MATLAB版)
  7. 苹果系统安装驱动的五种方法
  8. Java 常见面试题
  9. Android gpuimage美颜滤镜,基于GPUImage的实时美颜滤镜
  10. PS软件Photoshop设置使用鼠标进行放大缩小设置
  11. 百度地图 java 纠偏_模板:纠偏服务首页 | 百度地图API SDK
  12. android+recovery+启动流程,Recovery启动流程(一)- 应用层到开机进入recovery详解
  13. JavaFX Scene Builder的使用
  14. bert实践:关系抽取解读
  15. Nodejs 服务端生成验证码
  16. 网页计算器 html代码原理,HTML网页之计算器代码
  17. uva10635Prince and Princess(LIS)
  18. 24段魔尺,可以折出哪些精美图案
  19. 有关海外域名注册的详细问题解答
  20. matlab中selector用法,MATLAB SIMULINK Bus Selector 总线选择

热门文章

  1. 【爬虫实践】用递归获取网站的所有内链和外链
  2. spring手撕源码
  3. macOS下鼠标滚轮慢速滚动不起作用的问题解决
  4. 计算机英语简写对照,计算机术语简写-全称对照表.pdf
  5. 修改jar包两种方法
  6. AC米兰 传统豪门的没落
  7. 视频教程-实战Go语言:多人聊天室-Go语言
  8. 武汉大学2007年数学分析试题解答
  9. vs2015 打包程序(摘抄自博客园-流浪阿丁)
  10. 图片 标记 软件_如何设计软件功能标记