preface

In fact, only 10-20% of end-user response time is in retrieving HTML documents from the Web server and delivering them to the browser. If you want to effectively reduce page response times, you must focus on the remaining 80-90% of the end user experience. In this blog post, I summarized front-end page performance optimizations based on actual project experience and some testing experience. Some of these lessons are taken from Steve Souders’s Guide to Building High Performance Web Sites, Publishing House of Electronics Industry.

First, code related optimization

  1. Put the style sheet at the HEAD – use the link tag to place the style sheet in the HEAD of the document
  • Following the HTML specification and placing the style sheet in the header is a great way to avoid white screens and the flickering of unstyled content.
<! DOCTYPE html> <html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title></title> <! Use the link tag to place the stylesheet in the document's HEAD --> <link rel="stylesheet" href="example.css">
</head>

<body></body>

</html>
Copy the code
  1. Place the script at the bottom
  • What happens when a script is placed at the top: the script blocks the display of what follows it; Scripts block downloads of components that follow them;
  • The script on the bottom of the label before, similar to the document. The body. The appendChild (yourScript), will not block the page content, and the visual components in the page can download as soon as possible.
<! DOCTYPE html> <html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title></title>
  <link rel="stylesheet" href="example.css"> </head> <body> <! -- Place the script at the bottom --> <script SRC ="example.js"></script>
</body>

</html>
Copy the code
  1. Reducing HTTP requests

CSS Sprites

Combine multiple images into one image and use background-position to locate the required image. Only one image per request reduces HTTP requests. (SVG is recommended for ICONS, but iconfont is also acceptable)

  • There are many tools for composing Sprite images
  • Local tools: github.com/iwangx/spri…
  • Online tool https://www.toptal.com/develo…

Local tools:

  • Inline images and scripts require no additional HTTP requests, and images less than 10K can be set to base64 bits.
<img src="data:image/jpeg; base64,/9j/4AAQSkZJRgABAQEASABIAAD/4SUJRXhpZgAATU>Copy the code

Merge scripts and stylesheets

  • In general, it is better to use external scripts and style sheets for performance, but performance can be degraded if modular code is split into multiple small files, each resulting in an additional HTTP request
  1. Use external Javascript and CSS
Good

<link rel="stylesheet" href="example.css">

<script src="example.js"></script>
bad

<style>
// code
</style>

<script>
// code
</script>
Copy the code
  • The main benefits of using external Javascript and Css are that caching can be configured to facilitate component reuse
  1. Using CDN (Content Delivery Network)

CDN is a content distribution network built on the network. Relying on the edge servers deployed in various places and through the function modules of load balancing, content distribution and scheduling of the central platform, users can obtain the content they need nearby, reduce network congestion and improve user access response speed and hit ratio. The key technologies of CDN mainly include content storage and distribution. — from Baidu Baike

  • Resources introduced through CDN are currently basically using the latest HTTP2 protocol, so the performance can be optimized to the extreme, thanks to CDN.
  • BootCDN – Bootstrap Chinese open source project free CDN acceleration service
  • UNPKG
  1. Code compression

Gzip Compression Gzip compression can save 50% to 70% of network overhead

The types of compression supported by the browser can be viewed by checking network accept-Encoding: gzip, deflate. Deflate browsers also support GZIP, but many browsers that support GZIP do not support Deflate, so gzip is the ideal compression method

  • For webpack projects, see gZIP compression in Vue’s first screen load time optimization below
// npm install compression --save-dev
const compression = require('compression')
Copy the code

Code compression

Grunt, gulp, Webpack can compress HTML, CSS, Javascript code

Second, server-related optimization

In this article, nginx server is used for relevant configuration, and Apache can also be used for relevant optimization. Please refer to Google for specific operations

  1. Enable Gzip compression
  • Configure gzip compression on the server
gzip on; # open Gzip
gzip_static on; # Enable static file compression
gzip_min_length  1k; # Do not compress the critical value, greater than 1K compression
gzip_buffers     4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types     text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss; The type of file to compress
gzip_vary on;
gzip_proxied   expired no-cache no-store private auth;
gzip_disable   "MSIE [1-6]\.";

Copy the code

Nginx-related configuration of my server:

HTTP2’s front-end performance is mainly reflected in: request and response multiplexing, header compression

  • Feel the multiplexing

  • Http2 must be used with HTTPS
  • Using HTTPS requires ca certificate Aliyun HTTPS certificate purchase (free CA certificate)
  1. Open the cache

Adding Expires headers (strong caching)

Personal site configuration

location ~.*\.(svg|woff|js|css){
    root /yourFilePath;
    expires 1d;
}
Copy the code
  • A Web server uses an Expires header to tell a Web client that it can use the current copy of a component until a specified time, after which the response will be considered invalid, as the HTTP specification simply states. It is sent in the HTTP response
expires: Thu, 30 May 2019 20:51:42 GMT
Copy the code
  • The Expires header above tells the browser that the response is valid until May 30, 2019. If this header is returned for an image in the page, the browser will use the cached image for subsequent page views, reducing the number of HTTP requests by one

