开篇
目前团队内的项目所使用的技术为 SPA
单页面应用(React
)客户端方式渲染。
客户端渲染
方式相较于服务端渲染
,能够轻松实现局部渲染效果(无需请求完整页面),用户体验更好。
但客户端渲染也存在一个很大的弊端
:首屏加载缓慢,因为要等待 JS 主文件资源加载完毕后,执行 render
渲染页面,这样就会造成等待白屏
时间太长。
这对于一个产品化的应用来说,面对大量的用户,若打开应用白屏时间过长,非常容易造成用户流失。
对于 首屏渲染优化
的思路和方法网上资料也有很多,下面,笔者将自己在公司产品项目上所做的首屏优化实践分享于大家。
1.延迟(动态)加载 辅助 资源;
2.页面路由按需加载;
3.代码分割(打包层面);
4.静态图片资源采用 cnd 方式。
一、延迟(动态)加载 辅助 资源
通常,在 HTML 文件中除了要引入应用程序的打包资源,可能还会涉及引入其他功能脚本
资源。
比如,公司内有一个云文件应用,里面的文件需要支持进行预览,而预览的具体实现是在一个独立的工程中,提供脚本文件来覆盖使用所有产品化预览场景。
这时候,云文件应用就需要引入预览相关的 JS 资源,在点击文件时,调用预览 API 进行预览。
最初,预览资源是在主程序的打包资源之前引入的。我们都知道 script
标签会同步执行并阻塞后面的资源加载,这就会导致主程序的资源被延后加载
,从而增加了白屏
时长。
其实在初始化时加载预览资源
可能意义不大(除非是程序初始化后立刻预览一个文件),在我们这个场景下,云文件应用初始化后进入首页,显示的是文件列表,只有用户点击列表中的文件后,开始进行预览。
那我们其实可以借助 JS 动态创建标签
的方式,将预览资源的加载时机移动在点击文件时(仅在第一次预览时动态加载资源),这样,就不会影响主应用的资源加载,减少白屏时长。
对于 动态加载资源
,你的代码实现可能如下:
const usePreviewApi = () => {const loadResourceFlag = useRef<{ [key: string]: boolean }>({ css: false, js: false });...const seePreview = (previewParams: SeePreviewParams) => {// 避免重复的加载if (Object.keys(loadResourceFlag.current).some(key => loadResourceFlag.current[key])) return;// 第一次加载预览资源if (!window.JwP