我变秃了,也变强了——再探博客调优

科技资讯 投稿 5400 0 评论

我变秃了,也变强了——再探博客调优

0x00 大纲

目录
    0x00 大纲
  • 0x01 前言
  • 0x02 书接上回
  • 0x03 性能调优
    • DNS 预获取(DNS-prefetch)
    • 预连接(preconnect)
    • 预加载(preload)
    • 减少不必要的 HTTP 调用
    • 使用自定义的语法高亮
    • 进一步精简 JavaScript 和 CSS
    • 性能辅助分析
  • 0x04 小结

0x01 前言

四个月前,我在《你是来找茬的吧?对自己的博客进行调优》一文中探讨了以博客的使用者而不是开发者身份去进行优化,究竟能做到何种程度的问题。当时以 Edge 浏览器的开发者工具里的 lighthouse 评分和加载时间作为基准,经过一系列的针对性优化调整,将博客首页的评分逼近到了“性能(99/100)”、“无障碍阅读(100/100)”的水平,但是当时有一个遗憾,就是没能完成双百,那么时隔多日,这次就要集中一点,登峰造极,完成双百挑战。

0x02 书接上回

lighthouse 评分如下:

既然堵不住,那能不能加速呢?

0x03 性能调优

DNS 预获取(DNS-prefetch)

https://common.cnblogs.com/
https://images.cnblogs.com/
https://pic.cnblogs.com/
https://blog-static.cnblogs.com/
https://account.cnblogs.com/

我们打开命令提示符或者其它你喜欢的终端,输入nslookup命令(注意不能用ping指令,部分服务器出于安全考虑,是禁用 ICMP 协议访问的),查看各个域名对应的 DNS 解析地址,就会发现它们的 IP 地址是不一样的,以主站和 pic.cnblogs.com 为例:

DNS-prefetch (DNS 预获取 是尝试在请求资源之前解析域名。这可能是后面要加载的文件,也可能是用户尝试打开的链接目标。
DNS-prefetch 可帮助开发人员掩盖 DNS 解析延迟。
<link rel="dns-prefetch" href="//common.cnblogs.com">
<link rel="dns-prefetch" href="//images.cnblogs.com">
<link rel="dns-prefetch" href="//pic.cnblogs.com">
<link rel="dns-prefetch" href="//blog-static.cnblogs.com">
<link rel="dns-prefetch" href="//account.cnblogs.com">

注意这里不需要添加主站的地址,因为主站的 DNS 在浏览器访问那一刻已经被解析过了。

预连接(preconnect)

DNS-prefetch 仅执行 DNS 查找,但preconnect会建立与服务器的连接。如果站点是通过 HTTPS (提供)服务的,则此过程包括 DNS 解析,建立 TCP 连接以及执行 TLS 握手。将两者结合起来可提供进一步减少跨域请求的感知延迟的机会。
<link rel="preconnect" href="//common.cnblogs.com">
<link rel="preconnect" href="//images.cnblogs.com/">
<link rel="preconnect" href="//pic.cnblogs.com/">
<link rel="preconnect" href="//blog-static.cnblogs.com/">
<link rel="preconnect" href="//account.cnblogs.com/">

我们看下效果,以userinfo接口调用为例(访问 account.cnblogs.com)为例,增加 DNS 预获取优化之前耗时是这样的:

预加载(preload)

以自定义的头像为例,需要由自定义的主题脚本通过prepend的方式动态添加节点,这意味着主题脚本和jquery-2.2.0.min.js完成加载之前,该头像都暂时不可用。但是头像的 URL 地址我们是预先知道的,这个等待就白白浪费了许多时间。

<link rel="preload" as="image" href="//images.cnblogs.com/likecs_com/mylibs/1647185/o_200214034545avatar.png">

减少不必要的 HTTP 调用

loadBlogDefaultCalendar函数发起的,这个函数定义在blog-common.min.js文件里——上一篇文章提到过,这个文件是默认加载的,是博客园的公共JavaScript函数库,无法屏蔽。

loadBlogDefaultCalendar是作为全局函数发起匿名调用的,那么在blog-common.min.js文件加载之后,loadBlogDefaultCalendar函数执行之前,我们是可以利用JavaScript Function Hijacking把它替换掉的,像这样:

<script>window.loadBlogDefaultCalendar=Function.prototype</script>

它刚好可以与前面所有的优化一起放在博客园后台-设置页面中“页首 HTML 代码”处,保存后刷新页面,再看原来的 AJAX 请求已经没有了:

使用自定义的语法高亮

prism.js语法高亮,它会根据页面中的language type自动加载对应语言的高亮模块。对于一个页面有多种语言或开启了行号显示的情况,可能会发生多次的模块加载,那么你会在控制台看到prism-autoloader.min.js同时加载了若干个prism-*开头的脚本。那为什么说是可能呢?因为prism.js里面其实已经集成了多种常用语言,除非你用到了里面没有的语言模块或者插件,才会触发加载动作。

prism.js的官网上可以很方便的定制模块,只勾选自己常用的几种语言即可,BTW,我还使用了彩虹括号插件……总之,像买菜一样选择自己想要的东西就好了:

进一步精简 JavaScript 和 CSS

在开发者工具里找到”覆盖范围“标签,如果没有,可能要点击旁边的”+“号手工添加。点击”开始检测覆盖率并刷新页面“,覆盖率统计在你手工点击停止前会一直进行,这时候你可以去页面进行各种操作,尽可能地触发代码。随后在覆盖率报告中,可以看到当前各个 JavaScript 和 CSS 的使用情况:

这样做的目的是找出优先加载和优先执行项,如果脚本和样式表体积较大,就可以按照执行优先级拆分,利用前面提到的预加载(preload)技术将最基础部分优先加载,后续使用到的脚本和样式延迟加载或者按需加载。尽量减少或加快关键资源的加载,依然是提高 FP、FCP 和 LCP 分数的关键。

性能辅助分析

lighthouse 能帮你评估页面的总体情况的话,那么性能分析工具则可以助你从细节入手找到瓶颈。同为开发者工具里,切换到“性能”标签,点击”开始分析并重新加载页面“按钮,能够自动刷新当前页面并对其进行采样分析,最终生成的报告如下所示:

如果性能报告中出现了红色三角形长任务(被标记红色),也是需要重点关注的,它指示主线程上耗时过长且性能缓慢的工作,通过查看对应时间轴火焰图上最宽的部分,找到耗时的原因。

另一类比较关键的事件是”重新计算样式“事件,如果发现了长时间运行的 “重新计算样式”事件,可以选中它,然后在下方点击 “选择器统计信息”功能来了解哪些 CSS 选择器占用的时间最多。从我的个人经验来看,通常来说 CSS 的优化收益不是很大(微秒级),除非有很严重的性能问题,选择前面几项耗时最突出的选择器进行优化是比较划算的方案。

0x04 小结

在经过一系列的究极折磨后,这是首页最终的 lighthouse 评分:

(0.1×98 + 0.1×100 + 0.25×99 + 0.3×100 + 0.25×100/(0.1 + 0.1 + 0.25 + 0.3 + 0.25 = 99.55

看来还可以继续寻找新的优化方法。

编程笔记 » 我变秃了,也变强了——再探博客调优

赞同 (31) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