Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Boston Ember.js - Lazy Loading Videos

Lauren Tan
January 15, 2015

Boston Ember.js - Lazy Loading Videos

Lightning talk by @sugarpirate_, presented at Boston Ember.js on 15/01/2015.

If you’re like me, every time you embed a video iframe into your app you feel a little dirty. Embedding an iframe means loading an entire html document and the crazy amounts of resources it brings along with it. What’s worse is having to embed multiple videos — you really start to feel the performance hit the more videos you add. While they have their benefits, we don't want to load them until we absolutely need them – this lightning talk briefly covers the simple addon I made to do just that.

https://github.com/poteto/ember-lazy-video

https://medium.com/delightful-ui-for-ember-apps/lazy-loading-videos-in-ember-7504a4abe34f

Lauren Tan

January 15, 2015
Tweet

More Decks by Lauren Tan

Other Decks in Programming

Transcript

  1. LAZY LOADING VIDEOS IN EMBER.JS ! @sugarpirate_ " @poteto #

    $ https://github.com/poteto/ember-lazy-video BOSTON EMBER.JS – 15TH JAN 2015
  2. // services/lazy-video-provider.js import Ember from 'ember'; import youtube from 'ember-lazy-video/lazy-video-providers/youtube';

    import vimeo from 'ember-lazy-video/lazy-video-providers/vimeo'; var YOUTUBE_REGEX = /^[a-zA-Z0-9_-]{11}$/; var VIMEO_REGEX = /^[\d]+$/; export default Ember.Object.extend({ youtube: youtube, vimeo: vimeo, getUrl: function(provider, endpoint, videoId, opts) { var params; opts = (typeof opts === "undefined") ? {} : opts; params = Ember.$.param(opts); return this._getProvider(provider, videoId)[endpoint](videoId) + '?' + params; }, getThumbnailUrl: function(provider, videoId) { return this._getProvider(provider, videoId).thumbnailUrl(videoId); }, ...
  3. _getProvider: function(providerName, videoId) { var provider; if (!providerName && videoId)

    { if (VIMEO_REGEX.test(videoId)) { providerName = 'vimeo'; } if (YOUTUBE_REGEX.test(videoId)) { providerName = 'youtube'; } } provider = this.get(providerName); Ember.assert('Couldn\'t determine provider from `videoId` or the provider supplied was invalid: ' + providerName, provider); return provider; } });
  4. // lazy-video-providers/youtube.js import Ember from 'ember'; export default { apiUrl:

    function(videoId) { return '//gdata.youtube.com/feeds/api/videos/' + videoId; }, embedUrl: function(videoId) { return '//www.youtube.com/embed/' + videoId; }, thumbnailUrl: function(videoId) { return Ember.RSVP.resolve('//img.youtube.com/vi/' + videoId + '/maxresdefault.jpg'); } };
  5. // lazy-video-providers/vimeo.js import Ember from 'ember'; export default { apiUrl:

    function(videoId) { return '//vimeo.com/api/oembed.json?url=http%3//vimeo.com/' + videoId; }, embedUrl: function(videoId) { return '//player.vimeo.com/video/' + videoId; }, thumbnailUrl: function(videoId) { var apiUrl = this.apiUrl(videoId); return new Ember.RSVP.Promise(function(resolve, reject) { Ember.$.getJSON(apiUrl).then(function(res) { resolve(res.thumbnail_url); }); }); } };
  6. // initializers/lazy-video.js import LazyVideoProviders from 'ember-lazy-video/services/lazy-video-providers'; export default { name:

    'flash-messages', initialize: function(container, application){ application.register('service:lazy-video-providers', LazyVideoProviders, { singleton: true }); application.inject('component:lazy-video', 'providers', 'service:lazy-video-providers'); } };
  7. // components/lazy-video.js import Ember from 'ember'; var on = Ember.on;

    var get = Ember.get; var set = Ember.set; export default Ember.Component.extend({ provider: null, isDisplayed: false, videoTitle: null, videoId: null, classNames: [ ‘lazyLoadContainer' ], attributeBindings: [ 'style' ], videoThumbnail: null, click: function() { this.set('isDisplayed', true); }, videoSrc: Ember.computed('provider', 'videoId', function() { var providers = get(this, 'providers'); var provider = get(this, 'provider'); var videoId = get(this, 'videoId'); return providers.getUrl(provider, 'embedUrl', videoId, { autoplay: 1 }); }), _getVideoThumbnail: on('didInsertElement', function() { var providers = get(this, 'providers'); var provider = get(this, 'provider'); var videoId = get(this, 'videoId'); var _this = this; providers.getThumbnailUrl(provider, videoId).then(function(res) { set(_this, 'videoThumbnail', res); }); }), style: Ember.computed('videoThumbnail', function() { var thumbnail = get(this, 'videoThumbnail'); return 'background-image: url(' + thumbnail + ')'; }) });
  8. <!-- templates/components/lazy-video.hbs --> {{#if isDisplayed}} <iframe {{bind-attr src=videoSrc}} width="100%" height="100%"

    frameBorder="0" allowFullScreen></iframe> {{else}} {{#if template}} {{yield}} {{else}} <div class="lazyLoad-play"> <svg>...</svg> </div> {{/if}} {{/if}}