2013-02-19 11 views
5

Ieri ho deciso di migliorare il modo in cui il mio sito web carica i video di YouTube solo incorporandoli quando un utente li richiede. A volte una pagina può contenere fino a 30 video e questo richiederebbe molto tempo per essere caricato.Primo tentativo di caricamento lento (posticipazione del carico di video di YouTube incorporati): come posso farlo con più garbo?

Questa è la prima volta che ho tentato un metodo "lazy loading" di qualsiasi cosa, e ho pensato che sarebbe valsa la pena chiedere:

Che cosa posso fare per migliorare su questo?

Come posso renderlo un po 'più elegante?

Questo manca completamente il punto di caricamento differito?

JSFiddle.

Ignora lo stile poiché è irrilevante qui.


Il modo in cui funziona è quello di prima immissione un'ancora nella pagina contenente l'ID del video:

<a href="#" data-video="FzRH3iTQPrk" class="youtube-video"> 

Il jQuery dietro poi loop attraverso ogni a.youtube-video e crea un arco trasparente con miniatura del video come il suo sfondo:

$('a.youtube-video').each(function() { 
    var videoId = $(this).attr('data-video'); 
    var videoThumbnail = "http://img.youtube.com/vi/" + videoId + "/0.jpg"; 

    var videoBackground = $('<span class="youtube-thumbnail"></span>'); 

    videoBackground.css({ 
     background:"#fff url('"+videoThumbnail+"') no-repeat" 
    }) 
    ... 

E 'quindi modifica lo stile del tag di ancoraggio (questo è fatto qui per evitare che interessano i browser con JavaScript disabilitato):

$(this).css({ 
     height:315, 
     width:460, 
     position:"relative", 
     display:"block", 
     textAlign:"center", 
     color:"#fff", 
     fontSize:26 
    }); 

E poi finisce il ciclo con l'aggiunta del brano a l'ancora:

$(this).text('Click to load video'); 
    $(this).append(videoBackground); 
}); 

Il caricamento dell'oggetto video di YouTube incorporato si verifica l'ancora clic:

$('a.youtube-video').click(function(e) { 
    e.preventDefault(); 
    var videoId = $(this).attr('data-video'); 
    var videoThumbnail = "http://img.youtube.com/vi/" + videoId + "/0.jpg"; 
    var videoEmbed = $('<object> ... </object>');  
     ... 

Questo termina aggiungendo il codice di incorporamento al padre dell'ancora e rimuovendo l'ancora:

$(this).parent().append(videoEmbed); 
    $(this).hide(); 
}); 
+0

Che cosa stai usando il videoThumbnail sul gestore clicca per? Sto lavorando a qualcosa di simile, e un problema che ho riscontrato è la quantità di ripetizioni che si verificano per ogni video. La tua esperienza potrebbe essere diversa. Inoltre, considera la riproduzione automatica del video dopo il clic iniziale, in modo che gli utenti non debbano fare clic due volte. – lrusli

+0

Ah, l'ho rimosso ora. Era per il momento in cui inizialmente usavo le piccole miniature - a clic si espandeva l'immagine e la si sostituiva con la miniatura più grande. –

+2

