首页 / 资讯 / 前端首屏加载性能优化 一线踩坑攒下的实在经验

前端首屏加载性能优化 一线踩坑攒下的实在经验

上周帮朋友排查个老项目的线上问题。 打开页面白屏等了4秒。 首屏内容才慢悠悠出来。用户早就划走了。 这种场景,做过前端的人谁没碰到过?

别上来就堆优化方案

很多团队拿到优化需求的第一反应,是列个长长的技术清单。上CDN、压图片、拆代码包、上SSR,恨不得把所有能搜到的优化手段全部堆上去。 之前接触过一个团队,为了把LCP压到2秒以内,把整个应用的代码拆成了30多个细粒度的chunk。结果首屏加载速度确实好看了,路由切换的时候,浏览器一次性发出去几十条资源请求,点个菜单等两秒才出内容,整体体验比优化前还差。 说白了,前端首屏加载性能优化从来不是孤立的数字游戏。你用什么代价换首屏的速度,得算得明明白白。你把首屏非关键的交互组件全部延后加载,用户等首屏内容出来之后,点个折叠面板,等组件加载的1秒空白,算不算体验损失?你把所有非核心的JS全部压缩到极致,代码可读性差到后来的维护者没人敢动,每次发版都要提心吊胆,这算不算长期成本?
前端首屏加载瀑布流分析截图
很多人测性能只盯着实验室的理想环境。打开Chrome的Performance面板,把所有首屏之外的资源全部block掉,算出来LCP能到1.2秒,觉得交差了。 可真实的线上环境哪有这么理想。 地铁里刷网页的。 公司网被同部门同事占满带宽的。 老旧手机开着十几个后台APP的。 你在满速4G环境下测出来的漂亮数值,到了真实用户的场景里,根本站不住脚。

容易被忽略的隐性成本

之前碰到个做电商活动页的团队。为了把首屏速度提上来,把所有营销弹窗、优惠券领取组件全部做成异步加载。一开始测出来的LCP确实从3.8秒降到1.6秒,数据漂亮得很。 结果上线一周,优惠券的领取转化率掉了12%。 为啥?因为用户进页面之后,等异步组件加载的那0.8秒,已经顺着页面滑到下面的商品区了。弹窗弹出来的时候,根本挡不住用户的视线,自然没人点。 这就是隐性的代价。你为了首屏的那零点几秒速度,把本来能直接触达用户的功能给延后了,最后业务数据掉了,锅还是要前端来背。 还有的团队为了压资源体积,把首屏用的网页字体过度压缩,字重丢了不说,小字号下的文字边缘全是锯齿,用户盯着看两分钟就累得慌。还有的人把SSR直出当万能解法,把所有用户的个性化数据全部塞进首屏HTML里,HTML体积干到2M多,传输是快了,浏览器解析DOM的时候主线程卡半天,白屏时间反而更长。
前端首屏资源加载优先级对比示意图
前端首屏资源加载优先级对比示意图
很多人觉得代码分割越细越好。把每个小组件都拆成独立的包,觉得这样首屏加载的资源少。麻烦在于,拆的越细,HTTP请求的数量就越多。在弱网环境下,每个请求的TCP握手开销叠起来,比把几个相邻的组件打在一个包里还慢。 这事没那么玄。你不用追着最新的技术概念跑,先去看看真实用户的网络分布,看看有多少用户是在2G、3G环境下打开你的网站,再决定要不要拆那么细的包。

别为了指标牺牲真实体验

现在很多团队的性能考核,就盯着几个冷冰冰的核心指标。LCP够不够快,FID够不够低,CLS够不够稳,数值达标就算完事。 但真实用户的感受,从来不是这些数字能完全代表的。 我上次打开个资讯类网站。 首屏文章标题1.8秒就出来了。 我刚准备点进去看个开头。 啪的一下,顶部加载出来个通栏广告,把整个标题顶到屏幕外面去了。 就这操作,你就算把所有性能指标都刷到满分,用户下次也不会再来。 做优化之前,最先要搞清楚的,从来不是什么技术手段最先进,而是你的用户进来之后,第一时间最想看到什么。把这部分资源的加载优先级拉到最高,剩下的内容,哪怕晚个一两秒加载,也没人会在乎。 比如你做个文档站,用户进来就是想找文档内容,那你把文档正文的文字、核心样式优先加载,导航栏的动态效果、侧边栏的推荐内容晚个几百毫秒加载,完全不影响。反过来,如果你把导航栏的动效资源放在最前面加载,正文的JS包被堵在请求队列后面,就算你每个包的体积都压到几百KB,用户也要盯着白屏等半天。 不过话说回来,我见过最离谱的操作,是为了优化首屏,把整个页面的首屏内容全部转成base64编码塞在CSS里。是,资源请求是少了,但是CSS文件干到1.5M,浏览器解析CSS的时候主线程直接被占满,点个按钮都没反应。你说这算优化还是算拆台? 很多人喜欢预加载、预请求。什么资源都prefetch、preload。结果把本来要用来加载核心内容的带宽全部占了,核心资源反而慢了。说白了,这些手段都是工具,不是你堆的越多就越好。你得算清楚,在你的用户场景里,哪些资源是真的需要提前加载的,哪些是锦上添花的。 别被那些堆术语的优化文章吓住。你去真实的用户场景里待两天,看看用户到底在什么网络下打开你的网站,看看他们进来之后最先点什么,比你对着十几种优化方法挨个试有用的多。 对了,上次帮朋友改的那个老项目。我们没上什么复杂的SSR,也没拆几十上百个chunk。就把首屏的3张轮播图压到原来的1/3大小,把非首屏的图表库延后加载,把本来要放在首屏的弹窗组件挪到用户滚动到对应位置再加载。改完之后,真实用户的首屏平均加载时间从4.2秒降到1.8秒。 没有什么魔法。 就是把之前被浪费的带宽,全部让给用户真正想看的内容而已。