Practice 2: DPS (Draw-Page-Structure)

Premise Background:

Vue-skeleton-webpack-plugin generates the corresponding skeleton screen through pre-rendering manually written code, and renders the written Vue skeleton screen components during construction through vueSSR and webPack. The DOM nodes and related styles generated by pre-rendering are inserted into the final output HTML, and then the DOM nodes required by the skeleton screen are generated by pre-rendering, but this scheme is not flexible and controllable. Therefore, the scheme of skeleton screen injection (above) of Vue2. X project is optimized — automatic generation of webpage skeleton screen (DPS).

DPS procedure

1. Install DPS

npm i draw-page-structure -D
Copy the code

2. Add the page that needs to generate skeleton screen in a specific page:

mounted() {
    // Note: after generating the skeleton screen, paste the skeleton screen code into the vue file, the following code needs to comment out, otherwise generate HTML insert page every time
    setTimeout(() = > {
        createSkeletonHTML({
        // This code is actually invalid
            background: 'red'.animation: 'opacity 1s linear infinite; '
        }).then((skeletonHTML) = > {
        // This output is the skeleton screen node, you can customize the skeleton screen node content
            console.log(skeletonHTML);
        }).catch((e) = > {
            console.error(e);
        });
    }, 5000);
},
Copy the code

3,npm run devAfter running in the browser, you can output the skeleton screen node of the current page on the console, copy and add it to the application page, for example:

src/commercialActivity/index.vue

<template lang="html">
    <div class="commercialActivity">
    <! Transition -->
        <transition name="skeleton">
            <div v-if="showSkeleton">
            <! -- Skeleton screen node -->
                <div class="_ __" style="height:100%; z-index:990; background:#fff"></div><div class="_" style="Height: 2.099%; Top: 3.748%; Left: 6.667%; Width: 73.667%."></div><div class="_" style="Height: 2.099%; Top: 3.748%; Left: 81.067%; Width: 12.267%."></div><div class="_" style="Height: 1.799%; Top: 8.096%; Left: 6.667%; Width: 34.492%."></div><div class="_" style="Height: 1.799%; Top: 8.096%; Left: 74.133%; Width: 19.200%."></div><div class="_" style="Height: 4.498%; Top: 14.768%; Left: 9.333%; Width: 7.467%."></div><div class="_" style="Height: 2.249%; Top: 15.967%; Left: 26.975%; Width: 40.000%."></div><div class="_" style="Height: 2.249%; Top: 15.892%; Left: 69.333%; Width: 4.000%; border-radius:50%"></div><div class="_" style="Height: 2.099%; Top: 15.967%; Left: 76.000%; Width: 16.000%."></div><div class="_" style="Height: 2.249%; Top: 27.361%; Left: 1.867%; Width: 3.950%."></div><div class="_" style="Height: 10.195%; Top: 23.388%; Left: 8.483%; Width: 17.908%."></div><div class="_" style="Height: 2.249%; Top: 23.763%; Left: 29.058%; Width: 66.938%."></div><div class="_" style="Height: 2.399%; Top: 26.912%; Left: 30.125%; Width: 6.400%; border-radius:2px"></div><div class="_" style="Height: 1.799%; Top: 27.211%; Left: 74.246%; Width: 21.750%."></div><div class="_" style="Height: 2.249%; Top: 30.960%; Left: 29.058%; Width: 66.938%."></div><div class="_" style="Height: 2.399%; Top: 37.031%; Left: 40.858%; Width: 12.800%."></div><div class="_" style="Height: 1.150%; Top: 37.830%; Left: 55.942%; Width: 3.200%."></div><div class="_" style="Height: 2.849%; Top: 42.429%; Left: 35.067%; Width: 29.867%."></div><div class="_" style="Height: 2.249%; Top: 95.610%; Left: 1.867%; Width: 4.000%."></div><div class="_" style="Height: 6.447%; Top: 93.403%; Left: 6.975%; Width: 6.400%."></div><div class="_" style="Height: 6.447%; Top: 93.403%; Left: 73.333%; Width: 26.667%."></div>
            </div>
        </transition>.</div>
</template>
<style>. _ {position:fixed
z-index:999; <! -- Because in the createSkeletonHTML method,background: 'red'< span style = "box-sizing: border-box; color: RGB (51, 51, 51); line-height: 22px; font-size: 14px! Important; word-break: inherit! Important;"#efefef; Payable}. {top:0%;
left:0%;
width:100%;
}
</style>
Copy the code

app.styl

// Skeleton transition
.skeleton-enter-active
  transition opacity .6s
.skeleton-enter
  opacity 0
.skeleton-leave-active
  transition opacity .6s
.skeleton-leave-to
  opacity 0
  
Copy the code

The skeleton is displayed before the page is rendered, i.e. the interface is not returned, and the interface returns the skeleton hidden. Note the code that generates the skeleton screen in Mounted. Otherwise, a skeleton screen node is automatically generated after each page is run. Multiple skeleton screens overlap each other.

