feat(v2): optimize image processing with sharp & lqip (#1663)

* feat(v2): optimize image processing

* cleanup
This commit is contained in:
Endi 2019-07-15 01:28:16 +07:00 committed by Yangshun Tay
parent f77e96d28d
commit bc5bceeb87
15 changed files with 838 additions and 33 deletions

View file

@ -49,8 +49,10 @@
"fs-extra": "^7.0.0",
"globby": "^9.2.0",
"html-webpack-plugin": "^4.0.0-beta.5",
"image-webpack-loader": "^5.0.0",
"import-fresh": "^3.0.0",
"lodash": "^4.17.14",
"lqip-loader": "^2.2.0",
"mini-css-extract-plugin": "^0.7.0",
"nprogress": "^0.2.0",
"null-loader": "^3.0.0",
@ -58,12 +60,16 @@
"portfinder": "^1.0.20",
"react-dev-utils": "^9.0.1",
"react-helmet": "^6.0.0-beta",
"react-ideal-image": "^0.0.5",
"react-loadable": "^5.5.0",
"react-loadable-ssr-addon": "^0.1.8",
"react-router": "^5.0.1",
"react-router-config": "^5.0.1",
"react-router-dom": "^5.0.1",
"react-waypoint": "8.0.3",
"responsive-loader": "^1.2.0",
"semver": "^6.1.1",
"sharp": "^0.22.1",
"shelljs": "^0.8.3",
"static-site-generator-webpack-plugin": "^3.4.2",
"std-env": "^2.2.1",

View file

@ -0,0 +1,29 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import IdealImage from 'react-ideal-image';
function Image(props) {
const {alt, className, img} = props;
return (
<IdealImage
{...props}
alt={alt}
className={className}
height={img.src.height}
placeholder={{lqip: img.preSrc}}
src={img.src.src}
srcSet={img.src.images.map(image => ({
...image,
src: image.path,
}))}
width={img.src.width}
/>
);
}
export default Image;

View file

@ -156,6 +156,20 @@ export function createBaseConfig(
exportOnlyLocals: isServer,
}),
},
{
test: /\.(gif|png|jpe?g)$/i,
use: [
'lqip-loader',
{
loader: 'responsive-loader',
options: {
adapter: require('responsive-loader/sharp'),
sizes: [300, 600, 900, 1200],
},
},
'image-webpack-loader',
],
},
],
},
plugins: [

View file

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 223 KiB

After

Width:  |  Height:  |  Size: 223 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 200 KiB

After

Width:  |  Height:  |  Size: 200 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 197 KiB

After

Width:  |  Height:  |  Size: 197 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Before After
Before After

View file

@ -10,7 +10,7 @@ const users = [
{
title: 'Channel.js',
description: 'The missing constructor for creating safe async iterators',
preview: '/img/showcase/channeljs.png',
preview: require('./showcase/channeljs.png'),
website: 'https://channel.js.org',
source: 'https://github.com/channeljs/channel',
fbOpenSource: false,
@ -19,7 +19,7 @@ const users = [
{
title: 'Component Kit',
description: 'A declarative UI framework for iOS',
preview: '/img/showcase/componentkit.png',
preview: require('./showcase/componentkit.png'),
website: 'https://componentkit.org',
source: 'https://github.com/facebook/componentkit',
fbOpenSource: true,
@ -28,7 +28,7 @@ const users = [
{
title: 'Flux',
description: 'Application architecture for building user interfaces',
preview: '/img/showcase/flux.png',
preview: require('./showcase/flux.png'),
website: 'https://facebook.github.io/flux/',
source: 'https://github.com/facebook/flux',
fbOpenSource: true,
@ -37,7 +37,7 @@ const users = [
{
title: 'Hermes',
description: 'JavaScript engine optimized for React Native',
preview: '/img/showcase/hermes.png',
preview: require('./showcase/hermes.png'),
website: 'https://hermesengine.dev',
source: 'https://github.com/facebook/hermes',
fbOpenSource: true,
@ -46,7 +46,7 @@ const users = [
{
title: 'uniforms',
description: 'A set of React libraries for building forms',
preview: '/img/showcase/uniforms.png',
preview: require('./showcase/uniforms.png'),
website: 'https://uniforms.tools/',
source: 'https://github.com/vazco/uniforms',
fbOpenSource: false,

View file

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Before After
Before After

View file

@ -9,6 +9,7 @@ import React from 'react';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import withBaseUrl from '@docusaurus/withBaseUrl';
import Image from '@docusaurus/Image';
import Layout from '@theme/Layout';
@ -18,7 +19,7 @@ import styles from './styles.module.css';
const QUOTES = [
{
thumbnail: 'img/christopher-chedeau.jpg',
thumbnail: require('./christopher-chedeau.jpg'),
name: 'Christopher "vjeux" Chedeau',
title: 'Lead Prettier Developer',
text: (
@ -34,7 +35,7 @@ const QUOTES = [
),
},
{
thumbnail: 'img/hector-ramos.png',
thumbnail: require('./hector-ramos.png'),
name: 'Hector Ramos',
title: 'Lead React Native Advocate',
text: (
@ -47,7 +48,7 @@ const QUOTES = [
),
},
{
thumbnail: 'img/ricky-vetter.jpg',
thumbnail: require('./ricky-vetter.jpg'),
name: 'Ricky Vetter',
title: 'ReasonReact Developer',
text: (
@ -197,10 +198,10 @@ function Home() {
{QUOTES.map(quote => (
<div className="col" key={quote.name}>
<div className="avatar avatar--vertical margin-bottom--sm">
<img
<Image
alt={quote.name}
className="avatar__photo avatar__photo--xl"
src={withBaseUrl(quote.thumbnail)}
img={quote.thumbnail}
/>
<div className="avatar__intro">
<h4 className="avatar__name">{quote.name}</h4>

View file

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Before After
Before After

View file

@ -6,6 +6,7 @@
*/
import React, {useEffect} from 'react';
import Image from '@docusaurus/Image';
import Layout from '@theme/Layout';
import classnames from 'classnames';
@ -42,7 +43,7 @@ function Showcase() {
<div className="col col--4">
<div className={classnames('card', styles.showcaseUser)}>
<div className="card__image">
<img src={user.preview} alt={user.title} />
<Image img={user.preview} alt={user.title} />
</div>
<div className="card__body">
<div class="avatar">

798
yarn.lock

File diff suppressed because it is too large Load diff