Hai dato un'occhiata all'API di YouTube per incorporare comodamente i video, hanno un jS api (https://developers.google.com/youtube/js_api_reference) e un iframe api (https://developers.google.it/youtube/iframe_api_reference) – Arindam

risposta

4

È necessario impostare l'href in modo che le persone sappiano cosa stanno per essere caricati. Questo può essere fatto sull'elemento quando viene generata la pagina o in JS. Deve essere sull'elemento se vuoi che la tua pagina funzioni per le persone che hanno Javascript disabilitato.

var url = "http://www.youtube.com/watch?v=" + videoId; 
$(this).attr('href', url); 

Si dovrebbe anche dire alla gente che cosa accadrà se si clicca o impostando un titolo:

$(this).attr('title', "Click to play video"); 

o creando un overlay come quelli al SMH che lo rende più evidente che cliccando su l'immagine riprodurrà un video. O entrambi.

Inoltre, non è necessario interrompere l'apertura di una nuova finestra quando le persone tengono premuto CTRL o il tasto di comando.Ho aggiornato il fiddle ma fondamentalmente nel vostro evento click è necessario scaricare:

var isCtrlPressed = e.ctrlKey || e.metaKey; 
if (isCtrlPressed == true){ 
    return; 
} 

So che hai detto ignorare lo stile, ma io preferirei che un segnaposto ha un colore di sfondo che è ovviamente diverso dallo sfondo della pagina. Se una pagina è a caricamento lento, posso dire che qualcosa verrà caricato lì, piuttosto che essere un bit di pagina vuoto.

Questo manca completamente il punto di caricamento differito?

Non del tutto, ma in questo caso è leggermente inutile. Il caricamento differito viene solitamente utilizzato quando la cosa che viene caricata è molto complessa (ad esempio una tabella enorme) e quindi aggiungerebbe molto alla dimensione della pagina, il che renderebbe il rendering iniziale della pagina molto tempo dopo che l'utente ha seguito il collegamento .

Anche se i video di YouTube possono essere lenti da caricare, non dovrebbero in realtà bloccare il caricamento della pagina e il rendering nel frattempo, quindi posticipare il caricamento dei video offre solo un piccolo vantaggio per un bel po 'di lavoro.

Immagino che dovresti misurare quanto velocemente qualcuno può visualizzare una pagina, scorrere fino in fondo e quindi fare clic per riprodurre l'ultimo video. Se è più veloce con il caricamento differito, poiché gli altri video non sono caricati, il lettore flash potrebbe comunque valerne la pena.

1

C'è un jsfiddle del codice sottostante here. (Il player non appare correttamente, penso che jsfiddle non funzioni bene con il "metodo embed" .So che funziona su jsfiddle usando il metodo iframe ma hai accennato che volevi evitare iframe).

Un grande miglioramento, come già accennato, è utilizzare swfobject per generare l'embed giocatore. Quando si utilizza questo metodo, è necessario creare un segnaposto per l'elemento giocatore. Il segnaposto verrà rimosso e sostituito con l'embed quando si fa clic sul collegamento. Consiglio vivamente di creare un div genitore per il link e il player. Per evitare il ridimensionamento degli elementi quando l'embed sta generando, devi anche impostare esplicitamente la larghezza/altezza dell'elemento contenitore.

Penso che questo sia un buon uso del caricamento differito. Anche se i flash player non bloccano il caricamento, usano ancora molte risorse e apprezzerei una pagina che inizialmente si presenta come un set di miniature.

Markup

<script src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"> 
</script> 

<div class="container"> 
    <div id="placeholder_FzRH3iTQPrk"></div> 
    <a href="#" data-video="FzRH3iTQPrk" class="youtube-video"></a> 
</div> 
<div class="container"> 
    <div id="placeholder_go43XeW6Wg4"></div> 
    <a href="#" data-video="go43XeW6Wg4" class="youtube-video"></a> 
</div> 

JavaScript

$(document).ready(function() { 
    $('a.youtube-video').each(function() { 
     var videoId = $(this).attr('data-video'); 
     var videoThumbnail = "http://img.youtube.com/vi/" + videoId + "/0.jpg"; 
     var videoBackground = $('<span class="youtube-thumbnail"></span>'); 
     videoBackground.css({ 
      background:"#fff url('"+videoThumbnail+"') no-repeat" 
     }); 

     // also set the parent container size to prevent flicker 
     $(this).add($(this).parent()).css({ 
      height:315, 
      width:460, 
      position:"relative", 
      display:"block", 
      textAlign:"center", 
      color:"#fff", 
      fontSize:26 
     }); 
     $(this).text('Click to load video'); 
     $(this).append(videoBackground); 
    }); 

    $('a.youtube-video').click(function(e) { 
     e.preventDefault(); 
     var videoId = $(this).attr('data-video'); 
     var params = { allowScriptAccess: "always", allowFullScreen: "true" }; 
     var atts = { id: 'player_'+videoId }; 
     $(this).hide(); 
     swfobject.embedSWF(
      "http://www.youtube.com/v/"+videoId+"?enablejsapi=1&playerapiid=ytplayer&version=3", 
      'placeholder_'+videoId, "460", "315", "8", null, null, params, atts); 

    }); 
}); 
+0

Hai lo stesso link due volte e nessun collegamento a un violino ... – Danack

+0

Grazie, corretto .. –

Problemi correlati