src/commercialActivity/commercialActivity.js

data() {
        return {
            showSkeleton: true.// Whether to display the skeleton}}methods: {
        // Scroll down to load
        infinite(val) {
            return _.debounce(() = > {
            // Where the interface is requested
                this.getProductInfo({
                    activity_id: this.activityId,
                    page: this.listQery.page,
                    ser: val ? val.search : ' '
                }).then(() = > {
                // Interface returns skeleton hide
                    this.showSkeleton = false;
                    if (!this.errorType.type) {
                        this.$refs.infiniteLoading.stateChanger.loaded();
                    } else {
                        this.$refs.infiniteLoading.stateChanger.complete();
                    }
                    if (this.hasMore) {
                        this.distance = -Infinity;
                    } else {
                        this.$refs.infiniteLoading.stateChanger.complete();
                    }
                }).catch((err) = > {
                // Interface returns skeleton hide
                    this.showSkeleton = false;
                    console.log(err);
                });
                if (this.isAllChecked) {
                    this.isAllChecked = true; }},500); }},Copy the code

4, DPS is to generate the skeleton of the currently visible page. The rules of DPS design are as follows:

    1. Only the DOM nodes visible in the visible area are traversed, including: non-hidden elements, elements larger than 0, non-transparent elements, elements whose content is not a space, elements located in the visible area of the browsing window, etc.
    1. Generate color blocks for (background) images, text, form items, audio and video, Canvas, custom feature blocks and other areas;
    1. You can use getBoundingClientRect to obtain the absolute values of the node width, height, and distance from the viewport, and calculate the percentage corresponding to the width and height of the current device as the unit of the color block to adapt to different devices

5, Because the DPS generated page skeleton is run in the page node, rather than the first screen skeleton in index.html, the interaction is seen as seeing ‘.White screen -> Page skeleton -> Normal page‘, the actual DPS is simply code that generates the skeleton of a page. So in the front screenindex.htmlPage to joinloading(For details, it depends on whether the project requires first-screen loading) :

<body>
    <div id="app">
        <! -- The style is written here so that when the page comes in, everything in the app will be replaced -->
        <style>
            #app {
              height: 100%;
              margin: 0px;
              padding: 0px;
            }
            #loader-wrapper {
              position: fixed;
              top: 0;
              left: 0;
              width: 100%;
              height: 100%;
            }
            #loader {
              display: block;
              position: relative;
              left: 50%;
              top: 50%;
              width: 150px;
              height: 150px;
              margin: -75px 0 0 -75px;
              border-radius: 50%;
              border: 3px solid transparent;
              border-top-color: red;
              -webkit-animation: spin 2s linear infinite;
              -ms-animation: spin 2s linear infinite;
              -moz-animation: spin 2s linear infinite;
              -o-animation: spin 2s linear infinite;
              animation: spin 2s linear infinite;
            }
            #loader:before {
              content: "";
              position: absolute;
              top: 5px;
              left: 5px;
              right: 5px;
              bottom: 5px;
              border-radius: 50%;
              border: 3px solid transparent;
              border-top-color: red;
              -webkit-animation: spin 3s linear infinite;
              -moz-animation: spin 3s linear infinite;
              -o-animation: spin 3s linear infinite;
              -ms-animation: spin 3s linear infinite;
              animation: spin 3s linear infinite;
            }
            #loader:after {
              content: "";
              position: absolute;
              top: 15px;
              left: 15px;
              right: 15px;
              bottom: 15px;
              border-radius: 50%;
              border: 3px solid transparent;
              border-top-color: red;
              -moz-animation: spin 1.5 s linear infinite;
              -o-animation: spin 1.5 s linear infinite;
              -ms-animation: spin 1.5 s linear infinite;
              -webkit-animation: spin 1.5 s linear infinite;
              animation: spin 1.5 s linear infinite;
            }
            #loader-wrapper .fengche-logo {
              display: block;
              position: absolute;
              left: 50%;
              top: 50%;
              width: 60px;
              height: 60px;
              margin: -30px 0 0 -30px;
            }
            #loader-wrapper .fengche-logo img {
              width: 100%;
            }
            @-webkit-keyframes spin {
              0% {
                -webkit-transform: rotate(0deg);
                -ms-transform: rotate(0deg);
                transform: rotate(0deg);
              }
              100% {
                -webkit-transform: rotate(360deg);
                -ms-transform: rotate(360deg);
                transform: rotate(360deg); }}@keyframes spin {
              0% {
                -webkit-transform: rotate(0deg);
                -ms-transform: rotate(0deg);
                transform: rotate(0deg);
              }
              100% {
                -webkit-transform: rotate(360deg);
                -ms-transform: rotate(360deg);
                transform: rotate(360deg); }}</style>
        <div id="loader-wrapper">
        <div id="loader"></div>
        <div class="fengche-logo">
            <img src="data:image/gif;base64,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" />
        </div>
        </div>
    </div>
    <! -- built files will be auto injected -->
