8000 fix(core): load cashed image (#336) · qiwi/pijma@8012035 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit 8012035

Browse files
fix(core): load cashed image (#336)
1 parent aa2dc63 commit 8012035

File tree

2 files changed

+56
-30
lines changed

2 files changed

+56
-30
lines changed

packages/core/src/image/Image.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, {FC, ReactNode, Children, isValidElement} from 'react'
2+
23
import {Img, Box, Pos, Value} from '../primitive'
34
import {InView} from '../InView'
45
import {Stub} from '../stub'
@@ -8,6 +9,8 @@ export interface ImageProps {
89
width: Value
910
height: Value
1011
src: string
12+
cachedDelay?: number
13+
viewedDelay?: number
1114
srcSet?: string
1215
sizes?: string
1316
alt?: string
@@ -23,6 +26,8 @@ export const Image: FC<ImageProps> = ({
2326
sizes,
2427
alt,
2528
stub = true,
29+
cachedDelay = 50,
30+
viewedDelay = 1000,
2631
onLoad,
2732
}) => (
2833
stub ? (
@@ -32,6 +37,8 @@ export const Image: FC<ImageProps> = ({
3237
src={src}
3338
srcSet={srcSet}
3439
stub={stub}
40+
cachedDelay={cachedDelay}
41+
viewedDelay={viewedDelay}
3542
onLoad={onLoad}
3643
children={(renderProps) => (
3744
renderProps.loaded ? (

packages/core/src/image/ImageControl.ts

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {Component, ReactNode} from 'react'
2+
23
import {Value} from '../primitive'
34
import RenderChild from '../RenderChild'
45

@@ -8,6 +9,7 @@ export interface ImageControlProps {
89
src: string
910
srcSet?: string
1011
stub?: string | ReactNode
12+
cachedDelay?: number
1113
viewedDelay?: number
1214
onLoad?: () => void
1315
children: RenderChild<{
@@ -19,94 +21,111 @@ export interface ImageControlProps {
1921
}>
2022
}
2123

24+
enum Step {
25+
NONE,
26+
CHECK_CACHE,
27+
NO_CACHE,
28+
LOAD,
29+
DONE,
30+
}
31+
2232
export interface ImageControlState {
23-
viewed: boolean
24-
loaded: boolean
33+
step: Step
2534
}
2635

2736
export class ImageControl extends Component<ImageControlProps, ImageControlState> {
2837

2938
public static defaultProps = {
39+
cachedDelay: 50,
3040
viewedDelay: 1000,
3141
}
3242

3343
public state: ImageControlState = {
34-
viewed: false,
35-
loaded: false,
44+
step: Step.NONE,
3645
}
3746

38-
private viewedTimer: number | undefined
39-
4047
public componentWillUnmount: () => void = () => {
4148
clearTimeout(this.viewedTimer)
49+
clearTimeout(this.cachedTimer)
4250
}
4351

52+
private viewedTimer: number | undefined
53+
54+
private cachedTimer: number | undefined
55+
4456
private onChange: (inView: boolean) => void = (inView) => {
4557
clearTimeout(this.viewedTimer)
4658
if (!inView) {
4759
return
4860
}
49-
if (this.isCached) {
61+
if (this.state.step === Step.NONE) {
5062
this.setState({
51-
viewed: true,
63+
step: Step.CHECK_CACHE,
5264
})
53-
return
65+
const image = document.createElement('img')
66+
image.src = this.props.src
67+
image.srcset = this.props.srcSet || ''
68+
image.onload = () => {
69+
clearTimeout(this.viewedTimer)
70+
clearTimeout(this.cachedTimer)
71+
this.setState({
72+
step: Step.LOAD,
73+
})
74+
}
75+
this.cachedTimer = setTimeout(() => {
76+
image.onload = null
77+
image.src = ''
78+
image.srcset = ''
79+
this.setState({
80+
step: Step.NO_CACHE,
81+
})
82+
}, this.props.cachedDelay)
5483
}
5584
this.viewedTimer = setTimeout(() => {
5685
this.setState({
57-
viewed: true,
86+
step: Step.LOAD,
5887
})
5988
}, this.props.viewedDelay)
6089
}
6190

6291
private onLoad: () => void = () => {
63-
if (!this.state.viewed) {
92+
if (this.state.step !== Step.LOAD) {
6493
return
6594
}
6695
if (this.props.onLoad) {
6796
this.props.onLoad()
6897
}
6998
this.setState({
70-
loaded: true,
99+
step: Step.DONE,
71100
})
72101
}
73102

74103
private get src(): string | undefined {
75104
const {stub, src} = this.props
76-
if (this.state.viewed) {
105+
if (this.state.step === Step.LOAD || this.state.step === Step.DONE) {
77106
return src
78107
}
108+
if (this.state.step === Step.NONE || this.state.step === Step.CHECK_CACHE) {
109+
return undefined
110+
}
79111
if (typeof stub === 'string') {
80112
return stub
81113
}
82114
return undefined
83115
}
84116

85117
private get srcSet(): string | undefined {
86-
if (!this.state.viewed) {
87-
return undefined
88-
}
89-
return this.props.srcSet
90-
}
91-
92-
private get isCached(): boolean {
93-
try {
94-
const image = document.createElement('img')
95-
image.src = this.props.src
96-
const complete = image.complete
97-
image.src = ''
98-
return complete
99-
}
100-
catch (e) {
101-
return false
118+
if (this.state.step === Step.LOAD || this.state.step === Step.DONE) {
119+
return this.props.srcSet
102120
}
121+
return undefined
103122
}
104123

105124
public render() {
106125
return this.props.children({
107126
src: this.src,
108127
srcSet: this.srcSet,
109-
loaded: this.state.loaded,
128+
loaded: this.state.step === Step.DONE,
110129
onChange: this.onChange,
111130
onLoad: this.onLoad,
112131
})

0 commit comments

Comments
 (0)
0