我是如何搭建这个博客的
嗯!2024 年的新博客!
为什么要搭这个博客? #
人们说世界上没有两片一样的叶子。而在世人的眼里也许只能看到那一抹绿,没有人在乎两片叶子之间的细微的差别。对于现代人而言也难逃“我绝不罕有,往街里绕过一周,我便化乌有”,诚然如此。我所爱的,定然也有类似的爱;我所恨的,也不是天下一份。我所想要的,世上定然有一个人和我一样想。所以,同质的想法、重复的话,有存在的必要吗?把别人的话再说一次,那不算是种浮夸、要做大娱乐家吗? 我抱持这种想法很久。要别人完全不一样,要自己出类拔萃,要博人眼球。往往是一番痛苦挣扎之后再胎死腹中。
可我现在想变得不一样了。只是当作对自己普通人生的记录,也是件好事。就写写编程、写写游戏或者是写写玩具,对我这个已经开始常常遗忘万事细节的中年人来说,就已经有纪念品的功效了。“啊,那时候我就喜欢这种幼稚的东西啊。”确是多年后用于怀念的好物件。感谢 IT 技术,也许这种垃圾也能免费保存几十年,要比厚厚一本日记本存续得更好、更久。我确实现在看淡对别人的想法了,真的顾不上,自己开心就好了。
所以,终于有这个博客。
如果抛开框架,一个静态博客应该考虑哪些要素? #
- SSG
- 最小体积的 JavaScript bundle。要是可以不加载 js 回来,那就完美了。
- 图片一定是渐进的
如何选择框架?为什么是 astro? #
- astro 更像是 jsx 版本的模板引擎,可组合、有插槽,构建时渲染网页内容。
- 在处理复杂交互、模板不够用之时,又可以使用 react/vue 等更复杂的组件,即所谓的 Island。当然可以懒加载、异步加载。非常适合评论、登录这一类的辅助功能。不需要用什么 Server Component,也就不需要超大个头的 react。
- 简单,清晰。没有奇怪的封装,比如 GraphQL。啊,对,说的就是你,Gatsby,你坐下。
在 astro 的基础之上,要如何优化细节? #
1. 渐进图片 #
这东西 Google 提了非常之久,现在看已经是很多优秀网站的标配。
本质上是说,在移动端上用小尺寸的图片,桌面端上用大一点的。如果你把图片放大、查看原图,那再去加载原始图片。
CDN #
当然没有什么比 CDN 更能加速图片的下载了。所以我这次使用用了 ImageKit 的服务。对于我这个小破站非常合适,并且:
- 免费额度十分慷慨:20GB Bandwidth, 20GB Media storage, 1000 Video processing units, and 500 Extension units.
- 功能完备:图片压缩、减裁、格式转化一应具全。
- 网络快:我自己的体感上要比 cloudflare image 更快一些,而后者每个月还要 $5 的。
- 免费账户随意申请,不要填任何信用卡
良心啊!强烈推荐!
图片体积优化 #
以这张 Unsplash 图片来举例:https://unsplash.com/photos/a-night-sky-filled-with-stars-and-trees-eKbt1g1RT6I
这是一张原始尺寸 6000x4000px、足足有 11+MB 的超大图片。那么我们在打开博客页面时就把它加载进来,非常浪费流量,也拖累了加载时长。如果浏览者是手持设备,这么高质量的图片,直接展现在页面里也看不到太多细节。这个时候,即使转换到 webp/avif 格式之后也仍然有 2.3MB+ 的大小,还是不够理想。
所以,我们需要把这个图片做尺寸缩小,最好是能根本设备的尺寸来缩小到对应的尺寸。一般来说,移动设备的屏幕宽度在 512px 以内,桌面端就可以大一点。而根据我的博客设计风格,最宽设置成 1024px 就非常足够了。只有当浏览者想要最高质量的图片时,也就是点击图片、查看原图时,给他提供优化格式的原始图片。
这个工作说起来不复杂,可以结合 sharp 等工具可以很容易地完成。但要不说现在日子富裕了呢,我们有更方便的 Image CDN 可以用。专业的图片 CDN 不仅仅提供 CDN 的下载加速能力,还提供非常方便的尺寸调整、格式转换等等能力。前边有提到的 ImageKit 就非常好用。
这里用一个例子概要介绍一下我是如何使用 imagekit 的。比如我们将上边的 unsplash 图片,上传到 imagekit 后可以得这样一个链接:
https://ik.imagekit.io/6mysxbs8t/dcleiaDupYmt9b5gDr93ZvGgStNld9hk8YD0YmTrxQg.jpg
根据 imagekit 的图片优化能力要求,只需要在 appId 6mysxbs8t 后边加上转化指令即可,比如我想生成成一个移动端使用的 512px 宽、webp 格式的图片。那对应的链接就是
https://ik.imagekit.io/6mysxbs8t/tr:w-512,f-webp/dcleiaDupYmt9b5gDr93ZvGgStNld9hk8YD0YmTrxQg.jpg
这张调整后的图片,只有 13KB。目测在移动端上使用是足够的。
响应式加载 #
现在的日子富裕了!DOUBLE KILL!
我们现在有一个新的元素叫 picture。它支持设定多个 source,每个 source 可以搭配一个 media-query。
这里有一个来自 MDN 的示例:
<picture>
<!-- 当 media-query 生效里,使用这个图片 -->
<source srcset="mdn-logo-wide.png" media="(min-width: 600px)" />
<!-- 默认加载这个 -->
<img src="mdn-logo-narrow.png" alt="MDN" />
</picture>
这也就非常简单地实现了移动端、桌面端分别加载不同的尺寸的图片。
懒加载 #
现在的日子富裕了!TRIPLE KILL!
现在,img 元素有一个新的属性 loading。我们只要设定成 lazy 就行了。你的高级浏览器会只在图片被展现到视野里才开始加载图片。赞美技术的进步。
模糊占位图 #
占位图:在网络很差时,它可以临时性地给用户看到一定的内容,以提升体验。它有这么几个特点:
- 极致压缩: 这是一个实际尺寸很小(128px宽),并且通过高斯模糊过的图片。所以它的体积一般只有1-2KB。
- 直接内嵌:由于它已经非常小了,再发起一个请求不划算。因此直接以
base64的形式嵌入。
效果如这个图片所示:
这张图片的原图也在这篇博客中 😆
如何快速把图片上传到 ImageKit? #
我花了一点时间,做了一个 raycast 的扩展。当前还在等待扩展的 MR。MR 通过之后大家就可以在 raycast store 中安装它。
这个插件的功能非常简单:
- 上传在
Finder中选中的图片 - 上传剪贴板中的图片
- 查看上传记录
放上几张截图,一目了然:
插件提供 markdown 图片引入的代码生成,方便直接写入到 markdown 文档里。
CDN 预热 #
首次访问 CDN 上的图片,肉眼可见的慢。访问过之后,就变得快起来。这是 CDN 原理所决定的。
所以能预热肯定是好的。但是对于我这么一个日均 PV < 10 的小博客做个全球预热真的是太浪费了!为了地球母亲,现在还是省一点。
2. 页面预加载 #
除了第一个落地页面之外,从这个页面出发的其他所有页面,都可以被预加载。具体来说就是在 a 元素上做手脚。a 元素的功能就是在多个页面之间跳转,所以当 a 元素满足被渲染之后,我们就可以把它指向的下一个页面给提前加载回来。当然,这种渲染即预加载有点激进。astro 提供了 4 种预加载策略:
load页面渲染完成时viewport当a出现在视野时hover当鼠标浮在链接上时tap当用户点击a链接时
load 最激进,tap 最保守,我比较倾向 viewport。预加载之后,由于对应的 html 已经被 http 缓存住,当真正打开时就会非常迅速。
后续还打算做什么? #
- 登录
- 评论
- mdx 优化
- 文章提纲 table of content
- code 块优化
- copy 按钮
- 标题 / 文件名
- sandbox:类似于 MDN 上的 playground。大概会接入一个免费的 sandbox 服务。
- 搞花样
- 放一个 COBE 在页脚上
- 接入某个 CMS 体系,发布内容不再需要依赖
astro dev。- 方案0: 也许直接在
github上编辑源码就是一个不错的选择 ⁉️ - 方案1: 接入 mak 在线编辑器。这个编辑器会将 markdown 文档发布到 gist。那再通过脚本工具每次构建时,把所有的 gist 拉取到本地再生成页面。或者是直接在 notion 里边写?
- 方案2: 由于登录和评论大概会用
supabase,所以把文档内容也放进去,可能是个好选择。
- 方案0: 也许直接在