惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
爱范儿
爱范儿
P
Proofpoint News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
Latest news
Latest news
The Hacker News
The Hacker News
Cyberwarzone
Cyberwarzone
博客园 - 【当耐特】
Project Zero
Project Zero
小众软件
小众软件
T
Tailwind CSS Blog
量子位
博客园 - 聂微东
I
Intezer
美团技术团队
S
SegmentFault 最新的问题
T
Tor Project blog
Spread Privacy
Spread Privacy
V
Vulnerabilities – Threatpost
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Jina AI
Jina AI
罗磊的独立博客
B
Blog RSS Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Troy Hunt's Blog
有赞技术团队
有赞技术团队
Google DeepMind News
Google DeepMind News
宝玉的分享
宝玉的分享
C
Cisco Blogs
L
LINUX DO - 热门话题
Last Week in AI
Last Week in AI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
AI
AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Azure Blog
Microsoft Azure Blog
L
LINUX DO - 最新话题
Know Your Adversary
Know Your Adversary
GbyAI
GbyAI
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Recent Commits to openclaw:main
Recent Commits to openclaw:main
L
Lohrmann on Cybersecurity
The Register - Security
The Register - Security
L
LangChain Blog
博客园 - 叶小钗
T
Tenable Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

atpX

自建 S3 兼容对象存储服务 Garage 听风的歌 偶尔是深夜就好了 新玩具 AirPods Pro 3 公交车上的时间 从 WHOIS 到 RDAP 通过 WireGuard 访问 NFS 共享文件 自建音乐串流服务探索 我停止了探索 Fediverse 互联网背景噪音 我的数字生活降级 小城与确定性的墙 一只特立独行的猪 Fediverse 与社交 承认的勇气 mediaX - 轻量书影音记录管理工具 我的博客写作流程 网站新增 Misc 页面 擅长对线的鲍勃 在 Chroot 环境下使用 Rsync 同步 再见 JavaScript 当我玩博客时我在玩什么 为什么我的博客没有友链页面 小熊猫与大熊猫 (HDR 照片测试) 是时候为网站开启 HTTP/3 支持了吗 使用 AdGuard Home 搭建自用 DoH 服务 谈谈读书与消遣 2023 年终总结 西安两日游 从 AirPods「升级」到 EarPods Docker 搭建去中心化的微博客平台 Mastodon 聊聊 iPhone 15 Pro 使用感受 能否将 TOTP 二次验证存放在密码管理器里 认识史蒂夫·乔布斯 与“锤哥”克里斯·海姆斯沃斯一起养生 逃离爆炸的信息 你想活出怎样的人生 重温《龙珠》动画 为什么关闭评论 从域名注册商到 DNS 服务,找到自己的组合 如何提高用户网页阅读体验 从 Typecho 迁移到 Hugo 个人博客的最终归宿是静态网站吗 我选择了放弃 jQuery 关于我的小破站折腾速度优化这件事 记一次家庭网络折腾 贴一些 SmokePing 记录 我的域名邮箱选择 不存在的语录 Typecho 评论验证插件 CaptchaPlus 谈谈写字这件事 新的网站 Logo 探索 自建 vaultwarden / bitwarden_rs 密码管理器 使用 Plausible 自建网站流量统计分析工具 如何优雅地徒手剥开火腿肠 简单的集中隔离生活记录 新玩具 M2 MacBook Air 使用 acme.sh 申请 Google 公共证书 Docker 搭建去中心化的微博客平台 Misskey 搭建 Lsky Pro 兰空图床 折腾树莓派系统的一天 我的吉卜力之旅 使用 Uptime Kuma 自建服务器/网站在线率监控 Spartan Host Review - Best Hosting & Service Support Debian 下 Nginx 配合 Fail2Ban 减少恶意扫描和攻击 升级 Typecho 到最新开发版本 v1.2.0 Linux rm 命令详解 Debian 系统安装 Docker 教程 BandwagonHost - Reliable Blog and Business VPS Hosting 使用 Isso 为 Hugo/Hexo 等静态网站添加评论功能 推荐 5 款免费开源的网站流量分析统计工具 搭建 Shynet 网站流量统计分析工具 聊聊 DDoS 攻击那些事 Hugo 使用 Fancybox 实现图片灯箱/放大功能 从 Debian 10 升级到 Debian 11 教程 使用 Umami 自建网站流量统计分析工具 Linux 一次执行多个命令的 3 种方式 Typecho 修改永久链接后旧链接 301 跳转到新链接 从不同需求推荐几家稳定可靠的 VPS 服务商 Build EchoIP service with Docker 浅谈一下这些年折腾过的 VPS 单线复用解决一根网线同时 IPTV 和宽带问题 不完全吃灰的树莓派 开发一个自己的 Telegram Bot 使用 Nginx 实现 TCP 四层反向代理 画画真难 我读村上春树 使用 acme.sh 自动签发和更新证书 卡拉马佐夫式悲剧 安装 File Browser 轻量网盘工具 新玩具树莓派到手 Linux 定时自动备份数据到 OneDrive/Google Drive 记一次服务器崩溃 使用 rsync 同步文件 短信的消失 幻灭的艺术家 新玩具戴尔 S2721DGF 开箱 蝴蝶 用 Docker 整合 SeafilePro 搭建私人云盘 搭建自己的 kms 服务器
曲线解决 Typecho 图片占位抖动问题
ATP · 2022-10-07 · via atpX

