使用rollup打包图片懒加载插件
前言
众所周知,图片的加载是前端页面加载性能的优化之一。如果一个页面在加载的时候全部加载当前页面的图片,当图片资源比较多且比较大(质量)的时候会严重影响页面的加载。特别是SPA应用,先加载jsbundle资源,再去加载图片资源,这样就会更加影响页面的加载性能。
一般我们优化页面加载的时候通常有一下几种方案:
把CSS文件放在页面顶部,而javascript文件放在底部
去掉不必要的js脚本插件
利用浏览器缓存
使用 CSS Sprites 整合图像
压缩CSS和javascript脚本
启用gzip压缩
优化图像
减少DNS查询
最小化重定向
本文编写的插件主要是从在加载页面的时候减少图片的请求来优化页面加载性能。下面分享一下使用rollup打包的懒加载图片插件。下面手把手教你撸一个图片懒加载插件,开始上车了...
初始化项目
创建img-lazyload目录,执行下边命令
cd img-lazyload
npm init -y
安装配置rollup
rollup教程请查看官方文档
安装插件
npm install -D @babel/core @babel/preset-env
npm install -D rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-uglify
@babel/core
babel的核心插件必不可少
@babel/preset-env
es6转化es5的插件,因为代码使用了es6新特性,需要配置babel
rollup
rollup核心包必不可少
rollup-plugin-babel
如果使用了babel,需要这个插件
rollup-plugin-commonjs
node_modules中的包大部分都是commonjs格式的,要在rollup中使用必须先转为ES6语法,所以需要安装插件 但是本项目代码没有使用其它插件,这个包可以不安装,也可以不用添加commonjs的配置
rollup-plugin-node-resolve
rollup无法识别node_modules中的包,需要插件告诉 Rollup 如何搜寻外部依赖,但是本项目代码没有使用其它插件,这个包可以不安装,也可以不用添加resolve配置
rollup-plugin-uglify
压缩打包js代码
配置rollup打包js代码
建build/rollup.config.js, src/index.js文件
src/index.js这里编写代码,先添加下边代码
console.log("hello world");
build/rollup.config.js配置代码如下
这里只写了简单的配置
import { uglify } from 'rollup-plugin-uglify'
import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs' // commonjs规范的代码转化es6
import babel from 'rollup-plugin-babel'
export default {
input: 'src/index.js', // 打包入口
output: {
file: 'dist/index.min.js', // 输出文件
format: 'umd', // 打包格式,支持浏览器,也支持commonjs
name:"ImgLazyLoad", // 编译浏览器环境的包时需要指定name属性
},
plugins:[
babel({
exclude: ['node_modules/**']
}), // 支持babel
resolve(), // 查找包路径
commonjs(), // 支持commonjs的插件
uglify(), // 压缩代码的插件
],
}
到这里简单的配置已经完成,下边我们检查配置是否成功
添加打包命令在package.json中
"build": "rollup --config build/rollup.config.js"
我们执行npm run build,会看到生成一个dist/index.js文件,下边这个就是我们打包生成的最终代码
QQ截图20200314113944.png
然后编写demo进行测试打包是否成功
新建example/index.html
编写代码如下
这是主要是需要把打包的代码在html中进行加载
打开静态html,调出控制台。console.log("hello world")正常执行。说明rollup的配置可以打包
现在我们初始化项目完成,下边编写图片懒加载代码
图片懒加载源码
删除src/index.js的测试代码,编写如下代码
/*
* 图片懒加载对象
* */
function ImgLazyLoad(className) {
if (!this instanceof ImgLazyLoad) {
console.warn('ImageLazy is a constructor and should be called with the `new` keyword')
return;
}
// 判断类名是否为null
if(!className) return;
// 获取className的Node节点
this.imageList = [...document.querySelectorAll(className)];
if(this.imageList && this.imageList.length >0){
// 初始化的时候需要先去执行一下滚动监听方法,需要首屏图片加载出来
this.pageScroll();
this.initScrollEvent();
}
}
/*
* 初始化监听滚动事件
* */
ImgLazyLoad.prototype.initScrollEvent = function(){
window.addEventListener('scroll',()=>{
this.imageList.length && this.pageScroll();
})
}
/*
* 监听滚动的回调方法
* */
ImgLazyLoad.prototype.pageScroll = function(){
let imgs = this.imageList;
const replacedIndexList = [];
for(let i = 0;i < imgs.length;i++){
// 判断当前图片是否在屏幕当前显示区域(这里做了一个小技巧,当图片的头部离屏幕底部60px开始加载图片的地址,防止图片过大且滑动过快的时候显示空白区域)
if(imgs[i].getBoundingClientRect().top - 60 <= window.innerHeight){
this.replaceImgSrc(imgs[i]);
replacedIndexList.push(i);
}
}
const array = [];
// 把加载过的图片从数组中移除
for(let i = 0;i < imgs.length;i++){
if(replacedIndexList.indexOf(i) <= -1){
array.push(imgs[i])
}
this.imageList = array;
}
}
/*
* 替换属性,正式加载图片
* */
ImgLazyLoad.prototype.replaceImgSrc = function(el){
if(el){
// 将图片替换为真实地址,加载图片
let src = el.getAttribute('original-src');
el.src = src;
}
}
export default ImgLazyLoad;
运行npm run build构建源代码发现编译报错
QQ截图20200314133248.png
经过排查发现时babel没有配置
在项目根目录新建babel.config.js文件,代码如下:
module.exports = {
presets: ['@babel/preset-env']
};
重新执行npm run build构建源代码发现无报错
完善Demo
第一张图片 这是占用文字测试demo 这是占用文字测试demo 这是占用文字测试demo 这是占用文字测试demo 第二张图片 这是占用文字测试demo 这是占用文字测试demo 这是占用文字测试demo 这是占用文字测试demo 这是占用文字测试demo 第三张图片
打开静态src/index.html,调出控制台,查看元素。如下图
QQ截图20200314134823.png
发现加载页面的时候,第二,三张图片没有加载。上拉页面的时候,当图片快要出现在屏幕的时候,图片src被替换成了真实的图片地址,这时候才真正加载图片。
这里到此结束,这个项目还有不足之处。
用在spa项目中,只能在单独组件使用(而且必须在组件的加载完成生命周期方法之后),不能一次创建永久使用
谢谢!
发表评论 (审核通过后显示评论):