Preface
White screens have always been a major problem that has plagued the front-end when the CSR project was born. How to increase the waiting time of users, reduce the bounce rate, and improve the page performance under the condition of low cost is the front-end has been solving problems. This kind of solution directly generates a skeleton screen from the page node, and pre-renders the user to display the outline of the content while waiting for the content to load, providing a better user experience and making the content feel faster.
How does the white screen come about
This is a screenshot of the Chrome performance
of a normal CSR project. As you can see from the snapshot, the time for the white screen is about 330ms.
The execution logic of the page during this time:
- Request HTML -> Wait for HTML document -> Parse HTML ->
Request JS and CSS resources
->Execute vendors and index.js logic
After 330ms, the page appears in a general frame, the execution logic of the page:
-
vue render each component
->mounted page mount
-> call the business API request data -> render the returned data -> complete page
It is precisely because the CSR project spends a lot of time in the processes of waiting for file loading
, CSSOM construction
, JS parsing
, etc., that the user will be in a state of gray and white screens that are not interactive for a long time, that is, blanks.
For details, please see the article of Hanyang Pre-rendering during construction: Practice of first frame optimization of web pages
What will the white screen affect
By analyzing more than 150 websites and page abandonment data of 150 million page visits, Gomez discovered the lack of visitor loyalty. The page response time increased from 2 seconds to 10 seconds, and the page bounce rate increased by 38%.
To put it simply, each additional 1s of page waiting time is a decrease in the bounce rate and transaction rate for the app. For the boss, it is "losing money", and for you, it is impossible to increase the salary.
Currently commonly used white screen solutions
Scheme | Pre-rendering | SSR | NSR |
---|---|---|---|
Advantages | Does not rely on data | SEO friendly, easy to build, FMP is faster than pre-rendering | SEO friendly, high first screen performance, FMP is the fastest |
Disadvantages | SEO is not friendly, FMP is slow | High cost, high front-end load pressure | High cost, high client pressure |
Both SSR and NSR are very good solutions to the white screen, but the shortcomings are also obvious. The cost is too high. SSR relies heavily on the stability of the service. For small and medium-sized companies, there are few resources to provide a stable server for the front end. In the environment, once the node fails, the loss is great, and the CSR solution is very costly for the client and there are many uncertainties.
Pre-rendering is not a silver bullet
Based on this, pre-rendering
may be the simplest and most practical solution, but pre-rendering
is not a silver bullet, let’s take a look at the first version of our team’s implementation of pre-rendering
When you happily hand over the hard-made pre-rendering to the visual inspection, you may get just a word ugly
:(
That's right, ugly
or unfriendly
, feeling that the internet speed is very slow
, these are the reactions of colleagues who have seen the first version. Why is this happening?
It can be found by comparing the two screenshots
- 1. The picture is not loaded, causing a large area of color blocks on the page
- 2. The back-end request is not returned, which also caused the vacancy of the page and even the deformation of the frame
We found that the problem is mainly in the placeholder element. If the element can be placed in advance, the pre-rendering can render a very beautiful page, so is there any placeholder element that is convenient
fast
good-looking
?
When I searched for a solution, I found that someone had proposed a placeholder solution.
A scheme for automatically generating skeleton screens
Skeleton screen
Yes, it is @Jocs, who shared A scheme for automatically generating skeleton screens, and the subsequent open source page-skeleton-webpack-plugin, providing a lower cost solution The plan of the skeleton screen provides a new idea for the realization of the skeleton screen. For the specific plan, please see his article
It is a pity that the page-skeleton-webpack-plugin
has not been updated and maintained for three years. Although it is a very feasible solution, there is still a lot of room for improvement, so I decided to use the page-skeleton-webpack-plugin
On the basis of, provide a more convenient solution, this is the origin of Killblanks
Killblanks
This project officially started in 2020. After half a year of debugging and development, it finally successfully passed the abtest
test and went live. And in February 2021 open source, thanks to everyone who paid for it.
Principle
Use Purpeteer
to simulate the browser request page function, and load the Google plug-in @killblanks/skeleton-ext Generate the page of the skeleton screen component, straight out the html
file
Frame
Currently Killblanks is built on lerna and consists of three core functions
-
@killblanks/prerender Provides pre-rendering capabilities, reads web content through
Purpeteer
, and outputs HTML directly - @killblanks/skeleton Modified the skeleton code of page-skeleton-webpack-plugin and fixed some of the bugs
- @killblanks/skeleton-ext Google plug-in for skeleton to facilitate debugging and output of skeleton screen components
Use
Killblanks is very convenient to use, if you understand the principle, you can get started in three minutes
1. Installation
yarn add @killblanks/prerender -D
2. Configuration
// webpack.config.js
const prerender = require('@killblanks/prerender')
export default {
...
plugins: [new prerender()]
...
}
- For detailed steps, please see @killblanks/prerender
3. Use @killblanks/skeleton-ext
- For detailed steps, please see @killblanks/skeleton-ext
4. Use the generated skeleton screen components in the project
- For example, like what is done in 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. Enter PRERENDER_SKELETON in the browser's console
Enter `PRERENDER_SKELETON` in the Chrome console to start the skeleton screen preview
Final effect
Performance
Finally, look at the abtest
test, Killblanks brought about the changes in page performance data
Data Sources
Use the company's online activities in Indonesia to conduct abtest to obtain relevant data
Data
type | total | fcp | lcp |
---|---|---|---|
@killblanks | 1532 | 536ms | 661ms |
Normal | 1730 | 990ms | 993ms |
First-contentful-paint(fcp)
- FCP average comparison: 536: 990 @killblanks can increase
454ms
, an average increase of45%
Largest-contentful-paint(lcp)
- LCP average comparison: 661: 993 @killblanks can increase
332ms
, an average increase of33.4%
Future
killblanks There are still many functions to be improved in the future, which is currently being done
- unit test
- Optimize documentation
- Support react && angular
- Complete demo
Welcome to the front-end friends to leave your own opinions in issue, If you have time, please killblanks Click ⭐.
Top comments (0)