关于vue.js:????Killblanks-使用预渲染和骨架屏解决前端白屏问题

前言

白屏始终是CSR我的项目诞生来困扰前端的一大问题,如何在低成本的状况下,减少用户的等待时间,缩小跳出率,以及进步页面性能,是前端始终在解决的难题,killblanks 作为其中一种的解决方案,将页面节点间接生成骨架屏,通过预渲染让用户能在期待内容加载时显示内容的轮廓,提供了更好的用户体验,并使内容感觉更快。

白屏是怎么产生的

这是一个一般CSR我的项目的Chrome performance截图,能够从快照中看到,白屏的工夫大概在330ms左右,

在这段时间里页面的执行逻辑 :

  • 申请HTML -> 期待HTML文档 -> 解析HTML -> 申请JS和CSS资源 -> 执行vendors和index.js逻辑

330ms后页面呈现大体框架,页面的执行逻辑:

  • vue render各个组件 -> mounted页面挂载 -> 调用业务的API申请数据 -> 渲染返回的数据 -> 残缺的页面

正是因为CSR我的项目在期待文件加载CSSOM 构建JS 解析等过程中消耗了大量工夫,导致了用户会长工夫处于不可交互的首屏灰白屏状态,即白屏(blanks)

具体能够看看寒阳的文章构建时预渲染:网页首帧优化实际

白屏会影响什么

  • Why Web Performance Matters: Is Your Site Driving Customers Away?

通过剖析150多个网站和1.5亿次页面拜访的页面放弃数据,戈麦斯发现了游客忠诚度的匮乏,页面响应工夫从2秒减少到10秒,页面跳出率减少了38%

简略来说每减少1s页面的等待时间,对于app来说是跳出率和成交率的降落,对于老板来说就是赔钱,对于你来说就是涨不了工资

目前罕用的白屏解决方案

计划 预渲染 SSR NSR
长处 不依赖数据 SEO 敌对,构建不便,FMP比预渲染快 SEO 敌对,首屏性能高, FMP最快
毛病 SEO 不敌对,FMP 慢 老本高,前端负载压力大 老本高,客户端压力大

SSR和NSR都是十分好的解决白屏的计划,然而毛病也很显著,老本太高,SSR十分依赖服务的稳定性,对于中小公司而言很少有资源能为前端提供一套稳固的服务器环境,一旦node呈现故障,损失很大,而CSR计划则是对于客户端来说老本很高,有很多不确定性。

预渲染不是银弹

基于此,预渲染可能是最简略也最理论的一种计划,但预渲染也并非是银弹,来看看咱们团队第一个版本实现的预渲染

当你高高兴兴的把辛苦做好的预渲染交给视觉视检时,可能换来的是只是一个字🙁

没错,或者说是不敌对,感觉网速很慢,这些都是看过第一个版本的共事的反馈,为什么会这样?

通过两个截图比照能够发现

    1. 图片未加载导致页面存在大面积的色块
    1. 后端的申请未返回也造成了页面的空缺甚至是框架的变形

咱们发现问题次要在元素占位上,如果能提前对元素进行占位,预渲染就能渲染出很漂亮的页面,那么有没有不便 快捷 难看的占位元素呢?

当我搜寻解决方案的时候发现,早有人提出了一种占位计划

一种自动化生成骨架屏的计划

骨架屏

是的,正是@Jocs,在18年分享了一种自动化生成骨架屏的计划,以及后续开源的page-skeleton-webpack-plugin,提供了一种老本较低的解决骨架屏的计划,为骨架屏实现形式提供一种新的思路,具体计划能够看看他的文章

比拟惋惜的是page-skeleton-webpack-plugin三年没更新保护了,尽管是一种很可行的计划,然而还有很多能进步的空间,因而我决定在page-skeleton-webpack-plugin的根底上,提供一种更不便的计划,这就是Killblanks的由来

Killblanks

2020年这个我的项目正式开始,通过半年的调试和开发,终于胜利通过abtest测试,落地上线,
并于2021年2月开源,感激每一位对此付出的人。

