新的一年从优化博客开始。这一次从内容,性能这两方面对博客进行优化。
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,内容,流量之类的报告可以参考SimilarWeb 和 Alexa。但是如果你的博客流量很少,以上的这些网站大部分栏目都会是空着的,因为没有足够的数据进行分析。
性能
我的博客从电脑端加载性能还算不错(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
相比于邮件订阅,浏览器通知订阅似乎更吃香。考虑以后添加浏览器通知的支持。到时候记得订阅哦。