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

这篇具有很好参考价值的文章主要介绍了我变秃了,也变强了——再探博客调优。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

“我苦心锻炼了三年,我变秃了,也变强了。” —— 琦玉老师

0x00 大纲

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

0x01 前言

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

0x02 书接上回

上回说到,我们优化后的首页 lighthouse 评分如下:

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

那么性能部分扣掉的一分是在哪里扣掉的呢?点击“查看计算器”链接,里面会有详细的一个评分情况,如下图所示:

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

可以看到评分是相当苛刻的,而且五项标准的分数权重不一样,也即是说,只要你有任何一项有短板,就算其它分数再高,也没办法获得100的评分。可以看到这里主要的扣分项是 FCP 首次内容绘制时间和 LCP 最大内容绘制时间,至于原因,其实在上一篇文章的末尾有提到过,就是有些资源属于页面强制加载项,我们作为使用者是没有办法去裁剪和控制的。

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

0x03 性能调优

DNS 预获取

在自己的博客首页,按 F12 打开开发者工具,切换到“网络”标签,然后刷新博客首页,在 URL 一列,可以查看到所有资源的加载的 URL 地址。然后你会发现,这些资源并非全部来源于同一个服务器,至少可以看到以下不同于主站地址 www.cnblogs.com 的二级或三级子域名:

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 提前进行解析,是不是可以加快访问速度呢?答案是肯定的。借助 DNS 预获取(DNS-prefetch)技术,可以达到我们的目的,在 MDN Web Docs 上,对于该技术是这样阐述的:

DNS-prefetch (DNS 预获取) 是尝试在请求资源之前解析域名。这可能是后面要加载的文件,也可能是用户尝试打开的链接目标。

当浏览器从(第三方)服务器请求资源时,必须先将该跨域域名解析为 IP 地址,然后浏览器才能发出请求。此过程称为 DNS 解析。DNS 缓存可以帮助减少此延迟,而 DNS 解析可以导致请求增加明显的延迟。对于打开了与许多第三方的连接的网站,此延迟可能会大大降低加载性能。

DNS-prefetch 可帮助开发人员掩盖 DNS 解析延迟。

以我自己的博客为例,我将以下域名加入了预取列表(注意因为这些地址都是基于 HTTPS 协议进行访问,所以我这里省略了协议名称,但如果你是加载第三方资源的,务必知晓其访问协议,可能需要指定 HTTP 前缀,请根据实际情况修改):

<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 在浏览器访问那一刻已经被解析过了。

预连接

DNS 预获取(DNS-prefetch)技术可以与预连接(preconnect)技术联用,这里同样援引 MDC Web Docs 的解释:

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

在上面的 DNS 预获取列表后,增加下面的预连接列表:

<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/cnblogs_com/mylibs/1647185/o_200214034545avatar.png">

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

可以看到请求链变短了,而且加载时间也提前了。同时也要注意,预加载(preload)并非在所有浏览器中都支持,不过好在它可以安全降级,顶多是不生效,不会影响到页面的正常使用。

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

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

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

在这里可以看到浏览器在渲染当前页面时所做的各项工作的耗时统计以及负载分析,在报告摘要中,详细罗列了各个步骤所消耗的时间占比,建议从占比最大的部分开始优化,因为这样的收益可能是最高的。

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

此外,还可以关注 FP、FCP、LCP 的触发时机,以及 CLS 的触发次数和位置等诸多细节部分。前面我们提到过,如果 CLS 发生次数过多,将会使用户体验下降,同时严重影响评分。

另一类比较关键的事件是“重新计算样式”事件,如果发现了长时间运行的“重新计算样式”事件,可以选中它,然后在下方点击 “选择器统计信息”功能来了解哪些 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

看来还可以继续寻找新的优化方法。文章来源地址https://www.toymoban.com/news/detail-413750.html

