目的:都是为了防止页面加载js,导致阻塞页面渲染的机制。
一、预加载加载
提前加载资源(例如图片),当用户需要查看时可直接从本地缓存中渲染 。
实现预加载的方法
1、单纯的css 实现
可通过CSS的background属性将图片预加载到屏幕外的背景上(用户的不可视区域)。只要这些图片的路径保持不变,当它们在Web页面的其他地方被调用时,浏览器就会在渲染过程中使用预加载(缓存)的图片。简单、高效,不需要任何JavaScript。
#preload-01 { background: url(img1.png); }
#preload-02 { background: url(img2.png); }
#preload-03 { background: url(img3.png); }
2、单纯的js预加载图片
<div class="hidden">
<script type="text/javascript">
var images = new Array() function preload() {
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image()
images[i].src = preload.arguments[i]
}
}
preload(
"http://domain.tld/gallery/image-001.jpg",
"http://domain.tld/gallery/image-002.jpg",
"http://domain.tld/gallery/image-003.jpg"
) </script>
</div>
3、使用ajax实现预加载
window.onload = function() {
setTimeout(function() {
// XHR to request a JS and a CSS
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://domain.tld/preload.js');
xhr.send('');
xhr = new XMLHttpRequest();
xhr.open('GET', 'http://domain.tld/preload.css');
xhr.send('');
// preload image
new Image().src = "http://domain.tld/preload.png";
}, 1000);
};
4、使用Imgage对象
js中执行到该语句后就会加载进来
window.onload = function() {
setTimeout(function() {
// preload image
new Image().src = "http://domain.tld/preload.png";
}, 1000);
};
5、使用html文档中img标签
执行文档时直接加载进来只不过让其不显示
<img src="http://domain.tld/preload.png" alt="预加载" style="display:none"/>
二、延迟加载(懒加载)
懒加载又称延迟加载。
图片的懒加载
当访问一个页面时,先把img元素或者其他元素的背景图片替换成一张大小1*1px图片的路径(只需要请求一次的占位图),只有当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来,这就是图片的懒加载。
懒加载的实现步骤
- 首先,不要将图片地址放到src属性中,而是放到其它属性(data-original)中。
- 页面加载完成后,根据scrollTop判断图片是否在用户的视野内,如果在,则将data-original属性中的值取出存放到src属性中。
- 在滚动事件中重复判断图片是否进入视野,如果进入,则将data-original属性中的值取出存放到src属性中。
懒加载的实现原理
页面中img元素,如果没有src属性,浏览器就不会发出请求去下载图片,只有通过js设置图片路径,浏览器才会发送请求;
懒加载的原理是先在页面中把所有的图片统一使用一张占位图进行占位,把真正的路径存在元素的‘data-url’属性中,要使用的时候,在设置。
懒加载的优点
页面加载速度快、可以减轻服务器的压力、节约了流量,用户体验好
三、vue中的懒加载
vue中的延迟加载是通过webpack代码拆分组件实现的。
延迟加载的方法:
1、 vue组件的延迟加载
通过将import函数包装到箭头函数中,Vue将仅在请求时执行它,并在该时刻加载模块。
Vue.component('AsyncCmp', () => import('./AsyncCmp'))
2、vue路由器中的延迟加载
vue路由器内置支持延迟加载。假设我们想在/login 路由中延迟加载一个Lgin 组件
// Instead of: import Login from './login'
const Login = () => import('./login')
new VueRouter({
routes: [
{ path: '/login', component: Login }
]
})
3、延迟加载vuex模块
Vuex有一种registerModule方法可以让我们动态创建Vuex模块。
const store = new Vuex.Store()
...
// Assume there is a "login" module we wanna load
import('./store/login').then(loginModule => {
store.registerModule('login', loginModule)
})