性能初探:页面加载慢

一、初识“白屏之痛”

2016年初春,我负责的第一个企业官网项目终于上线了。
凌晨三点,当最后一个文件通过FTP传到服务器,我在公司破旧的工位上用力拍了下键盘——那种混杂着疲惫与成就感的情绪,至今记忆犹新。

然而第二天上午,运营同事发来一张截图:
“客户说网站打开要十几秒,一直白屏。”

我刷新页面,盯着浏览器标签栏那个缓慢旋转的加载图标,心里一沉。
原来代码在本地跑得飞快,到了真实网络环境竟是另一番景象。


二、笨拙的第一次“优化”

我打开F12,笨拙地切到Network面板——那时我甚至不知道这个标签页的存在。
眼前瀑布流让我倒吸一口凉气:
47个HTTP请求,其中32个是未合并的CSS背景小图标,首页一张banner图竟有2.3MB,jQuery和三个插件各自独立加载……

“原来这就是白屏的原因?”我喃喃自语。

我的“优化”简单粗暴:

  1. 把图片用PS“另存为Web格式”,质量调到60%
  2. 手动把十几个小图标拼成一张雪碧图
  3. 在页面底部把JS挪到一起

重新部署后,加载时间从14秒降到9秒。
我松了口气,以为问题解决了。


三、师傅的“性能第一课”

带我的师傅老张路过我工位时瞥了一眼屏幕:
“还在用同步加载jQuery?知道async属性吗?”
“雪碧图是手工拼的?没用构建工具?”
“CSS没压缩就上线了?”

他拉过椅子坐下,在我电脑上敲了几行命令:
“装个grunt,配置个cssminuglify。”
“图片用tinypng的API压缩。”
“最重要的是——”他指着代码里一堆$(document).ready()
“你知道jQuery的ready事件其实比DOMContentLoaded还慢吗?”

那个下午,我笔记本上记满了新名词:
关键渲染路径、CSS阻塞、JS异步加载、HTTP/1.1并发限制……


四、深夜的“性能战争”

真正让我崩溃的是客户发来的测试视频——
在某个三线城市网吧的IE8上,页面加载整整28秒。

“IE8没有开发者工具啊!”我几乎要抓狂。
老张丢给我一个U盘:“里面有个ietester,再装个fiddler模拟慢速网络。”

那是我第一次接触“网络模拟”:
把带宽调到2Mbps,延迟设到200ms,刷新页面——熟悉的白色再次长久停留。

我学会了:

  • 把CSS内联到<head>里关键的那部分
  • 给JS加上defer
  • loading="lazy"(虽然那时还没这个属性,但学会了图片延迟加载的思路)
  • 发现某个插件居然在加载时同步请求了谷歌字体——直接删掉

凌晨四点,当页面在模拟的3G网络下5秒内完成首屏渲染时,
我瘫在椅子上,第一次体会到“性能优化”这四个字的分量。


五、意外的“高级技巧”

项目上线一周后,客户突然要求加一个“领导视察”的专题页,
里面要放二十多张高清合影。

“这不可能快得起来!”我向经理抗议。
老张却神秘一笑:“知道什么是‘渐进式JPEG’吗?”

他教我:

  1. 用Photoshop保存为“连续”格式的JPEG
  2. 先加载一个模糊的缩略图
  3. 用JS监听滚动,进入视窗再加载原图

“用户看到的是从模糊到清晰的过程,感知速度会快很多。”
——这是我第一次接触“感知性能”的概念。


六、写在青铜时代的尾声

那个项目最终稳定在3G网络下4.2秒首屏。
我在项目总结里写道:
“性能优化不是上线前的临阵磨枪,而是从设计阶段就该考虑的约束条件。”

很多年后,当我面对Webpack的代码分割、React的Suspense、
CDN的边缘计算时,总会想起2016年那个春天:
我蹲在公司的测试机房,用一台装着Windows XP的旧电脑,
一遍遍刷新页面,数着秒表,和浏览器的加载动画较劲。

青铜时代的性能初探,没有高深的算法,没有复杂的工具链,
有的只是一个切图仔,第一次意识到:
代码不仅要能运行,还要跑得快;
功能不仅要实现,还要让人等得舒服。

那是我职业生涯中,
第一次真正理解“用户体验”四个字,
是从等待的每一秒开始的。