intersection observe 的一次使用

原因:公司官网的单一页面有很多图片,图片又有很多的动画效果,受到服务器配置限制,初次访问会卡顿,而官网这种东西恰恰是单次访问类型的。

着手开始优化。

当前存在的问题:

1.图片太多,几乎每张都是png的高清大图。感觉没必要使用质量这么高的。

2.图片的加载,原生写法,监听scroll事件判断图片是否出现在视图区,然后添加动画。

优化:那么针对上面两个点开始处理

第一 图片的处理

关于图片太多如何处理,这里简单说几种方式:没啥好坏之分,自己看着用吧

1.CDN托管(个人认为比较好用),需要考虑到CDN容量

2.图片的在线压缩处理,百度TinyPNG压缩后空间节省50%以上且分辨率不变,肉眼不可分

3.单独一个图片服务器,图片服务与应用服务分离 (杀鸡焉用牛刀?)

4.图片懒加载 通过js将img标签的data-src属性赋值给src属性

5.css Sprites 雪碧图,适用很多icon,缺点是一荣俱荣,一毁俱毁

6.图片压缩base64,节约请求,其实卡顿还是请求太多,处理不过来。

(将图片压缩成base64,随html或者css一起下载到浏览器,不需要额外的请求,这样就节约了请求,我们知道图片在传输过程中是流传输,如果将图片转换成base64,实际上是变大了,并且浏览器在decode  base64编码的图片时需要耗费很多时间的,所以如果我们选择此种方案的话,最好选择一些小图片,不然得不偿失,webpack中可以设置最大多少byte的图片压缩成base64)

第二 图片的触发

1.原生,scroll事件监听(触发频繁,性能消耗太大),利用offsetTop scrollTop offsetHeight等。注意布局,否则会出现offsetTop=0

2.今天的主角 intersection observe 

MDN文档请移步

我在config/intersection.js创建函数:

// 监听dom是否出现在可视区
export function createInteraction(dom, className) {
	const io = new IntersectionObserver(
		entries => {
			// 如果 intersctionRatio 为 0 ,说明目标元素在 view 外部,不需要操作
			if (entries[0].intersectionRatio <= 0) return;
			if (entries[0].intersectionRatio > 0.1) {
				entries[0].target.classList.add(className);
			}
		},
		{
			threshold: [0, 0.25, 0.5, 0.75, 1],
		}
	);
	// 开始监听
	io.observe(dom);
}
// 抽离的公共代码
export function publicAnimations(element) {
	element.forEach(item => {
		createInteraction(document.querySelector(item.dom), item.animate);
	});
}

没啥说的,主要看threshold配置,指的是 步长,元素出现于视图窗口的比例(自己动手改改就知道啥意思了)。

记录坑点:

1.上面封装后,dom是元素节点,classname是动画的class名称,我在第一次使用时,没有配置threshold,其实它是只读的,导致随机某个dom的class名称加不上,没有绑上动画效果。从浏览器控制台来看,是没有获取到dom,所以没有绑定。后来发现,intersection observe 在线程中优先级非常低,只有线程空闲时才会执行。加了 threshold 相当于延时效果,就可以获取到dom。

2.兼容性的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值