5

博客图片加载优化

 2 years ago
source link: https://hellflame.github.io/2020/09/04/image-load-optimize/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

博客图片加载优化

发布 : 2020-09-04 分类 : basics 浏览 : --

所谓“一站式”,大概是所有图片资源都在 github.io 一个站点,国内访问相关地址时一般都会十分缓慢,如果再把超大的图片放上去,不用代理的话,大概只能在不繁忙的凌晨能够加载出图片,平时应该什么图片都加载不出来,因为所有图片几乎都是同时请求资源,但是谁都没有请求完就都超时了

这里所谓的“解决”,其实并不能解决图片加载慢的问题,真正要解决大概只有通过CDN或者其他更快节点的图片节点才能解决。这里只是能够尽最大努力一张图片一张图片的加载

由于整个网站都是通过 hexo 生成完整的静态网站,所以第一步要做的,是在翻译markdown时将 img 标签的 src 属性置为无效,但又要能够在访问时恢复成正确的地址

page.more.replace(/\.webp-/igm, ".webp-")

这里做了两件事情,首先是将原始的 jpg 文件后缀替换为 webp ,使得在支持 webp 的浏览器上使用更小的资源,当然,这个webp图片是在生成静态网站时生成的;然后是在替换后缀时,添加了一个 - ,这样这个图片就一定是 404 了,这样图片的响应时间就会和响应 404 的时间一致的短了。更理想的情况应该是把 src 属性完全移除,添加一个类似 data-src 的属性,这样图片甚至都不会去尝试请求 404 地址,不过这里为了简单方便,就用了这种替代方式

最后,在访问时,需要将无效的地址替换为有效地址,重要的是依次替换,并且在上一张图片加载成功之后,下一张图片再继续加载

这里在原本蹩脚的 js 代码里,又添加了蹩脚的代码

function replaceImg() {
const browser = getBrowser()
const supportWebp = browser === "FireFox" || browser === "Chrome" // 判断是否支持 webp
const images = $(".post img") // 获取所有img标签
for (let i = 0; i < images.length; i ++) {
const target = $(images[i])
if (target.parent().get(0).tagName.toLowerCase() === 'a') {
continue
}
const originSrc = target.attr('src')
if (originSrc.slice(-1)[0] !== '-') {
// 判断如果已经替换过,则跳过
continue
}
const realSrc = originSrc.slice(0, -1)
const wrapper = document.createElement('a')
const jpgSrc = realSrc.slice(0, realSrc.indexOf(".webp")) + ".webp-"
$(wrapper).attr("data-fancybox", "gallery") // 添加fancybox支持
if (supportWebp) {
// 如果支持 webp
target.attr('src', realSrc)
$(wrapper).attr("href", realSrc)
} else {
// 不支持webp
target.attr('src', jpgSrc)
$(wrapper).attr("href", jpgSrc)
}
images[i].onload = function() {
// 在当前这张图片加载完之后,再次执行 replaceImg
replaceImg()
}
target.wrap(wrapper)
break // 成功替换一次之后,立即结束循环
}
}

添加执行时机

$(document).ready(function() {
replaceImg()
})

整个过程采用了类似递归的形式触发下一张图片的加载,好处在于整个页面内的所有图片都会从上到下一张一张的加载,即使网速很慢,现在也会使用全部的带宽资源加载一张图片,如果依然无法加载出来,,,那说明真的不行,这个时候可以设计图片的 onerror 事件,决定是否要尝试下一张或者重试

嗯,,只想做一站式的人大概就只能想出这种节约资源的方式了=。=


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK