Skip to content

Commit

Permalink
Reader: Cut down image transfer significantly (#11400)
Browse files Browse the repository at this point in the history
* Reader: Teach the post preloader how to detect existing dimensions

Also, only try to preload 5 images max.

This cuts down on the number of images we need to transfer to load Reader pages and sigificantly speeds up how we choose what image to show.

* Teach various pieces of the reader to load smaller images

* Use consts for contants, update READER_CONTENT_WIDTH
  • Loading branch information
blowery authored Feb 15, 2017
1 parent f65de02 commit 90f9bcc
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 38 deletions.
5 changes: 4 additions & 1 deletion client/blocks/reader-post-card/featured-image.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ import { noop } from 'lodash';
* Internal Dependencies
*/
import cssSafeUrl from 'lib/css-safe-url';
import resizeImageUrl from 'lib/resize-image-url';

const FEATURED_IMAGE_WIDTH = 250; // typical width of a featured image in the refresh

const FeaturedImage = ( { imageUri, href, children, onClick } ) => {
if ( imageUri === undefined ) {
return null;
}

const featuredImageStyle = {
backgroundImage: 'url(' + cssSafeUrl( imageUri ) + ')',
backgroundImage: 'url(' + cssSafeUrl( resizeImageUrl( imageUri, { w: FEATURED_IMAGE_WIDTH } ) ) + ')',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: 'center center'
Expand Down
5 changes: 2 additions & 3 deletions client/blocks/reader-post-card/gallery.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import resizeImageUrl from 'lib/resize-image-url';
import cssSafeUrl from 'lib/css-safe-url';
import { isFeaturedImageInContent } from 'lib/post-normalizer/utils';
import ReaderPostCardExcerpt from './excerpt';

const GALLERY_ITEM_THUMBNAIL_WIDTH = 420;
import { READER_CONTENT_WIDTH } from 'state/reader/posts/normalization-rules';

function getGalleryWorthyImages( post ) {
const numberOfImagesToDisplay = 4;
Expand All @@ -31,7 +30,7 @@ function getGalleryWorthyImages( post ) {
const PostGallery = ( { post, children, isDiscover } ) => {
const imagesToDisplay = getGalleryWorthyImages( post );
const listItems = map( imagesToDisplay, ( image, index ) => {
const imageUrl = resizeImageUrl( image.src, { w: GALLERY_ITEM_THUMBNAIL_WIDTH } );
const imageUrl = resizeImageUrl( image.src, { w: READER_CONTENT_WIDTH / imagesToDisplay.length } );
const safeCssUrl = cssSafeUrl( imageUrl );
const imageStyle = {
backgroundImage: 'url(' + safeCssUrl + ')',
Expand Down
7 changes: 6 additions & 1 deletion client/blocks/reader-related-card-v2/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ import Gravatar from 'components/gravatar';
import FollowButton from 'reader/follow-button';
import { getPostUrl, getStreamUrl } from 'reader/route';
import { areEqualIgnoringWhitespaceAndCase } from 'lib/string';
import safeImageUrl from 'lib/safe-image-url';
import resizeImageUrl from 'lib/resize-image-url';

const RELATED_IMAGE_WIDTH = 385; // usual width of featured images in related post card

function FeaturedImage( { image, href } ) {
const uri = resizeImageUrl( safeImageUrl( image.uri ), { w: RELATED_IMAGE_WIDTH } )
return (
<div className="reader-related-card-v2__featured-image" href={ href } style={ {
backgroundImage: 'url(' + image.uri + ')',
backgroundImage: 'url(' + uri + ')',
backgroundSize: 'cover',
backgroundRepeat: 'no-repeat',
backgroundPosition: '50% 50%'
Expand Down
30 changes: 2 additions & 28 deletions client/lib/post-normalizer/rule-content-detect-media.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import getEmbedMetadata from 'get-video-id';
/**
* Internal Dependencies
*/
import { iframeIsWhitelisted, maxWidthPhotonishURL } from './utils';
import { iframeIsWhitelisted, maxWidthPhotonishURL, deduceImageWidthAndHeight } from './utils';
import { READER_CONTENT_WIDTH } from 'state/reader/posts/normalization-rules';

/** Checks whether or not an image is a tracking pixel
Expand Down Expand Up @@ -46,39 +46,13 @@ function isCandidateForContentImage( image ) {
return ! ( isTrackingPixel( image ) || imageShouldBeExcludedFromCandidacy );
}

function deduceImageWidthAndHeight( image ) {
if ( image.height && image.width ) {
return {
height: image.height,
width: image.width
};
}
if ( image.naturalHeight && image.natualWidth ) {
return {
height: image.naturalHeight,
width: image.naturalWidth
};
}
if ( image.dataset && image.dataset.origSize ) {
const [ width, height ] = image.dataset.origSize.split( ',' ).map( Number );
return {
width,
height
};
}
return {
width: 0,
height: 0
};
}

/** Detects and returns metadata if it should be considered as a content image
* @param {image} image - the image
* @returns {object} metadata - regarding the image or null
*/
const detectImage = ( image ) => {
if ( isCandidateForContentImage( image ) ) {
const { width, height } = deduceImageWidthAndHeight( image );
const { width, height } = deduceImageWidthAndHeight( image ) || { width: 0, height: 0 };
return {
src: maxWidthPhotonishURL( image.getAttribute( 'src' ), READER_CONTENT_WIDTH ),
width: width,
Expand Down
25 changes: 21 additions & 4 deletions client/lib/post-normalizer/rule-wait-for-images-to-load.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {
forEach,
map,
pull,
take,
} from 'lodash';

/**
* Internal Dependencies
*/
import { thumbIsLikelyImage } from './utils';
import { deduceImageWidthAndHeight, thumbIsLikelyImage } from './utils';
import debugFactory from 'debug';

const debug = debugFactory( 'calypso:post-normalizer:wait-for-images-to-load' );
Expand Down Expand Up @@ -81,7 +82,17 @@ export default function waitForImagesToLoad( post ) {
imagesToCheck.push( post.featured_image );
}

const knownImages = {};

forEach( post.content_images, function( image ) {
const knownDimensions = deduceImageWidthAndHeight( image );
if ( knownDimensions ) {
knownImages[ image.src ] = {
src: image.src,
naturalWidth: knownDimensions.width,
naturalHeight: knownDimensions.height
};
}
imagesToCheck.push( image.src );
} );

Expand All @@ -90,11 +101,17 @@ export default function waitForImagesToLoad( post ) {
return;
}

// convert to image objects to start the load process
let promises = map( imagesToCheck, promiseForURL );

const imagesLoaded = {};

// convert to image objects to start the load process
// only check the first 5 images
let promises = map( take( imagesToCheck, 5 ), ( imageUrl ) => {
if ( imageUrl in knownImages ) {
return Promise.resolve( knownImages[ imageUrl ] );
}
return promiseForURL( imageUrl );
} );

forEach( promises, promise => {
promise.then( image => {
// keep track of what loaded successfully. Note these will be out of order.
Expand Down
23 changes: 23 additions & 0 deletions client/lib/post-normalizer/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,26 @@ export function isFeaturedImageInContent( post ) {

return false;
}

export function deduceImageWidthAndHeight( image ) {
if ( image.height && image.width ) {
return {
height: image.height,
width: image.width
};
}
if ( image.naturalHeight && image.natualWidth ) {
return {
height: image.naturalHeight,
width: image.naturalWidth
};
}
if ( image.dataset && image.dataset.origSize ) {
const [ width, height ] = image.dataset.origSize.split( ',' ).map( Number );
return {
width,
height
};
}
return null;
}
2 changes: 1 addition & 1 deletion client/state/reader/posts/normalization-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import addDiscoverProperties from 'lib/post-normalizer/rule-add-discover-propert
* Module vars
*/
export const
READER_CONTENT_WIDTH = 720,
READER_CONTENT_WIDTH = 800,
PHOTO_ONLY_MIN_WIDTH = 440,
GALLERY_MIN_IMAGES = 4,
GALLERY_MIN_IMAGE_WIDTH = 350;
Expand Down

0 comments on commit 90f9bcc

Please sign in to comment.