懒加载的好处
当我们一次性大批量的加载资源的时候, 会占用大量的内存, 尤其是在一些低内存的设备上会造成卡顿的现象, 所以我们就需要在必要的时候再进行资源的加载
懒加载就是在真正需要资源才加载资源, 这样就可以节省内存, 尽可能的减少卡顿现象的出现
懒加载原理
懒加载的原理就如上图所示, 当组件进入可视区域加载子组件, 不在可视区域内卸载子组件懒加载的原理就是这么简单, 下面介绍一下懒加载具体的实现方法
1. 计算子组件是否在可视区域之内
- const checkVisible = (component,offset=100,parent) => {
- // 获取实际的 DOM
- const node = ReactDOM.findDOMNode(component)
- // 获取距离顶部的距离
- const {top} = node.getBoundingClientRect()
- const windowHeight = window.innerHeight || document.documentElement.clientHeight
- const {top:parentTop,bottom:parentBottom } = parent.getBoundingClientRect()
- // 可视区域顶部的位置
- const finalTop = Math.max(parentTop,0)
- // 可视区域底部的位置
- const finalBottom = Math.min(parentBottom,windowHeight)
- // 计算是否在可视区域之内
- if(top > finalTop - 100 && top < finalBottom + 100){
- return true
- }
- return false
- }
2. 添加滚动事件
首先我们先利用上面的函数检查检查子组件是否在可视区域内, 如果是则设置 isVisible 为 true, 则显示组件, 否则不显示组件
- checkedVisible(parent) { // 是否只懒加载一次, once 为 true 加载之后不再操作 dom
- const once = this.props.once;
- const offset = this.props.offset
- return throttle(() = >{
- const visibleState = this.state.isVisible
- if (! (once && visibleState)) {
- const isVisible = checkVisible(this, offset, parent) this.setState({
- isVisible
- })
- }
- },
- 200)
- }
- const parent = getScrollParent(node);
- const checkedVisibleFn = this.checkedVisible(parent);
- // 添加滚动事件
- window.addEventListener("scroll", checkedVisibleFn, false)
为 window 对象添加滚动事件, 为防止滚动事件频繁触发 checkedVisible, 我们为检查 checkVisible 函数节流, 减少性能开销此处我们利用的 throttle 函数, 更多关于节流函数和函数去抖的介绍可参考这边博客: JS 魔法堂: 函数节流 (throttle) 与函数去抖(debounce)
3. 获取可滚动的父组件
当前我们只是为考虑了 window 对象可滚动的情况, 如果是 DOM 对象可滚动我们就需要获取可滚动的父对象, 而不只是仅仅 window 对象
- // 获取滚动的父元素
- const getScrollParent = (node) = >{
- if (!node) {
- return document.documentElement
- }
- let parent = node;
- // 正则
- const overflowReg = /(scroll|auto)/
- while (parent) {
- if (!parent.parentNode) {
- return document.documentElement
- }
- const {
- overflow
- } = window.getComputedStyle(parent) if (overflowReg.test(overflow)) {
- return parent
- }
- parent = parent.parentNode
- }
- return document.documentElement
- }
- export
- default getScrollParent
4. 再次添加滚动事件
如果不仅仅是 window 可滚动我们在添加滚动事件之前进行一次判断
- const node = ReactDOM.findDOMNode(this);
- const parent = getScrollParent(node);
- const checkedVisibleFn = this.checkedVisible(parent);
- if (parent === document.documentElement) {
- window.addEventListener("scroll", checkedVisibleFn, false)
- } else {
- parent.addEventListener("scroll", checkedVisibleFn, false)
- }
总结
以上基本就是 react 懒加载基本实现的方法, 具体的代码以及 demo, 可以参考源码: https://github.com/volcanoliuc/react-lazyload-demo
此 demo 仅仅只是简化版的 react 懒加载, 如果是在实际的项目中需要使用推荐使用 react-lazyload
来源: http://www.bubuko.com/infodetail-2499728.html