lasy load图片的实现
无意中看到了这篇关于使用LQIP(Low Quality Image Placeholders) 原文链接,方案实现图片加载优化方案。在此实践一把。
1. 方案实现
- 页面初始化时,img元素初始化时,src使用低质量的图片,显示出图片的大概轮廓
- 页面滚动到当前图片位置,后台启动加载原图
- 原图加载完成,替换掉之前的src显示出原图
监听页面是否滚动到图片位置使用的IntersectionObserver,减少使用scroll过程造成的页面卡顿。
2. 代码结构
index.tmpl
<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>lasyload and LQIP</title>
<meta name="viewport" id="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<link rel="shortcut icon" href="/favicon.ico">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no">
</head> <body>
<p>You may need to install go and Primitive</p>
<p>
This is long article.
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<img src="./images/1.jpg" class="big-pic" alt="">
<br/><br/><br/>
next line
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<img src="./images/2.jpg" class="big-pic" alt="">
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
3th picture
<br/>
<br/>
<img src="./images/3.jpg" class="big-pic" alt=""> </p>
<script type='text/javascript' src='./bundle.js'></script>
</body> </html>
lib/index.js
function replaceSrc (changes) {
changes.forEach(change => {
if (change.intersectionRatio <= 0) return
let item = change.target
let src = item.getAttribute('data-src')
let img = new Image()
img.onload = function () {
item.setAttribute('src', src)
}
img.src = src
// observer.unobserve(item)
})
}
module.exports = function (selector) {
let els = document.querySelectorAll(selector)
let observer = new IntersectionObserver(replaceSrc.bind());
[].forEach.call(els, (item) => {
observer.observe(item)
})
}
index.js
let dealPic = require('../lib/index')
dealPic('.big-pic')
各文件关系是:
- index.tmpl是HTML模板,编译之后生成index.html
- lib/index.js 用于监听元素是否达到了页面位置
- index.js用于生成bundle.js
3. 构建的实现
首先需要安装go和primitive. primitive库: https://github.com/fogleman/primitive
安装primitive时有些网站被墙了,所以要下载安装包安装。网上搜索到了一个第三方下载地址:https://www.golangtc.com/download/package
按提示下载解压至go目录下的src,然后执行
go install github.com/fogleman/primitive
安装完成环境。
安装npm库依赖包:
npm i glob sqip browserify
使用glob检索所有的图片,sqip用于转换图片为最小格式的svg,browserify为了使用require模块。
使用正则检测出html模板中所有的img, 匹配已经转为svg的文件,文件相同,使用base64格式替换掉原src,新加data-src为原src, 设置width height等。最后输出文件为index.html
构建的代码如下:
const sqip = require('sqip')
const glob = require('glob')
const path = require('path')
const fs = require('fs')
function getSvgList (folder) {
return new Promise((resolve, reject) => {
glob(folder + '/**/*.jpg', {}, function (err, files) {
if (err) {
reject(err)
}
let list = []
files.forEach(file => {
const result = sqip({
filename: file,
numberOfPrimitives: 10,
})
list.push({
file: path.join(__dirname, file),
result,
})
})
resolve(list)
})
})
}
function replaceHtml (html, list) {
if (!path.isAbsolute(html)) {
html = path.join(__dirname, html)
}
let str = fs.readFileSync(html, 'utf-8')
let htmlPath = path.dirname(html)
const REG = /(<img .*?src=\")(.*?)\"( .*?>)/g
let imgSrc = REG.exec(str)
while (imgSrc) {
let src = imgSrc[2]
let file
if (path.isAbsolute(src)) {
file = path.join(__dirname, src)
} else {
file = path.join(htmlPath, src)
}
list.forEach(item => {
if (item.file === file) {
var imgInfo = item.result.img_dimensions
str = str.replace(imgSrc[0], function (str) {
return imgSrc[1] + 'data:image/svg+xml;base64,' + item.result.svg_base64encoded + `" data-width="${imgInfo.width}" data-height="${imgInfo.height}"`
+ ` data-src="${src}"` + imgSrc[3]
})
}
})
imgSrc = REG.exec(str)
}
fs.writeFileSync('./example/index.html', str)
}
getSvgList('./example/images/')
.then(list => {
replaceHtml('./example/index.tmpl', list)
})
4. 执行构建并检测结果
在npm中加入scripts:
{
"build": "npm run sqip & browserify example/index.js -o example/bundle.js",
"sqip": "node sqip.js"
}
执行build后,example文件目录下会生成index.html。开启web服务器(我是使用的自己写的xmocker),访问example/index.html,使用throttle进行查看效果。
5. 总结
方案只是针对普通Html,对于其他模块,应该有现成的方案。访问体验确实好了很多。
附:代码地址 https://github.com/wenlonghuo/code-test/tree/master/001_lasyload
lasy load图片的实现的更多相关文章
- Lazy Load 图片延迟加载(转)
jQuery Lazy Load 图片延迟加载来源 基于 jQuery 的图片延迟加载插件,在用户滚动页面到图片之后才进行加载. 对于有较多的图片的网页,使用图片延迟加载,能有效的提高页面加载速度. ...
- jQuery Lazy Load 图片延迟加载
基于 jQuery 的图片延迟加载插件,在用户滚动页面到图片之后才进行加载. 对于有较多的图片的网页,使用图片延迟加载,能有效的提高页面加载速度. 版本: jQuery v1.4.4+ jQuery ...
- jQuery Lazy Load图片懒加载
传送门:官网地址,jQuery Lazy Load v1.7.2下载,Github 使用方法: 1.引用js文件 <script src="jquery.js">< ...
- lazy load 图片延迟加载 跟随滚动条
http://plugins.jquery.com/lazyload/ Jquery.LazyLoad.js插件参数详解: 1,用图片提前占位 placeholder : "img/grey ...
- img前置显示屏装load图片
只需要设置img的background能够 <img src="" alt="" class="detailImg" > cs ...
- imagepool前端图片加载管理器(JavaScript图片连接池)
前言 imagepool是一款管理图片加载的JS工具,通过imagepool可以控制图片并发加载个数. 对于图片加载,最原始的方式就是直接写个img标签,比如:<img src="图片 ...
- Android 三大图片加载框架的对比——ImageLoader,Picasso,Glide
一.ImageLaoder介绍 << Universal ImageLoader 是很早开源的图片缓存,在早期被很多应用使用 多线程下载图片,图片可以来源于网络,文件系统,项目文件夹ass ...
- MVC显示Base64图片
本篇演示ASP.NET MVC应用程序,显示Base64图片. Insus.NET浏览网页,发现一个站点http://www.base64-image.de/ 想起以前也有实现过<如何把数据流转 ...
- CImage 获取图片RGB 、图片高和宽;
1 CImage img , img1 ,imDest; 2 img1.Load( 图片路径); 3 img.Load( 图片路径); 4 为了防止图片失真,先处理一下在把图片显示出来 5 SetSt ...
随机推荐
- eclipse出现错误:he type java.util.Map$Entry cannot be resolved. It is indirectly referenced
eclipse出现错误:he type java.util.Map$Entry cannot be resolved. It is indirectly referenced jre 换成6的就好了选 ...
- CSS基础--常用样式
一.背景相关 背景颜色 background-color :颜色名称/rgb值/十六进制值 背景图片 background-image :url('') 背景图片平铺方式 background-rep ...
- Spring MVC中使用POI导出Word
内容绝大部分来源于网络 准备工作 准备[XwpfTUtil]工具类(来源于网络) 准备word模版 下载[XwpfTUtil]工具类 import org.apache.poi.xwpf.usermo ...
- Request.getparameternames 获取form表单里面所有的请求参数 。 返回一个Enumeration类型的枚举.
通过Enumeration的hasMoreElements()方法遍历.再由nextElement()方法获得枚举的值.此时的值是form表单中所有控件的name属性的值. 最后通过request.g ...
- CentOS之7与6的区别
前言 centos7与6之间最大的差别就是初始化技术的不同,7采用的初始化技术是Systemd,并行的运行方式,除了这一点之外,服务启动.开机启动文件.网络命令方面等等,都说6有所不同.让我们先来了解 ...
- Lambda表达式详解 (转)
前言 1.天真热,程序员活着不易,星期天,也要顶着火辣辣的太阳,总结这些东西. 2.夸夸lambda吧:简化了匿名委托的使用,让你让代码更加简洁,优雅.据说它是微软自C#1.0后新增的最重要的功能之一 ...
- 用记事本编写java中的HelloWorld
一.安装并配置jdk(图片来自百度经验) 安装JDK 选择安装目录 安装过程中会出现两次 安装提示 .第一次是安装 jdk ,第二次是安装 jre .建议两个都安装在同一个java文件夹中的不同文件夹 ...
- H3c交换机配置端口镜像详情
端口镜像 需要将G0/0/1口的全部流量镜像到G0/0/2口,即G0/0/1为源端口,G0/0/2为目的端口. 配置步骤 1.进入配置模式:system-view: 2.创建本地镜像组:mirrori ...
- Linux面试题(2)
一.Linux操作系统知识 1.常见的Linux发行版本都有什么?你最擅长哪一个?它的官网网站是什么?说明你擅长哪一块? Centos,Ubunto,fedora,openSUSE,Debian等,擅 ...
- React-Native 之 Modal介绍与使用
前言 遗漏的常用组件,刚发现官方有提供,这边也来介绍一下. 如本文有错或理解偏差欢迎联系我,会尽快改正更新! 如有什么问题,也可直接通过邮箱 277511806@qq.com 联系我. 本章涉及资源下 ...