到了这里,关于我变秃了,也变强了——再探博客调优的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式再探——策略模式

    最近在做产品的过程中,对于主题讨论回复内容,按照追评次数排序、点赞排序、时间排序等内容做了深入研究,通过策略模式可以很好的进行优化。 1.策略模式简介 2.策略模式的类图 3.策略模式代码 4.策略模式还可以优化的地方 5.策略模式的例子改造 策略模式:它定义了算

    2024年02月13日
    浏览(44)
  • 设计模式再探——代理模式

    最近在做产品过程中对于日志的统一收集做了深入的研究,最终映射到代理模式的运用上了,通过对代理模式的再探,对代理模式的敬畏又进行了一层升华。 1.代理模式简介 2.代理模式的类图 3.代理模式代码 4.代理模式还可以优化的地方 5.代理模式的项目实战,优化后 代理模

    2024年02月14日
    浏览(31)
  • Golang教程——配置环境,再探GoLand

    Go(也称为Golang)是一种开源的编程语言,由Google开发并于2009年首次发布。Go语言旨在提供一种简单、高效、可靠的编程语言,适用于构建可扩展的软件系统。 Go语言具有以下特点: 简洁易读: Go语言的语法简洁明了,易于阅读和理解。它摒弃了一些复杂的语法和概念,使得

    2024年02月08日
    浏览(38)
  • Python教程——配置环境,再探IDE

    如果我们想要使用Python语言编写程序,我们必须下载Python安装包并配置Python环境,我们现在就来下载一下Python安装包。 Python官方网站 点击下载按钮 我们选择合适的Python版本 这里我直接下载最新版Python3.12 下载速度是十分快的,然后我们进行安装操作 然后我们在文件夹找到安

    2024年02月08日
    浏览(41)
  • OpenResty学习笔记03:再探WAF

      我们上一篇安装的WAF来自另一位技术大神 赵舜东 ,花名 赵班长 ,一直从事自动化运维方面的架构设计工作。阿里云MVP、华为云MVP、中国SaltStack用户组发起人 、新运维社区发起人。 虽然并非安全专业出身,但根据他的自述,边学边写,只用了几天的时间就将WAF写出来了,

    2024年02月03日
    浏览(34)
  • 【Python 零基础入门】常用内置函数 再探

    Python 是一种解释性, 高级和通用的变成语言. Python 由 Guido van Rossum 创建并 1991 年首次发布. Python 的设计强调代码的可读性, 其雨大允许我们使用相较于 C++ 或 Java 更少的代码表达概念. Python 使得变成变得更简单, 更快捷. 下面就跟着小白我来一起看一下 Python 常用的内置函数.

    2024年02月04日
    浏览(43)
  • c++ 派生类 文本查询程序再探

    2024年02月14日
    浏览(30)
  • 理解机制,再探单元工厂的实现原理

    最近有点忙,好久没更新文章了,今天继续再研究一下单元工厂的实现机制。为什么我们要这么重视这一块的内容呢?因为用计算机的目的是为了处理大量数据,如果数据量不大,大多情况下用纸就好了,专门用个计算设备的便捷性也就体现不出来。而大量数据的呈现方式的

    2024年02月11日
    浏览(27)
  • HTTP杂谈之Referer和Origin请求头再探

    一  关于Referer和Origin的汇总 nginx防盗链 HTTP杂谈之Referrer-Policy响应头 iframe标签referrerpolicy属性 如何合法的跨域访问 nginx与跨域细节探究 使用referer模块和secure_link模块提供变量防盗链 二   细节点、重点、难点挖掘 ①  nginx valid_referers指令的 server_names  referer三点注意事项

    2024年02月10日
    浏览(38)
  • 数据库管理-第七十七期 再探分布式(20230523)

    上一次系统探讨分布式数据库还是在第三十六期,经过大半年的“进步”加上中间参加了不少国产数据库的研讨会或者交流,对分布式数据库的理解还是有了些许进步。 最近出现了所谓的“新词”:单机分布式,简言之就是一台服务器运行多个数据库实例,通过spanner框架等

    2024年02月08日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包