静态博客优化

Author Avatar
琉璃 2月 07, 2020

BBC 发现其网站的加载时间每增加一秒,便会多失去 10% 的用户。
DoubleClick by Google 发现,如果页面加载时间超过 3 秒,53% 的移动网站访问活动将遭到抛弃。

网站的加载时间直接关系到网站的访问量。我们可以提升网站的加载速度。比如优化代码,减少脚本数量,提升网站响应速度等等。这些提升网站加载速度的方法都比较硬核,需要一定的开发功底。比如想要优化代码,但是一个博客的主题代码量可不少,到底从哪着手优化呢?除了从理论上提升网站的加载速度,我们也可以减少用户感知到的等待时间。比如把重要的内容先加载了,不重要的东西之后加载。又或者对图片采用懒加载的方式。等图片进入窗口时,再进行加载。

背景

我的博客基于Hexo,托管在Netlify上,Theme是hexo-theme-material。几年前,这个Material Theme是Hexo社区最火的Material主题。但在2018年,仓库的拥有者消失了。拥有者消失之后,核心开发者也没有对项目进行后续的维护和开发。到了现在,托管项目文档的网站也打不开了。也不知道这个我还能再用这个主题几年。

准则

性能优化这个词很大。但到底从哪里开始优化呢? 我个人使用Google的PageSpeed Insights进行扫描。PageSpeed Insights的报告会显示网站的性能并且会给出建议。接着我就按照这些建议对网站进行优化。

如果需要看网站在各个地区的加载速度,可以使用站长工具17CE

对于网站SEO,内容,流量之类的报告可以参考SimilarWebAlexa。但是如果你的博客流量很少,以上的这些网站大部分栏目都会是空着的,因为没有足够的数据进行分析。

性能

我的博客从电脑端加载性能还算不错(Speed Index 在1.1s左右),但手机端性能奇差无比(Speed Index在5s左右)。归功于中国的网络设施,从中国访问我的网站加载速度也非常的慢。

CDN

CDN是提升博客加载速度最方便的方法。我选择的是CloudFlare。只要将域名的NS服务器改到CloudFlare上,CDN便会自动生效。这可以大大提升博客在全世界各地,除了中国的访问速度。

据说将SSl/TLS>Overview中的SSL模式改成Flexible可以提升网站的加载速度。但是Netlify默认HTTPS,如果将SSL模式改成Flexible,加载网站时会无限重定向,导致加载失败。

需要注意的是在Speed>Optimization>Rocket Loader开启的情况下,可能导致加载网页时Console中出现错误。但是并不会影响网站的加载和用户的浏览。

CloudFlare有中国节点,但是需要升级到Business版本并且提供备案证明。

如果需要进一步优化国内访问速度,可以考虑备案以后使用国内的CDN供应商,或者将网站托管在Coding上。

外部脚本

综合下来,速度最快的是jsDelivr。海外速度一流,从中国访问的速度也还行。几乎所有的常见第三方脚本都可以在上面找到。

从中国访问,速度最快的是BootCDN。中国访问速度一流,但是海外速度是不行。

综合考虑了一下,博客内的所有脚本都采用jsDelivr上的。

dns-prefetch

<link rel="dns-prefetch" href="https://yourSourceDomain.com"/>添加到Head中,可以让浏览器提前解析这些域名。减少加载外部脚本时的延迟。

图片

图片无处不在:头像,题图又或者是博客中的图片。一个图片动辄几百kb,极大的拖累了网站的加载速度。

图片压缩

Webp是Google近年来推出的无损图片格式。Webp比PNG小26%。大部分主流浏览器也支持Webp格式。如果将JPG图片压缩成Webp,并且接受80%的图像质量,文件大小可以减少60%。

Webp其一的补足就是编码和解码的速度要慢上不少。虽然解码速度慢了,但是文件体积减少了。Webp节省下来的图片下载时间完全大于多花在解码上的时间。