由于在 Web 中图片是在 DOM 结构渲染完成以后调用的,如果网速较慢,在 DOM 结构渲染完成时图片尚未加载,此时图片的高度会默认为 0;当图片加载完成后,会重新计算进行重绘,所以会出现抖动现象(图片下面的内容被挤下去)。Google 也针对这种页面布局抖动提出了累积布局偏移(Cumulative Layout Shift)这一指标用来测量真实用户体验中发生偏移的频率。

虽然对内容没什么影响,但对用户体验来说还是比较差的,特别是网络比较差的情况下。

以前用的解决办法

为了解决这个问题,以前一直都在用一个笨办法,直接在图片外加一个 wrapper,利用 CSS 的特性,使用 padding-bottom 来占位。举一个例子:

<div class="img-wrapper">
  <img src="/atpx.com/img.png">
</div>
.img-wrapper {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 56.25%; 
}

img {
  position: absolute;
  top: 0;
  left: 0;
  max-width: 100%;
}

简单来说就是提前给图片一个父元素 <div>,设置 padding-bottom,计算图片的 宽/高*100%,若图片为 16:9,则 padding-bottom 的值为 56.25%. 由于 CSS 是在 DOM 结构渲染时就已经排好版了,所以后续加载的图片只需要在父元素里伸展躺平就行了。

这样写的好处就是简单、兼容性高,缺点也显而易见,如果图片的大小不一样,每张图片都要单独设置。我还真就每张图片这样设置 🙃,因为 Typecho 的 Markdown 中支持引入 HTML 语句,所以过去两年我的每篇文章就像下面这样:

[内容]

!!!
<div class="img-wrapper" style="padding-bottom:23.33%">
!!!
![example](/images/atpx.com.png)
!!!
</div>
!!!

[内容]

这肯定不是一个长久之计,如果我以后要将博客转移到其他平台将会是个大麻烦。

曲线解决办法

这两年断断续续的尝试过几次解决办法:

  • 自定义代码块,PHP 替换
  • 服务器后端返回图片宽高
  • JS 获取图片宽高,生成图片
  • 图片宽高信息写入文件名,通过正则匹配获取

迫于太麻烦/太菜等原因,最后都没用多久或者放弃。这两天又在思考,能不能从哪里找个突破口,简单的方式实现。最后把目光放到了 Markdown 上,Markdown 中引入一张图片的写法如下:

![alt text](/images/atpx.com.png "title text")

但一直以来 title 属性我都没用上,那么是否可以利用下,于是经过一天的探索终于优雅的解决了图片占位的问题。

首先是面临一个小问题,Typecho 本身用的 SegmentFault 自己编写的 Hyperdown 解析器,不知道是有 bug 还是我以前哪里魔改过,加上 title 内容后解析错误,输出 html 内容为:

