Commit 3ba33e92 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Lazy-loading design images with IntersectionObserver

parent 07f96c73
<script>
import { GlLoadingIcon } from '@gitlab/ui';
import { GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import Timeago from '~/vue_shared/components/time_ago_tooltip.vue';
import { n__, __ } from '~/locale';
......@@ -8,6 +8,7 @@ import { DESIGN_ROUTE_NAME } from '../../router/constants';
export default {
components: {
GlLoadingIcon,
GlIntersectionObserver,
Icon,
Timeago,
},
......@@ -46,6 +47,7 @@ export default {
data() {
return {
imageLoading: true,
isInView: false,
};
},
computed: {
......@@ -77,6 +79,9 @@ export default {
showLoadingSpinner() {
return this.imageLoading || this.isUploading;
},
imageLink() {
return this.isInView ? this.image : '';
},
},
methods: {
onImageLoad() {
......@@ -103,14 +108,16 @@ export default {
</span>
</div>
<gl-loading-icon v-show="showLoadingSpinner" size="md" />
<img
v-show="!showLoadingSpinner"
:src="image"
:alt="filename"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
@load="onImageLoad"
/>
<gl-intersection-observer @appear="isInView = true">
<img
v-show="!showLoadingSpinner"
:src="imageLink"
:alt="filename"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
@load="onImageLoad"
/>
</gl-intersection-observer>
</div>
<div class="card-footer d-flex w-100">
<div class="d-flex flex-column str-truncated-100">
......
---
title: Lazy-loading design images with IntersectionObserver
merge_request: 28555
author:
type: added
......@@ -30,12 +30,16 @@ exports[`Design management list item component with no notes renders item with c
style="display: none;"
/>
<img
alt="test"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src="http://via.placeholder.com/300"
/>
<gl-intersection-observer-stub
options="[object Object]"
>
<img
alt="test"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src=""
/>
</gl-intersection-observer-stub>
</div>
<div
......@@ -99,12 +103,16 @@ exports[`Design management list item component with no notes renders item with c
style="display: none;"
/>
<img
alt="test"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src="http://via.placeholder.com/300"
/>
<gl-intersection-observer-stub
options="[object Object]"
>
<img
alt="test"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src=""
/>
</gl-intersection-observer-stub>
</div>
<div
......@@ -168,12 +176,16 @@ exports[`Design management list item component with no notes renders item with c
style="display: none;"
/>
<img
alt="test"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src="http://via.placeholder.com/300"
/>
<gl-intersection-observer-stub
options="[object Object]"
>
<img
alt="test"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src=""
/>
</gl-intersection-observer-stub>
</div>
<div
......@@ -224,12 +236,16 @@ exports[`Design management list item component with no notes renders item with n
style="display: none;"
/>
<img
alt="test"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src="http://via.placeholder.com/300"
/>
<gl-intersection-observer-stub
options="[object Object]"
>
<img
alt="test"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src=""
/>
</gl-intersection-observer-stub>
</div>
<div
......@@ -279,13 +295,17 @@ exports[`Design management list item component with no notes renders loading spi
size="md"
/>
<img
alt="test"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src="http://via.placeholder.com/300"
style="display: none;"
/>
<gl-intersection-observer-stub
options="[object Object]"
>
<img
alt="test"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src=""
style="display: none;"
/>
</gl-intersection-observer-stub>
</div>
<div
......@@ -336,12 +356,16 @@ exports[`Design management list item component with notes renders item with mult
style="display: none;"
/>
<img
alt="test"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src="http://via.placeholder.com/300"
/>
<gl-intersection-observer-stub
options="[object Object]"
>
<img
alt="test"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src=""
/>
</gl-intersection-observer-stub>
</div>
<div
......@@ -409,12 +433,16 @@ exports[`Design management list item component with notes renders item with sing
style="display: none;"
/>
<img
alt="test"
class="block ml-auto mr-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src="http://via.placeholder.com/300"
/>
<gl-intersection-observer-stub
options="[object Object]"
>
<img
alt="test"
class="block mx-auto mw-100 mh-100 design-img"
data-qa-selector="design_image"
src=""
/>
</gl-intersection-observer-stub>
</div>
<div
......
import { createLocalVue, shallowMount } from '@vue/test-utils';
import VueRouter from 'vue-router';
import Item from 'ee/design_management/components/list/item.vue';
import { GlIntersectionObserver } from '@gitlab/ui';
const localVue = createLocalVue();
localVue.use(VueRouter);
......@@ -47,6 +48,19 @@ describe('Design management list item component', () => {
wrapper.destroy();
});
it('renders an image when it appears in view', () => {
createComponent();
const image = wrapper.find('img');
expect(image.attributes('src')).toBe('');
wrapper.find(GlIntersectionObserver).vm.$emit('appear');
return wrapper.vm.$nextTick().then(() => {
expect(image.attributes('src')).toBe('http://via.placeholder.com/300');
});
});
describe('with notes', () => {
it('renders item with single comment', () => {
createComponent({ notesCount: 1 });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment