0
点赞
收藏
分享

微信扫一扫

【前端性能优化】如何应对首屏加载白屏?


目录

  • ​​1. 骨架屏​​
  • ​​1.1 绘制静态骨架屏​​
  • ​​1.2 代码绘制骨架屏​​
  • ​​1.3 自动化解决方案​​
  • ​​2. 使用动态的Polyfill​​
  • ​​3. 代码分割​​
  • ​​4. 使用资源预加载​​


前言

随着Vue、React等框架的出现,SPA单页面应用越来越多,多数的SPA应用的结构都很类似。由于SPA页面打包之后的JavaScript文件非常大,等这个巨大的JavaScript文件加载完之后,首屏才能渲染,这就导致出现了白屏的问题。还有在移动端,一些需要快速迭代的开发项目都是使用HTML5开发的,同样首屏加载白屏问题非常的严重。

下面就来看一下针对首屏渲染白屏的解决方案。

1. 骨架屏

骨架屏就是指在未加载完时,先简单的用图形勾勒出页面的大概布局,给用户一个视觉上更好一点的体验,等页面加载完成之后,再将骨架屏替换掉即可,如下图所示:

【前端性能优化】如何应对首屏加载白屏?_css

实现骨架屏的方式有很多种,下面来看下常见的几种。

1.1 绘制静态骨架屏

最直接的实现方案就是直接绘制一张骨架屏的图片,在资源加载完毕之后,页面内容直接替换这张图片即可。我们知道base64格式的图片可以直接插入到HTML文档中,并且可以节约一次HTTP请求,所以我们可以把骨架屏的静态图片直接转化为base64格式插入到HTML文件中。

我们可以监听​​onLoad​​​事件,只要他完成之后,将图片替换掉即可。如果是Vue项目,我们可以在​​mounted()​​钩子中替换掉这张图篇。

1.2 代码绘制骨架屏

通过代码绘制骨架屏会比绘制静态图片更加灵活,可定制化程度高。我们可以根据自己的需要,绘制需要的样式。只需要根据首屏的大致轮廓绘制一个对应HTML结果,再用CSS填充上合适的背景色即可。

除此之外,我们还可以通过改动CSS,为这个骨架图添加一些动态的效果(加载动画),这样用户体验会更好。

1.3 自动化解决方案

如果我们需要给多个页面添加骨架图,那么就需要绘制多个骨架图,这样就比较麻烦。不过,现在已经有以下比较成熟的解决方案,目前使用比较广泛的是 ​​page-skeleton-webpack-plugin​​插件,该插件是一个webpack插件,可以根据具体的页面生成对应的骨架屏,使用起来非常方便。

具体使用方法可以在github查看:​​page-skeleton-webpack-plugin​​

除此之外,Ant Design也提供了骨架屏的方案:​​Skeleton骨架屏​​

2. 使用动态的Polyfill

先来看一下Polyfill是干嘛用的:

全世界有许多不同的浏览器和版本的浏览器在使用,每种浏览器都具有与其他浏览器完全不同的功能集。这会使浏览器开发成为一项艰巨的任务。流行浏览器的最新版本可以完成许多旧浏览器无法完成的任务-但是您可能仍必须支持旧浏览器。通过尝试使用polyfills重新创建缺少的功能,Polyfill.io使其更容易支持不同的浏览器:您可以在支持和不支持的浏览器中利用最新和最强大的功能。

简单来说,就是Polyfill可以为就得浏览器提供和标签API一样的功能,无需引入插件,只要引入一个JS文件即可。

然而我们现在为了所有手机的都能够顺利跑起来项目,引入的 Polyfill 非常多。基于这种情况我们完全可以使用动态Polyfill来代替我们现有的比较笨重的兼容方式。动态Polyfill使用方法也非常简单,我们只需要引入一个​​<script>​​ 标签即可:

<script src="https://polyfill.io/v3/polyfill.min.js"></script>

