富文本图片懒加载解决方案
图片懒加载,作为性能优化的一部分,想必我们并不陌生。
在React、Vue项目中,我们都可以引入对应的NPM包处理图片懒加载,如 lazyload、react-lazyload、vue-lazyload等。
那么,如果图片并不是直接通过接口的某个字段返回,而是包含在接口返回的富文本内容中,此时如果富文本的内容较多,尤其包含多个图片,首屏加载页面时,一次性渲染所有文本图片资源,自然会比较耗费性能。那么,富文本图片懒加载该如何实现呢?
本文以React项目为例,介绍一下富文本图片懒加载解决方案。
一、安装依赖:
cnpm i react-lazyload html-react-parser --save
二、引入对应模块:
import parse, {domToReact} from 'html-react-parser';
import Lazyload from 'react-lazyload';
三、将返回的字符串转换为React节点:
直接上代码实现:
parseStrToReact = (content) => {
const tagWhiteList = [
'div', 'p', 'span', 'section', 'iframe', 'pre', 'article',
'img', 'video',
'a', 'b', 'br', 'em', 'small', 'del',
'ul', 'li', 'ol', 'dl', 'dt', 'dd',
'table', 'thead', 'tbody', 'tfoot', 'tr', 'td',
'h1', 'h2', 'h3', 'h4', 'h5', 'h6'
];
const options = {
replace: ({type, name, attribs, children}) => {
if (type !== 'tag') {
return
}
if (!tagWhiteList.includes(name)) {
return (<span>{domToReact(children, options)}</span>)
}
if (attribs && attribs['data-lazy'] === 'img-lazy') {
return (
<Lazyload height={200}>{domToReact(children)}</Lazyload>
)
}
}
};
return parse(content, options)
};
其中,Lazyload组件的属性height根据业务场景自定义图片渲染后的真实高度;
四、获取最终渲染的文本内容:
getContent = () => {
let content = this.state.content;
content = content.replace(/<img([^>|]+)>/g, function (all, $1) {
return `<div data-lazy="img-lazy"><img ${$1}></div>`
});
try {
return <div id="content">{this.parseStrToReact(content)}</div>
} catch (e) {
return <div id="content" dangerouslySetInnerHTML={{__html: content}}/>
}
};
注意,此时try/catch的使用,如果富文本处理异常可以使用dangerouslySetInnerHTML作为兼容;
五、在render中使用:
render () {
const {content} = this.state;
return (
<div className="lazyLoadWrap">
<h3>富文本图片懒加载解决方案</h3>
{
this.getContent()
}
</div>
)
}
以上即为在React项目中处理富文本图片懒加载的解决方案,如果在Vue项目中,同样可以参考以上思路,欢迎大佬们发表看法,提出更多的解决方案。