另一个补足便是它做不到全平台的支持。Safari不支持Webp。因此我们可以考虑给safari用户特供PNG图片。

我使用的是腾讯智图。大部分时候图片品质的差距很难看出来。因此为了性能,我普遍选择30的图片品质。

图片懒加载

不加载用户看不到的图片。等那些图片进入用户的视线再加载。

虽然Chrome的设置中已经有了lazy load 的选项,但并不是默认开启的。因此我们需要一个第三方库。我选择的是lazysizes。将<script src="https://cdn.jsdelivr.net/npm/[email protected]/lazysizes.min.js" async></script> 插入到主题对应的位置。然后将<img src="<%- url_for(theme.img.avatar) %>" />改成这个样子<img class="lazyload" data-src="<%= url_for(theme.img.avatar) %>" >。也就是为img加上class="lazyload",将src改为data-src

脚本异步加载

对于不需要立即加载的脚本,我们可以采用异步加载。比如analytica.js,我们并不在意它什么时候加载。我们可以使用<script async src="https://www.google-analytics.com/analytics.js"></script>

async让外部脚本的加载完全独立于页面的加载。即DOMContentLoaded和有async的外部脚本没有任何关系。页面不再会等待这个脚本的加载。其他脚本也不会等待这个脚本的加载了。因此对于完全独立的脚本我们可以为它加上async。这样这个脚本的加载就不会阻塞页面的加载。

字体

如果看一看各个网站资源的大小,字体总是最大的那个。随着对网站设计的要求越来越高,越来越多的网站选择自定义字体。这便给网站带来了很大的性能开销。通常情况下,在字体加载完全之前,页面是不会进行渲染的。即页面上不会出现一个字。

为了减少用户感知到的等待时间,我们可以让内容一开始采用默认字体显示出来。等自定义字体加载完全后,再替换掉默认字体。我们需要做的仅仅是给@font-face加上一行font-display: swap;

Instant.page

用户想要点击一个链接是有预兆的。在电脑端,他们的鼠标会悬浮在超链接上。在手机端,他们会按下超链接(当手指松开时,才会触发点击)。这中间大概留给电脑几十毫秒的反应时间。如果我们提前对下一个页面进行加载,这就可以减少用户的等待时间。

Instant.page就实现了这样的功能。将<script src="https://cdn.jsdelivr.net/npm/[email protected]/lazysizes.min.js" async></script>加入网站,就可以享受这种近乎无赖的优化。

内容

除了让用户可以顺利的打开博客,博客的内容也是很重要的

清晰的标题

现代人不习惯花费大量时间阅读长篇文章。因此文章的分段,子标题一定要齐全。

用户第一眼看到的是文章标题和摘要。一个清晰的标题和摘要可以帮助读者了解这篇文章的主旨。当用户来到文章的页面时,清晰的子标题可以帮助读者确定他想阅读那一段。没有人想面对那种又臭又长的文章。

标签

标签尽量要齐全。标签可以帮助用户寻找到它所感兴趣的内容。当然最重要的还是让搜索引擎知道这篇文章到底讲了什么,什么时候展示这篇文章。

Latex

考虑到之后会写数学相关的内容,Latex也需要准备好。

Footnote

在写关于时候有了脚注的需求,因此添加了脚注。估计之后写数学内容的时候也用的上。

摘要

我的摘要总是独立于文章的。这个主题默认将摘要作为正文的第一段。这让我的文章有一种割裂感。因此我将摘要从正文中移除。

未来

字体

由于我的文章都较长,因此会考虑换一个字体。可能会考虑思源宋体。这个衬线体比较适合于较长的文章。(已完成)

手机端性能优化

手机端的性能还是远远落后于电脑端,也达不到优秀的水准。手机端的还是有较大的提升空间。

Web Notification Push

相比于邮件订阅,浏览器通知订阅似乎更吃香。考虑以后添加浏览器通知的支持。到时候记得订阅哦。

This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:https://www.inevitable.tech/posts/7a4bc632/