<img src="/images/atpx.com.png" alt=" title=" title="" text""="">

通过插件换成 Parsedown 解析器后正常解析:

<img src="/images/atpx.com.png" alt="alt text" title="title text">

接下来的操作思路就很清晰了,首先在主题 function.php 文件中添加一个函数用来加上 img-wrapper 并替换 padding-bottom 的值为 title 的值:

/**
 * Stop html page shakes
 * Written by ATP on 2022-10-07
 * Website: https://atpx.com
 */
function getContent($content) {
	$pattern = '/\<img.*?src\=\"(.*?)\".*?alt\=\"(.*?)\".*?title\=\"(.*?)\"[^>]*>/i';
	$replacement = '<div class="img-wrapper" style="padding-bottom:$3%"><img src="$1" alt="$2"></div>';
	$content = preg_replace($pattern, $replacement, $content);
	return $content;
}

甚至可以顺便加入懒加载的属性,目前这个属性浏览器的支持也很不错了:

<img src="$1" alt="$2" loading="lazy"> 

然后在输出文章内容的 post.php 文件中找到 <?php $this->content(); ?>,替换为:

<?php echo getContent($this->content); ?>

之后只需要在写文章插入图片时在 title 里写上图片的宽高百分比即可,如:

![alt text](/images/atpx.com.png "56.25")

最后输出的 html 如下:

<div class="img-wrapper" style="padding-bottom:56.25%">
    <img src="/images/atpx.com.png" alt="alt text">
</div>

虽然并不是自动化的解决问题,但目前的方式我还是比较满意了,也能在提升一点写作效率的同时保证 Markdown 文章的多平台一致性。

Updated on 2023-02-13

今天又看了一遍谷歌的文章 优化 Cumulative Layout Shift 累积布局偏移,似乎又有新花样—— aspect-ratio 属性,给容器设置一个宽高比,可以极大的方便布局和优化 CLS。

有了aspect-ratio,你只需要给一个宽度或者高度,它就能自己计算出另一个值,也就是说我只需要给每个 <img> 一个宽高比 aspect-ratio 和宽度 width,图片容器就可以自动计算占位了,可以省去一层嵌套。

正当我撸起袖子准备开干的时候,看了一眼兼容性,可惜的是从 Chrome 88(2021-01-19)才开始支持,而 Safari 等到 15( 2021-09-20)才开始支持,让我被迫冷静下来。但又仔细一想,先加上也无妨,每张图片都加上 widthheight 属性也是件麻烦事,等以后图片多了之后工作量更大。

当问题不大,在推出 aspect-ratio 之前, 现代浏览器就又开始支持根据图像的 widthheight 属性自动设置图像的默认长宽比了,并且兼容性会比 aspect-ratio 属性好一些。因此对于响应式图片来说,这里有两套解决方案:

  1. 设置 widthheight 属性再加上一点样式:
<img src="/images/atpx.com.png" width="1920" height="1080" style="max-width: 100%; height: auto;" />
  1. 设置 aspect-ratio 属性:
<img src="/images/atpx.com.png" style="aspect-ratio: 1920 / 1080; max-width: 100%;" />

所以我又按前面的方法又把所有图片的 Markdown 改成 width/height 的形式😣:

![alt text](/images/atpx.com.png "1920/1080")

然后稍微改一下替换函数:

/**
 * Stop html page shakes
 * Updated by ATP on 2023-02-13
 * website: https://atpx.com
 */
function getContent($content) {
	$pattern = '/\<img.*?src\=\"(.*?)\".*?alt\=\"(.*?)\".*?title\=\"(.*?)\/(.*?)\"[^>]*>/i';
	$replacement = '<img style="aspect-ratio:$3/$4" src="$1" width="$3" alt="$2" loading="lazy">';
	$content = preg_replace($pattern, $replacement, $content);
	return $content;
}

再次折腾下来的好处是可以少一层嵌套,并且战未来。随着时间的推移,等大多数人都升级祖传系统和浏览器之后,这套方案的体验会越来越好,也算是一劳永逸了。