Max – Age and mod_expires

  • Personal site CSS files use strong cache cache-control: max-age

server {
    add_header Cache-Control max-age=72000;
}
Copy the code
  • Before I explain how caching is a good way to improve transport performance, I need to mention an alternative to the Expires header. HTTP 1.1 introduced the cache-control header to overcome the Expires header limitation
  • Because the Expires header uses a specific time, it requires strict synchronization between the server and client clocks. In addition, the expiration date needs to be checked frequently, and a new date needs to be provided in the server configuration once it arrives in the future.
  • Cache-control uses the max-age directive to specify how long the component is cached. If less than max-age has elapsed since the component was requested, the browser uses the cached version, which avoids additional HTTP requests. A long max-age header can set the refresh window for the next 10 years.
Cache-Control: max-age=315360000
Copy the code
  • Expires or cache-control Max – age. If both occur together, the HTTP specification states that the max-age directive overwrites the Expires header.
  • Cache-control max-age is recommended; if you use Expires you need to worry about clock synchronization and configuration maintenance issues.

Configuring ETag (Negotiated Cache)

Vue official document Expires configuration

The browser must generate this HTTP request and perform validation checks, but this is still more efficient than simply downloading all expired components (as opposed to strong caching). If the component in the browser cache is valid (that is, it matches the component on the original server), the original server does Not return the entire content, but a 304 Not Modifed status code.

Attached: Vue first screen loading time is too long detailed optimization scheme

  • First, attach an optimized picture
  • The first screen load time from the original 10s to 2s, tested on individual sites

Note: I used [email protected], [email protected] when optimizing the VUE project. If it is cli2, the project has little impact, and the optimized scheme is combined with the server and Webpack.

The vuE-CLI scaffolding default configuration already significantly optimizes the overall performance of the front-end, and ON top of that, I added three optimizations to add significant improvements

  1. Gzip compression
  • First: Enable Gzip compression
  • Here is the configuration in vue.config.js in the front-end project
// install compression-webpack-plugin --save-dev const CompressionWebpackPlugin = require('compression-webpack-plugin') / / define the current environment const ENV = process. The ENV. NODE_ENV | |'development'Module. exports = {configureWebpack: config => {// Enable compression if you are in a development environmentif (ENV === 'production') {// Parameter configuration document: https://www.webpackjs.com/plugins/compression-webpack-plugin/ config.plugins.push(new CompressionWebpackPlugin({ algorithm:'gzip'.test: / \. (js) | | CSS HTML $/, threshold: 10240, minRatio: 0.8}}}}))Copy the code
  1. Use CDN content delivery network

In the index. HTML file, the environment determines whether to introduce the CDN file. In the vue.config.js file, webpack determines whether to use the CDN to introduce the global variables of the file through the environment

  • Using CDN requires configuration in webpack and index.html

The first step is to configure vue.config.js, just need to configure Gzip compression on the basis of the code:

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

const ENV = process.env.NODE_ENV || 'development'

module.exports = {
    configureWebpack: config => {
        if (ENV === 'production') {
            config.plugins.push(new CompressionWebpackPlugin({
                algorithm: 'gzip'.test: /\.(js|css|html)$/, threshold: 10240, minRatio: 0.8})) // Configure externals when the js file entered using the CDN can be referenced in the current project // for example, import vue from'vue'The uppercase Vue is the corresponding uppercase Vue config.externals = {'vue': 'Vue'.'vue-router': 'VueRouter'.'axios': 'axios'}}}}Copy the code

The second step is to configure index.html, using EJS syntax in the body to determine if the environment is production

<body>
  <div id="app"></div>
  <% if (NODE_ENV === 'production') { %>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
    <script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
    <script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
  <% } %>
</body>
Copy the code
  1. Configuration sourceMap
  • Devtool | webpack Chinese website You can according to the website for detailed configuration development environment and production environment
  • It is also possible to kill productionSourceMap directly as I did by productionSourceMap: false
const CompressionWebpackPlugin = require('compression-webpack-plugin')

const ENV = process.env.NODE_ENV || 'development'

module.exports = {
    configureWebpack: config => {
        if (ENV === 'production') {
            config.plugins.push(new CompressionWebpackPlugin({
                algorithm: 'gzip'.test: / \. (js) | | CSS HTML $/, threshold: 10240, minRatio: 0.8})) config. Externals = {'vue': 'Vue'.'vue-router': 'VueRouter'.'axios': 'axios'}}}, // Disable production environmentsourceMap
    productionSourceMap: false
}
Copy the code
  1. Using HTTP2

Refer to server Optimization article 2

conclusion

Front-end performance optimization is very important, and the points I mentioned in this article are the ones THAT I think are important and will be added when better solutions come along. Of course, you can also leave a comment in the comments section and we will discuss it together. Please point out any mistakes.

Segmentfault.com/a/119000001…