这样就保证了 polyfill 在我们需要的时候才会加载。如果对自己需要的 polyfill 比较清楚,也可以自己勾选需要的那部分,这样加载速度会更快。如下:

【前端性能优化】如何应对首屏加载白屏?_前端性能优化_02


上图中勾选的三个,对应的script标签如下:

<script src="https://polyfill.io/v3/polyfill.min.js?features=es2015%2Ces2016%2Ces2017"></script>

注意:动态 Polyfill 是通过判断浏览器的 UA头,然后根据不同的浏览器选择其对应需要的 Polyfill。

3. 代码分割

最上面说到了由于打包的JavaScript文件很大,导致的首屏加载速度不理想,那么就可以从这方面下手,对代码进行分割,

代码分割:

代码分割指的是将项目代码构建打包之后,根据指定规则分割成多个输出文件,这些文件可以被按需加载或者并行加载,可以用来优化代码加载时的资源大小以及优先级。正确的使用代码分割可以提升资源加载效率。

具体的代码分割方案是在webpack进行配置,这里先不做解释。之后再写webpack优化的时候在介绍吧~

对于分割的代码我们可以进行按需加载,最常用的就是ES6中的​​import()​​方法,在Vue项目中,我们经常用到的就是路由的按需加载。

4. 使用资源预加载

先来看一下MDN中关于资源预加载的解释:

页面资源预加载(Link prefetch)是浏览器提供的一个技巧,目的是让浏览器在空闲时间下载或预读取一些文档资源,用户在将来将会访问这些资源。一个 Web 页面可以对浏览器设置一系列的预加载指示,当浏览器加载完当前页面后,它会在后台静悄悄的加载指定的文档,并把它们存储在缓存里。当用户访问到这些预加载的文档后,浏览器能快速的从缓存里提取给用户。

简单来说就是当页面加载完成后或者其他空闲的时间,我们可以加载之后页面中用到的资源。

(1)rel="preload"

我们可以使用​​rel​​​属性,​​<link>​​​ 元素的 ​​rel​​​ 属性的属性值​​preload​​​能够让你在你的HTML页面中 ​​<head>​​元素内部书写一些声明式的资源获取请求,可以指明哪些资源是在页面加载完成后即刻需要的。

<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">

这样,我们预加载了css和js文件,在随后的页面渲染的时候,如果需要使用这两个文件,直接使用即可,因为已经缓存好了。不仅是这些文件可以预加载,字体,图片,音视频文件都可以进行预加载。

(2)rel="subresource"

除此之外,我们还可以使用 ​​subresource​​ 属性。subresource 和 preload 属性相比,它的优先级是最高的,使用方法和 preload 基本相同,如下:

<link rel="subresource" href="styles.css">

因此,如果我们的资源需要马上用到或者是当前页面急需的资源,我们就可以使用subresource。当然在实际的开发当中 preload 属性用的较多一些

(3) rel="prerender"

​prerender​​ 可以指定加载一个页面的所有资源,使用方法如下:

<link rel="prerender"  href="/result.html" />

​prerender​​ 的效果就和我们默认打开了一个隐藏的 tab 一样,会下载所有的资源、创建 DOM、渲染页面、执行 JS等等。如果用户进入指定的链接,隐藏的这个页面就会进入马上进入用户的视线。

这个属性虽然强大,但是却不能乱用,一定要确定这个页面用户的确会进行点击,才可以进行设置。否则用户不点,我们就浪费了大量的宽带资源去下载了一个无用的页面,这样反而得不偿失。

最后

关于首屏渲染白屏的解决方案还有很多。但是,归根结底,最主要的是对需要加载的资源进行优化,只要资源加载的足够快,首屏问题就解决了。我们可以借鉴​​《雅虎35条军规》​​中的原则,例如开启CDN、进行gzip压缩、对图片进行处理、懒加载等,都可以对首屏问题进行一定的优化。


举报

相关推荐

0 条评论