</body>
Copy the code

After running, the page interaction is as follows: First screen loading-> Page skeleton screen -> Normal UI interaction after data request returns.

6, when used in the projectHand wash lib - flexibleorPx is processed by REMAnd use someUI framework, e.g.vant, then using DPS, directly generated % skeleton screen, is not applicable, you need to customize the skeleton screen,Let's do % to rem, so that the skeleton screen UI interaction of the page is normal

mounted() {
    setTimeout(() = > {
    /* This is a custom skeleton screen, processing % to REM, project root font size =37.5px */
            createSkeletonHTML({}).then(skeletonHTML= > {
                // It is better to customize a larger height ratio, compatible with a variety of longer screens, such as 375 * 1000 (iphoneX-375 * 812)
                const skeletonWidth = document.body.clientWidth // Screen width
                const skeletonHeight = document.body.clientHeight // Screen height
                const skeletonTop = 0 // Width :375px, not including header 44px
                let cacheHtml = JSON.parse(JSON.stringify(skeletonHTML))
                cacheHtml = cacheHtml.replace(/<style>\S+<\/style>/.' ') // Remove the style and extract it to public
                // Convert the percentage to rem: height(px) = val * clientHeight/100
                cacheHtml = cacheHtml.replace(/height:\d*\.*\d*%/g.(val) = > {
                    return `height:${(skeletonHeight * val.slice(7, -1) / 3750).toFixed(6)}rem`
                })
                cacheHtml = cacheHtml.replace(/top:\d*\.*\d*%/g.(val) = > {
                    return `top:${(skeletonHeight * val.slice(4, -1) / 3750).toFixed(6)}rem`
                })
                cacheHtml = cacheHtml.replace(/left:\d*\.*\d*%/g.(val) = > {
                    return `left:${(skeletonWidth * val.slice(5, -1) / 3750).toFixed(6)}rem`
                })
                cacheHtml = cacheHtml.replace(/width:\d*\.*\d*%/g.(val) = > {
                    return `width:${(skeletonWidth * val.slice(6, -1) / 3750).toFixed(6)}rem`
                })
                console.log('First screen skeleton :', cacheHtml)
                // skeleton screen capture, remove the header44px(375px below the screen width)+ custom skeletonTop
                const skeletonCutTop = (skeletonTop + 44) / 37.5
                cacheHtml = cacheHtml.replace(/<div class="_" style="\S+<\/div>/g.(val) = > {
                    let isCut = true
                    val = val.replace(/top:\d*\.*\d*rem/g.(topRem) = > {
                        if (topRem.slice(4, -3) < skeletonCutTop) {
                            isCut = false
                            return topRem
                        }
                        return `top:${(topRem.slice(4, -3) - (44 / 37.5)).toFixed(6)}rem`
                    })
                    return isCut ? val : ' '
                })
                // Frame screen background capture + scroll down
                cacheHtml = cacheHtml.replace(/<div class="_ __" style="\S+<\/div>/g.(val) = > {
                    return `<div class="_ __" style="height:${((skeletonHeight - skeletonTop) / 37.5) toFixed (6)} rem, top:${(skeletonTop / 37.5).toFixed(6)}rem; z-index:990; background:#fff"></div>`
                })
                // Handle header hiding in wechat environment
                cacheHtml = `<div class="skeleton-box"><div :class="[$store.getters.isWx||$store.getters.isApp?'':'not-wx','skeleton-content']">${cacheHtml}</div></div>`
                console.log('Page skeleton :', cacheHtml)
            }).catch(e= > {
                console.error(e)
            })
        }, 8000)}Copy the code

Note 1:

Lib-flexible solution limit font size maximum 54px; Max-width :1280px; Word-wrap: break-word! Important; word-wrap: break-word! Important;

function refreshRem(){
    var width = docEl.getBoundingClientRect().width;
    if (width / dpr > 1280) {
        width = 1280 * dpr;
    }
    var rem = width / 10;
    docEl.style.fontSize = rem + 'px';
    flexible.rem = win.rem = rem;
}
Copy the code

Note 2:

The vant component at the top, like a search box, is not covered by a skeleton

const skeletonTop = 48 // Where the skeleton screen should be cut from (width:375px)
Copy the code

Note 3:

The vant component also needs to go to rem, postcss.config.js instead:

module.exports = ({ file }) = > {
    let remUnit
    if (file && file.dirname && file.dirname.indexOf('vant') > -1) {
        remUnit = 37.5
    } else {
        remUnit = 75
    }
    return {
        plugins: {
            'postcss-px2rem-exclude': {
                remUnit,
            }
        }
    }
}
Copy the code

Note 4:

General static page is not skeleton screen, because there is no interface request, its loading speed is very fast, there is no need for skeleton screen, and skeleton screen is also a static, just to have a request to improve the interactive experience!