本博客优化点总结 (一) - js 字体 归档 评论系统 CDN
修订记录
- 2021.01.05 - 更新部分内容
- 2017.02.18 - 初稿完成
这篇文章篇幅过长并且过于杂乱,2021 年我又开了个新坑 本博客优化点总结 (二) - Ghost 路由 RSS 暗黑模式 闪白屏,针对 Ghost 博客做了一些优化,并且完美处理了暗黑模式下闪白屏的问题。
储存模块
最早是自己写了一个可以上传图片到 upyun 的插件,pupboss/ghost-upyun-store。现在已经改用腾讯云。
链接优化
在文章内超链接的前面加上小图标,详细功能参考下面列表:
- https://500px.com/p/isjetl
- https://www.apple.com/
- https://www.bilibili.com/video/BV1o7411N7q8/
- https://www.douban.com/
- https://emby.media/
- https://www.facebook.com/
- https://github.com/pupboss
- https://www.google.com/
- https://www.imdb.com/
- https://instagram.com/isjetl
- https://www.jianshu.com/
- https://www.linkedin.com/in/isjetl/
- https://www.pinterest.com
- https://www.pupboss.com/
- https://www.reddit.com/
- https://weibo.com
- https://soundcloud.com/
- https://www.spotify.com/
- https://stackoverflow.com/
- https://store.steampowered.com
- https://telegram.me/telegram
- https://www.twitch.tv/
- https://twitter.com/isjetl
- https://v2ex.com/
- https://en.wikipedia.org/wiki/Main_Page
- https://www.youku.com/
- https://www.youtube.com/
- https://www.zhihu.com/
优化文章内链接
外部链接使用新 tab 打开。用 DOM 选择器遍历一下整个文档即可。
$(document.links).filter(function() {
return this.hostname != window.location.hostname;
}).attr('target', '_blank');
// 或者
var links = document.links;
for (var i = 0; i < links.length; i += 1) {
if (links[i].hostname && links[i].hostname != window.location.hostname) {
links[i].target = '_blank';
}
}
字体优化
- 使用 bramstein/fontfaceobserver 来管理外部字体的加载
- 使用 jrnewell/goog-webfont-dl 把谷歌字体下载到本地,虽然谷歌字体能访问了,根据测试,移动网络还是连不通,为了妥协,还是将字体放到本地吧
- 使用尽可能少的 font-family,减少 CSS 下载时间
- 加入一个标识符,如果 web 字体下载成功,就用 web 字体,如果没有,就调用系统内置字体
拆分大的 js 或者合并太碎的 js
现代浏览器支持同时下载多个 js 文件,把 js 拆分成 2-3 个可以提高性能。但是如果你的 js 文件过于零碎,最好考虑把它们合并起来,以减少频繁网络请求带来的延迟。
如果你有遇到过大 js 在 Nginx 里面下载不下来的问题,可以参考如下推特。
实际上是因为 Nginx 错误配置,导致缓存区无权限读写 - https://twitter.com/isjetl/status/1350725012550868995
精简 FontAwesome
FontAwesome 的字体体积还是有点大。如果有条件还是建议自己造 icon ,还方便前文说的网站小图标。另外某些去广告插件会屏蔽 social icon,自己造 icon 还有个好处就是可以避免这种情况。
Fanboy's Social Blocking List 这个规则简直丧心病狂,icon-github 这种 icon 也会被屏蔽掉。更要命的是在某些情况下,这个规则是默认加载到 AdBlock 的 – https://twitter.com/isjetl/status/1346393859580784641
加入了 ToC
使用的是 idiotWu/jQuery-TOC 这个插件。
Archive 功能
无耻的移植了xiaoluoboding/ghost-theme-kaldorei的创意。
评论系统
早期用的是 Disqus,因为它在国内被墙的缘故,当时出现过一些状况, async
加载模式下会阻塞页面渲染,只有超时失败之后才渲染出文字。后来解决了这个问题,如果有同样问题的朋友,可以参考最后一个小标题。
现在改用 Valine 方案,因为不需要后端,又能满足需求。
Google Analytics
最开始统计是放到服务器端的,GA 配合 Nginx,因为阿里云和 Google Analytics 还是很畅通的,但是问题就是导致统计的信息不全,最后还是放到了网页上,牺牲了一定的加载速度。
全站放到 CDN
我使用的是腾讯云的 CDN,性能还不错,挑不出毛病,价格也合理。详细可以参考这篇:全站 CDN 的选择和配置经验分享。
图片压缩
ImageOptim,最强大的压缩软件,没有之一。又拍云的压缩功能损失略大,反正我不能接受,效果不如这款软件。手动压缩后再上传 CDN,虽然略微麻烦一些,但是效果还是不错的。
图片 Lazy Load
以前用过 tuupola/jquery_lazyload 这个插件,实现图片的懒加载,改进用户体验。但是最后发现这是大坑一个,RSS 或者其他方式访问的话,图片不会被加载。结论就是流量不值钱,不要使用这个方案实现懒加载。如果真的想折腾,可以看看划到图片位置才显示的方案。
HTTPS & HTTP/2
- Let's Encrypt 的证书,自动更新
Nginx 1.10.3 使用的是 dotdeb 编译的 Nginx,编译时加入了新版的 openssl,可以支持 HTTP/2。Nginx 默认已经支持 HTTP/2。
HSTS & OCSP Stapling
这就属于 Nginx 的配置范畴了,具体可以看 Nginx 配置上更安全的 SSL & ECC 证书 & Chacha20 & Certificate Transparency。
HSTS Preloading
可以在这个网站上面提交你的网址 HSTS Preload List Submission,最后会加入到 Chrome 的 Preloading 列表,实现直接访问 HTTPS,而不是从 HTTP 跳转,可以有效预防劫持。
附录:外部资源引用
这里主要是说在别人服务器上的,尤其是被 GFW 的外部资源。当然了,不只限于 JS 文件,CSS,图片什么的都可以,原理大同小异。
我的博客上面的资源,几乎所有的 JS,图片,都在自己的 CDN,其他的在 VPS,只有 Google Analytics 和 Disqus 引用的第三方 JS。
事情需要从这个博客的 Theme,Namjagbarwa 说起,首页的 card 在 layout 之前,需要保证所有外部资源加载完毕,其代码类似于这样:
$(window).load(function() {
window.sr = window.ScrollReveal().reveal(cardName, {
afterReveal: function () {
if ($postsGrid) {
$postsGrid.masonry("layout");
}
}
});
});
没加载完的时候是一片空白。界面上什么都没有,造成一种假死的状态。
如果想加入 Disqus 评论个数的功能,需要引入 count.js
,所以就导致了没翻墙的情况下,这个资源根本无法加载成功,阻塞了 $(window).load()
。
即时这个 script 标签设置 async=true
,也是会阻塞。
解决办法很巧妙,既然 $(window).load()
只会在所有资源加载完毕的时候触发,那太简单了,把 Disqus 干掉不就好了么。。当然不行,干掉了还怎么显示评论个数。
JS 对资源的判定标准是,Tag 里面有 src
Attribute,我们只需要把这个 Attribute 干掉,就能保证 $(window).load()
忽略掉这个 JS。
<script type="text/javascript">
(function () {
var s = document.createElement('script'); s.async = true;
s.type = 'text/javascript';
s.setAttribute('external_src', '//' + window.disqus_shortname + '.disqus.com/count.js');
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>
我们把 count.js
的 Attribute 设置为 external_src
,就不会再阻塞 rendering,但是资源也没法加载了咋弄,这就更容易了,在 load 之后遍历一下:
$(window).load(function() {
$('[external_src]').each(function() {
var external_src = $(this).attr("external_src");
$(this).attr("src", $(this).attr("external_src")).removeAttr("external_src");
});
});
这样就完美解决了。