原理

利用Purpeteer能模仿浏览器申请页面的性能,加载谷歌插件@killblanks/skeleton-ext生成骨架屏组件的页面,直出 html 文件

框架

目前Killblanks依附lerna构建,由三个外围性能组成

  • @killblanks/prerender 提供预渲染能力,通过Purpeteer读取网页内容,直出HTML
  • @killblanks/skeleton 魔改了page-skeleton-webpack-plugin的skeleton代码,修复其中一些bug
  • @killblanks/skeleton-ext skeleton的谷歌插件,不便调试和输入骨架屏组件

应用

Killblanks应用十分不便,如果你明确其中原理,三分钟即可上手

1. 装置

  yarn add @killblanks/prerender -D

2. 配置

// webpack.config.js
const prerender = require('@killblanks/prerender')

export default {
  ...
  plugins: [new prerender()]
  ...
}
  • 具体步骤请查看@killblanks/prerender

3. 应用@killblanks/skeleton-ext

  • 具体步骤请查看@killblanks/skeleton-ext

4. 将生成的骨架屏组件应用在我的项目中

  • 比方像DEMO中所做的一样
// index.vue
<template>
  <div class="container">
    <skeleton :show="!!filterProductList.length">
      <div class="productionList">
        <div v-for="(item, key) in filterProductList" :key="item.goods_id + key" class="production">
          xxx
        </div>
      </div>
    </skeleton>
  </div>
</template>

<script>
import skeleton from './skeleton'
export default {
  components: {
    skeleton
  },
  data: () => {
    return {
      filterProductList: []
    }
  },
  mounted() {
    setTimeout(() => {
      const res = JSON.parse(
        `{"goods_id":"5e7d6d331d41c801b95f594f","name":"skeleton-test","photo":"https://o-static.ihago.net/ikxd/e62403ac0d365c57b4dbc1a0ab7e9cf4/128.png","svga_photo":"","tag":"new","type":1,"type":1805,"real_price":199,"price":299,"discount":8000,"update_time":1594695268}`
      )
      this.filterProductList = Array(10).fill(res)
    }, 3000)
  }
}
</script>
// skeleton.vue
  <script>
import Vue from 'vue'
const skeletonLoader = {
  name: 'skeletocnLoader',
  functional: true,
  props: {
    show: {
      type: Boolean,
      default: false
    }
  },
  render(h, context) {
    const { show } = context.props
    if (!show || window.__PRERENDER_INJECTED__) {
      const html = `<div>xxx</div>`
      const component = Vue.compile(html)
      return h(component)
    } else {
      return context.children[0]
    }
  }
}
export default skeletonLoader
</script>

5. 在浏览器的console输出PRERENDER_SKELETON

 在Chrome console中输出`PRERENDER_SKELETON`启动骨架屏预览

最初成果

性能

最初看看abtest测试,Killblanks带来的页面性能数据上的扭转

数据起源:

利用公司在印度尼西亚上线的流动,进行 abtest 得出相干数据

数据:

type total fcp lcp
@killblanks 1532 536ms 661ms
Normal 1730 990ms 993ms

First-contentful-paint(fcp)

  • FCP 平均值比照:536 : 990 @killblanks 能晋升454ms, 均匀进步45%

[Largest-contentful-paint(lcp)]()

  • LCP 平均值比照:661 : 993 @killblanks 能晋升332ms, 均匀进步33.4%

将来

killblanks将来还有很多性能须要欠缺,目前正在做的

  • 单元测试
  • 优化文档
  • 反对 react && angular
  • 欠缺 demo

欢送各位前端敌人能够在issue留下本人的意见,回绝白嫖,有工夫就为killblanks点下⭐吧。

招聘

目前Joyy下Hago团队正在炽热招聘,如果你对海内市场感兴趣,前端技术够硬,就来挑战下吧,重点是团队双休,不加班!

有趣味的敌人能够间接和BOSS沟通,也能够邮件分割我 lixichen@yy.com 内推其余岗位。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理