SPA 中的骨架屏预加载技巧

在现代 Web 开发中,单页面应用(Single Page Application,SPA)的兴起让用户体验得到了很大的提升。然而,SPA 的局部刷新却也带来了一个新的问题——页面应用的首屏加载过程变得更加复杂和缓慢。这时,骨架屏(Skeleton Screen)的出现,为解决这一问题提供了一个非常好的解决方案。

骨架屏是一种过渡状态的 Web 页面,通常使用大量占位符元素填充页面,用于提供用户的阅读体验,以代替由前端框架初始化渲染所带来的白屏等待时间。下面,本文将为大家介绍 SPA 中的骨架屏预加载技巧,帮助你提升 Web 网站的用户体验。

预备知识

在开始本文之前,我们需要先了解一些基础知识。

React

React 是 Facebook 意欲提供高性能、易用并轻量级的 JavaScript 框架,目前被广泛应用于前端应用的构建。React 通过构建可重用和可组合的 UI 组件和 Abstraction,尽可能简化了 JavaScript 应用的开发流程。

Ant Design

Ant Design 是一套基于 React 的企业级 UI 设计语言和组件库,其提供了丰富的可自定义的 React UI 组件、比较标准的设计规范和良好的文档。

骨架屏

骨架屏属于前端优化方案的一种,其通过一套专有的算法和模板,将页面初次加载时所关联的元素以及其样式信息预先定义出来。当页面渲染时,骨架屏所预先定义的样式和白色占位符被替换为实际的内容,用户体验得到了大大的提升。

SPA 中的骨架屏预加载

下面我们将为大家介绍 SPA 中使用骨架屏预加载的技巧,为您提升 Web 站点的用户体验。

1. 抽象公用骨架屏组件

我们首先需要定义一个骨架屏模板,并将其抽象成一个公用的组件,以在整个应用中都可以共享。

------ ------ - -------- - ---- --------
------ - -------- - ---- -------

----- ---------- - -- -- -
  ----------
    --------- ------ --
  -----------
--

------ ------- -----------

2. 通过预取数据初始化骨架屏

现实中请求后端接口是不可避免的,我们可以从后端得到需要渲染的数据,然后在组件挂载前先渲染骨架屏并发起网络请求,等待数据返回,在未获取到数据时使用“骨架屏”代替数据。下面展示了一个未优化的渲染方式,下一步讲解中你将会看到优化后的更新骨架屏方法。

------ ----- ---- --------
------ --- ---- -----------------
------ ---------- ---- ---------------------------

----- ------ ------- --------------- -
  ------------------ -
    -------------
    ---------- - -
      ----- ---
    --
  -

  ------------------- -
    ----------------------- -- -
      ---------------
        -----
      ---
    ---
  -

  -------- -
    ----- - ---- - - -----------
    ------ -
      ---- -----------------
        ------------ - -
          ----
            -------------- -- -
              --- --------------
                ---------------------
                ------------------
              -----
            ---
          -----
        - - -
          ----------- --
        --
      ------
    --
  -
-

------ ------- -------

3. 使用代理对象更新骨架屏

更新骨架屏最重要的一步就是寻找一个依赖充足的代理对象来承载,我们可以在内存中开辟一块空白区域,将新数据(真实数据)和骨架屏对象动态绑定在内存上,然后通过代理模式去代理内存空间里面的值,在请求到真实数据之前所有的 getter 方法数据都会返回“骨架屏”的内容,在请求到真实数据之后,会访问到真实数据。

修改上一个步骤中的代码:

------ ----- ---- --------
------ --- ---- -----------------
------ ---------- ---- ---------------------------

----- ----------- - ---------------------------- -- -
  ------ -
    --- -----------------
    ------ --------------------
    ----- -------------------
  --
---

----- ------------------- - -------------- -- -
  --- ------ - ---
  ----- ------------ - ----------------------- -- -
    ------ --- ------
      - ------- --
      -
        ----------- -------- --------- -
          -- ------- ------------------- -------- --------- --- --------- -
            ------ --------------- -- -------------
          -
          ------ -------------
        --
      -
    --
  ---
  --------------------------- ------ -- -
    ------ - - ---------- ---------------- ---- --
  ---
  ------ -------
--

----- ------ ------- --------------- -
  ------------------ -
    -------------
    ----- ----- - -
      -------- --------------------- ----- ----------- ---
    --
    ---------- - ------
  -

  ------------------- -
    ----------------------- -- -
      ----- ------- - --------------------- ---- ---
      ---------------
        --------
      ---
    ---
  -

  -------- -
    ----- - ------- - - -----------
    ------ -
      ---- -----------------
        ----
          ------------------------- -- -
            --- --------------
              ---------------------
              ------------------
            -----
          ---
        -----
      ------
    --
  -
-

------ ------- -------

这个优化方案看起来有点复杂,但是我们可以将 wrapperWithSkeleton 函数简化,在这个函数中,我们新建一个 obj 对象,然后通过 Object.entries(...propsList).forEach() 来更新这个对象,将这个对象返回即可。

----- ------------------- - -------------- -- -
    ----- --- - ---

    ---------------------------------------- ------- -- -
        -------- - --- ------
            - -------- --
            -
                ----------- -------- --------- -
                    -- ------- ------------------- -------- --------- --- --------- -
                        ------ --------------- -- -------------
                    -
                    ------ -------------
                --
            -
        --
    ---

    ------ ----
-

最后,我们将所有的数据结构配置都改成对象格式即可:

----- ----------- - ---------------------------- -- -
    ------ -
        --- -----------------
        ------ --------------------
        ----- -------------------
    --
---

----- ------ - -- -- -
    ----- --------- ----------- - ------------------------------ ----- ----------- ----

    ------------ -- -
        ----------------------- -- -
            ----- ------- - --------------------- ---- ---
            --------------------
        ---
    -- ----

    ------ -
        ---- -----------------
            ----
                ------------------------- -- -
                    --- --------------
                        ---------------------
                        ------------------
                    -----
                ---
            -----
        ------
    --
--

总结

通过代理模式,我们已经成功地利用骨架屏技术优化了单页面应用中的页面加载速度和用户体验。值得注意的是,本文中只是介绍了一种骨架屏预加载的技巧,但实际应用中还有很多优化方法与技巧,希望各位开发者可以进一步研究和应用。谢谢阅读!

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/664d6b39d3423812e4cfaa66