How to solve the slow loading speed of the first screen of SPA?

First screen loading

First Contentful Paint (First Contentful Paint) refers to the time from when the browser responds to the URL address input by the user to when the content of the first screen is rendered. At this time, the entire webpage does not necessarily have to be rendered completely, but it needs to display the content required by the current window.

First screen loading is arguably the most important part of user experience

About calculating time above the fold

Using the data provided by performance.timing:

Calculate the first screen time through DOMContentLoad or performance

// Option One:
document.addEventListener('DOMContentLoaded', (event) => {console.log('first contentful painting');
// Option II:

// performance.getEntriesByName("first-contentful-paint")[0]
// An instance of PerformancePaintTiming will be returned with the following structure:
{name: "first-contentful-paint",entryType: "paint",startTime: 507.80000002123415,duration: 0,

Reasons for slow loading

During the page rendering process, the factors that cause the slow loading speed may be as follows:

  • Network delay problem
  • Whether the resource file size is too large
  • Whether the resource has repeatedly sent requests to load
  • When loading the script, the rendering content is blocked


Several common SPA first screen optimization methods

  • Reduce entry file size
  • Static resource local cache
  • UI framework loaded on demand
  • Compression of image resources
  • Components are repackaged
  • Enable GZip compression
  • use SSR

Reduce the size of the entry file

The commonly used method is lazy loading of routes. The components corresponding to different routes are divided into different code blocks. When the route is requested, the route will be packaged separately, so that the entry file becomes smaller and the loading speed is greatly increased.

When configuring routing in vue-router, use the form of dynamically loading routing

routes:[ path: 'Blogs',name: 'ShowBlogs',component: () => import('./components/ShowBlogs.vue')

Load the route in the form of a function, so that the respective route files can be packaged separately, and the route component will be loaded only when the given route is parsed

Static resource local cache

The backend returns the resource problem:

  • Use HTTP cache, set Cache-Control, Last-Modified, Etag and other response headers
  • Using Service Worker Offline Caching

Reasonable use of localStorage by the front end

UI framework loaded on demand

In the daily use of UI frameworks, such as element-UI, or antd, we often directly refer to the entire UI library

import ElementUI from 'element-ui'

But in fact, the only components I use are buttons, paging, tables, inputs and warnings, so we need to reference them as needed

import { Button, Input, Pagination, Table, TableColumn, MessageBox } from 'element-ui';

Components are repackaged

Assuming that the A.js file is a commonly used library, now there are multiple routes using the A.js file, which causes repeated downloads

Solution: In the config file of webpack, modify the configuration of CommonsChunkPlugin

minChunks: 3 

minChunks is 3, which means that packages that have been used 3 times or more will be extracted and put into public dependency files, avoiding repeated loading of components

Compression of image resources

Although the image resource is not in the encoding process, it is the factor that has the greatest impact on page performance

For all image resources, we can perform appropriate compression

For the icons used on the page, you can use online font icons or sprite images to combine many small icons into the same image to reduce the pressure of http requests.

Enable GZip compression

After unpacking, let's compress it with gzip and install compression-webpack-plugin

cnmp i compression-webpack-plugin -D 

Introduce and modify webpack configuration in vue.congig.js

const CompressionPlugin = require('compression-webpack-plugin')

configureWebpack: (config) => {if (process.env.NODE_ENV === 'production') {// Modify configuration for production environment...config.mode = 'production'return {plugins: [new CompressionPlugin({test: /.js$|.html$|.css/, //Matching file name threshold: 10240, // Compress data over 10k deleteOriginalAssets: false //Whether to delete the original file})]}} 

We also need to do corresponding configuration on the server. If the browser that sends the request supports gzip, send it a file in gzip format. My server is built with the express framework. Just install compression to use it.

const compression = require('compression')
app.use(compression())// Called before other middleware uses 

use SSR

SSR (Server side), that is, server-side rendering, components or pages generate html strings through the server, and then send them to the browser

Building a server-side rendering from scratch is very complicated. It is recommended to use Nuxt.js to implement server-side rendering for vue applications

at last

Organized a set of "Interview Collection of Front-end Manufacturers", including HTML, CSS, JavaScript, HTTP, TCP protocol, browser, VUE, React, data structure and algorithm, a total of 201 interview questions, and made an answer for each question Answer and analyze.

Friends in need, you can click the card at the end of the article to receive this document and share it for free

Part of the documentation shows:

The length of the article is limited, and the following content will not be displayed one by one

Friends in need, you can click the card below to get it for free

Tags: Javascript Vue.js Front-end

Posted by djopie on Thu, 02 Mar 2023 14:01:49 +0530