白屏是什么
白屏时间:即用户点击一个链接或打开浏览器输入URL地址后,从屏幕空白到显示第一个画面的时间。
白屏的性能优化
1.减少包体积
- 代码压缩
- webpack中我们可以利用uglifyJsPlugin用来对JS进行压缩,从而减少js文件体积
- Tree Shaking
- 模块B中通过ES6规范引用了add方法,minus并没有引用,通过检查源码中没有引用的部分,将其删除,从而减少代码体积
// 模块 A
export function add(a, b) {
return a + b;
}
export function minus(a, b) {
return a - b;
}
// 模块 B
import {add} from 'module.A.js';
console.log(add(1, 2));
2.按需加载
最常见的一个场景,是基于路由的代码拆分。目前大多数前端都是SPA(单页面应用)。我们进入应用不需要将每一个页面的资源加载进来。我们可以通过dynamic import告诉webpack去做代码拆分。加载应用时,不需要渲染的页面可以先不加载这些页面的资源,减少lib资源的大小,缩小白屏时间,可以跳转该页面时候再加载该页面的资源。
3.合理利用浏览器缓存
白屏不仅仅是首次加载,当第二次加载时候,由于浏览器缓存的缘故,速度会快上很多,我们需要合理利用浏览器的缓存,减少白屏时间。
我们可以从下面几个角度去制定缓存策略。
- webpack的hash策略
当我们修改源码,重新编译打包时候,如果将所有文件的hash值改变,之前浏览器缓存的文件将不起作用,需要重新加载新的资源。hash分为三种:hash,chunkhash,contenthash。三种hash影响面不同,我们合理选择不同的hash。
- hash: 修改任意处代码,重新编译打包,所有文件的hash值都改变。
- chunkhash: 根据不同的entry进行以来分析,构建对应的chunk,生成对应的hash,如果某个entry修改了,仅影响该entry依赖的文件
- contenthash:每个文件的hash根据自身内容生成,当文件内容修改时,仅会影响自身的hash值,不会影响其他文件的hash
- DLL(Dynamic Link Library)动态链接库
我们的代码通常可以分为业务代码和第三方库。在我们不升级第三方库的情况下,这些动态库是不需要重新编译打包的,只需要构建我们的业务代码即可。这样可以减少编译时间,同时将第三方库缓存在浏览器,减少向server的请求。
4.代码进行合理的拆分
单页面应用里,将所有的资源打包几个bundle性能最佳。
一种情况是我们将所有的资源打包为一个js,毫无疑问,体积会非常庞大,首页加载会有很长时间的白屏,用户体验极差;如果我们将资源分割的过多,由于浏览器同域名请求的最大并发数的限制,也会有很长的白屏时间。webpack的SplitChunksPlugin提供了拆分的策略可以将资源切分为合理大小和数量的bundle。
5.合理的执行代码
- js:我们在请求接口时,最好优先请求首屏渲染的数据。看不见的数据,可以滚动时候分页加载。
- 图片资源:
- 图片icon优先使用svg
- 图片资源使用webp压缩格式,压缩效率比较高。
- 将图片分配到多个cdn域名,由于浏览器同一个域名的连接数限制,减少阻塞时间。
- 使用图片懒加载模式,具体做法src属性先加载默认图,利用# IntersectionObserver这个api检测图片资源在可视区域时,将图片的真实地址赋值给src。
总结
我们想要给用户更好的用户体验,减少第一次白屏时间和第二次白屏时间,我们可以从打包资源,http协议,浏览器缓存,代码的执行不同角度进行优化。