Using preload & prefetch to optimize the resource loading of front page

Vivo Internet technology 2020-11-11 10:33:41
using preload prefetch optimize resource


For the front page , Loading static resources plays an important role in page performance . This article will introduce two resource instructions provided by the browser -preload/prefetch, They can help browsers optimize the order and timing of resource loading , Improve page performance .

One 、 Start with an example

As shown in the figure above , We developed a simple cash register , During the payment process, you can expand the coupon list and select the corresponding coupon . You can see from the graph , When the list first expands , The coupon background has a gradual process of showing , The experience is not very good .

The reason for the problem is also obvious , Because the background uses a specially designed visual image , When the coupon list is expanded, you need to load images , The process of gradual background display is actually the process of image loading ; When the Internet is slow , The problem will be more obvious . that , How to solve this problem ?

Analyze carefully , We will find that the reason for the problem is that the background image is loaded too late .

If you can load the background image before the coupon list is rendered , This problem will not arise . From this point of view , We may think of two options :

  1. Use inline images , That is to convert the image into base64 Coded data-url. This way, , In fact, it is to integrate the information of pictures into css In file , It avoids the loading of image resources separately . But image inlining will increase css File size , Increase the first screen rendering time .
  2. Use js The code preloads the image
preloadImage() {
const imgList = [
require('@/assets/imgs/error.png'),
require('@/assets/imgs/ticket_bg.png')
];
for (let i = 0; i < imgList.length; i++) {
const newIMG = new Image();
newIMG.src = imgList[i];
}
}

This scheme mainly uses the browser's cache mechanism , from js Load the image ahead of time , When the coupon list is rendered, it can be obtained directly from the cache . however , This scheme adds extra code , You need to control the loading time , And the picture of url Hard coded in logic . 

It can be seen that , The above two solutions can solve our problem , But there are some shortcomings .

that , Is there a better solution ? The answer is prefetch- A preloading scheme provided by browser .

Two 、 What is? prefetch?

prefetch( Link prefetching ) It's a browser mechanism , It uses the browser's free time to download or prefetch documents that users may access in the near future . Web pages provide browsers with a set of prefetch hints , After the browser finishes loading the current page, it starts to pull the specified document silently and store it in the cache . When a user accesses one of the prefetched documents , You can quickly get from the browser cache .--MDN

say concretely , Browser pass <link rel="prefetch" href="/library.js"> Tag to achieve preloading .

among rel="prefetch" go by the name of Resource-Hints( Resource tips ), That is to assist the browser to optimize resources .

Similar instructions are rel="preload", We'll talk about it later .

<head>
...
<link rel="prefetch" href="static/img/ticket_bg.a5bb7c33.png">
...
</head>

Check the current coupon list loading effect .

Sure enough , We succeeded in achieving the desired effect . So how do browsers do it ? We turn on Chrome Of Network Let's look at the panel :

You can see , In the request list on the first screen, the coupon background image appears ticket\_bg.png Load request for , The request itself looks like a normal request ; After expanding the coupon list ,network A new ticket\_bg.png Access request , We soon found out , The requested status Although it is also 200, But there's a special mark —prefetch cache, Indicate that the requested resource came from prefetch cache . This performance proves the above prefetch The definition of , That is, the browser preloads resources in idle time , When it is used, it can be obtained from browser cache directly .

3、 ... and 、Preload

From the above case , We have realized the powerful ability of the browser to preload resources . actually , Preloading is a broad concept ,prefetch It's just one of the concrete ways to realize it , In this section, we introduce another preloading method preload. We mentioned above ,preload And prefetch Same as browser Resource-Hints, Used to assist browser in resource optimization . To distinguish between the two ,prefetch Usually translated as pre extraction ,preload It is translated as preload .

Elemental rel Property value of property preload Can let you in your HTML Some declarative resource acquisition requests are written inside the elements in the page , You can indicate which resources are needed immediately after the page is loaded . For this kind of resource that is immediately needed , You may want to start getting... Early in the page load lifecycle , Preload before the browser's main rendering mechanism intervenes . This mechanism enables resources to be loaded and available earlier , And it's not easy to block the initial rendering of the page , To improve performance .

Simply speaking , It is through <link rel="preload" href="xxx" as="xx"> Tag explicitly declares a high priority resource , Force the browser to request resources in advance , At the same time do not block the document normal onload. We also use a practical case to introduce in detail .

The picture above is another cash register we developed , For the sake of localization , The design uses custom Fonts . After the development, we found that , When the page is loaded for the first time, the text will flash for a short time (FOUT,Flash of Unstyled Text), It is obvious when the network condition is poor ( As shown in the moving picture ). The reason is , Is the font file by css introduce , stay css Load only after parsing , Browsers can only use degraded fonts until loading is complete . in other words , The font file was loaded too late , You need to tell the browser to load ahead of time , This is exactly preload Where it comes in handy .

We're at the entrance html file head Join in preload label :

<head>
...
<link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Demi.otf') %>" crossorigin>
<link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Regular.otf') %>" crossorigin>
...
</head>

See the effect of the page loading for the first time again :

The flash of font style is gone ! Let's use preload Front and rear network panel .

Before using :

After using :

You can see that the font file loading time is significantly ahead of time , Received in browser html It was loaded soon after .

Be careful :preload link You have to set as Property to declare the type of the resource (font/image/style/script etc. ), Otherwise, the browser may not be able to load resources correctly .

Four 、Preload and Prefetch The concrete practice of

1、preload-webpack-plugin

The two examples we gave earlier , It's all at the entrance html Manually add relevant code :

<head>
...
<link rel="prefetch" href="static/img/ticket_bg.a5bb7c33.png">
...
</head>
<head>
...
<link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Demi.otf') %>" crossorigin>
<link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Regular.otf') %>" crossorigin>
...
</head>

It's obviously not convenient , And the resource path is hard coded in the page ( actually ,ticket_bg.a5bb7c33.png In the suffix hash It's automatically generated by the build process , So hard coding doesn't work in many scenarios ).webpack plug-in unit preload-webpack-plugin Can help us automate the process , combination htmlWebpackPlugin Insert... In the build process link label .

const PreloadWebpackPlugin = require('preload-webpack-plugin');
...
plugins: [
new PreloadWebpackPlugin({
rel: 'preload',
as(entry) { // The resource type
if (/\.css$/.test(entry)) return 'style';
if (/\.woff$/.test(entry)) return 'font';
if (/\.png$/.test(entry)) return 'image';
return 'script';
},
include: 'asyncChunks', // preload Module scope , You can also take values 'initial'|'allChunks'|'allAssets',
fileBlacklist: [/\.svg/] // Blacklist of resources
fileWhitelist: [/\.script/] // White list of resources
})
]

PreloadWebpackPlugin The configuration is relatively simple on the whole , It should be noted that include attribute . The default value of this attribute is 'asyncChunks', Indicates that only preload asynchronous js modular ; If you need to preload images 、 Font and other resources , You need to set it to 'allAssets', Represents the processing of all types of resources .

But in general, we don't want to expand the preload range too much , So you have to go through fileBlacklist or fileWhitelist Control .

For modules loaded asynchronously , You can also use webpack Built in /_ webpackPreload: true _/ Tag for more granular control .

Take the following code for example ,webpack Will generate <link rel="preload" href="chunk-xxx.js" as="script"> Tag added to html Page header .

import(/* webpackPreload: true */ 'AsyncModule');
remarks :prefetch Configuration and preload similar , But there's no need to be right about as Property to set .

2、 Use scenarios

From the introduction above, we can see that ,preload The original intention of the design is to load the key resources needed for the first screen as soon as possible , To improve the page rendering performance .

At present, most browsers have the ability to predict and parse , You can parse the entry in advance html Resources of Chinese and foreign chains , So the entry script file 、 Style files, etc. don't need to be done intentionally preload.

But some are hidden in CSS and JavaScript The resource , Such as font files , It is the key resource of the first screen , But when css The file will not be loaded until it is parsed . This kind of scene is suitable for preload Make a statement , Load resources as soon as possible , Avoid page rendering delays . 

And preload Different ,prefetch The statement is about resources that may be accessed in the future , Therefore, it is suitable for modules loaded asynchronously 、 You may jump to other routing pages for resource caching ; For some resources that may be visited in the future , As the background image of the coupon list in the case above 、 Common loading failures icon etc. , It's also more applicable .

3、 Best practices

Based on the above sharing of usage scenarios , We can come up with a more general best practice :

  • In most scenarios, there is no need to use preload
  • Like font files, this hidden in the script 、 The first screen key resource in the style , It is recommended to use preload
  • Modules loaded asynchronously ( This is typical of a non home page in a single page system ) It is recommended to use prefetch
  • The probability that the resources to be accessed can be used prefetch Improve performance and experience

4、vue-cli3 Default configuration

  • preload

By default , One Vue CLI The application will automatically generate all files needed to initialize rendering preload Tips . These tips will be @vue/preload-webpack-plugin Inject , And through chainWebpack Of config.plugin('preload') Modify and delete .

  • prefetch

By default , One Vue CLI The app will do for all async chunk Generated JavaScript file ( Through dynamic import() On demand code splitting The product of ) Automatic generation prefetch Tips . These tips will be @vue/preload-webpack-plugin Inject , And through chainWebpack Of config.plugin('prefetch') Modify and delete .

5、 ... and 、 Summing up and stepping on the pit

1、preload and prefetch The essence of is preloading , Load first 、 After execution , Load and execution decouple .

2、preload and prefetch It won't block the page onload.

3、preload Key resources used to declare the current page , Force the browser to load as soon as possible ; and prefetch Used to declare resources that may be used in the future , Load when the browser is idle .

4、 Don't abuse preload and prefetch, It needs to be used in the right context .

5、preload The font resource of must be set crossorigin attribute , Otherwise, it will lead to repeated loading . 

The reason is that if you don't specify crossorigin attribute ( Even if homologous ), Browsers will be anonymous CORS Go to preload, The cache cannot be shared between two requests .

6、 About preload and prefetch Cache of resources , stay Google This is what the developer said in an article : If resources can be cached ( For example, there are effective cache-control and max-age), It's stored in HTTP cache ( That is to say disk cache) in , Can be used by current or future missions ; If the resource cannot be cached in HTTP In cache , As a substitute for , It's put in the memory cache until it's used . 

But we are Chrome browser ( Version number 80) Intermediate testing , It turns out that's not the case . Set the server's cache policy to no-store, Observe the loading of resources .

You can find ticket_bg.png The second load is not fetched from the local cache , Still loading from the server . therefore , If you want to use prefetch, The corresponding resources must do a reasonable cache control .

7、 There is no law https Certificate site is not available prefetch, Prefetched resources are not cached ( In the course of actual use , Unknown cause ).

8、 Finally, let's take a look at preload and prefetch Browser compatibility .

You can see , The compatibility of the two is not very good at present . Fortunately, they don't support preload and prefetch Your browser will automatically ignore it , So you can use them as a progressive enhancement , Optimize the resource loading of our page , Improve performance and user experience .

author : Sha Chaoheng
版权声明
本文为[Vivo Internet technology]所创,转载请带上原文链接,感谢

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple