Hi,

In order to improve performances, we should defer the loading of the Youtube videos after that the document is fully loaded.
I did a patch in order to put the source url of the video into a "data-src" attribute, and set the real "src" attribute with some JS only when the document is fully loaded.

The patch should be applied after the one I've done in this issue #2879018 because I've reorganized JS into a folder in this issue.

Thank you for reading this.

CommentFileSizeAuthor
#47 scald_youtube-defer_videos_loading-2881646-47.patch15.04 KBphjou
#46 scald_youtube-defer_videos_loading-2881646-46.patch15.12 KBphjou
#40 scald_youtube-defer_videos_loading-2881646-40.patch15.17 KBphjou
#40 scald_youtube-defer_videos_loading-2881646-40.patch15.17 KBphjou
#38 interdiff.txt784 bytesnagy.balint
#38 scald_youtube-defer_videos_loading-2881646-38.patch30.57 KBnagy.balint
#34 scald_youtube-defer_videos_loading-2881646-34.patch11.35 KBphjou
#31 scald_youtube-defer_videos_loading-2881646-31.patch14.88 KBphjou
#29 scald_youtube-defer_videos_loading-2881646-29.patch14.55 KBphjou
#24 interdiff.txt7.19 KBnagy.balint
#24 scald_youtube-defer_videos_loading-2881646-24.patch12.11 KBnagy.balint
#23 scald_youtube-defer_videos_loading-2881646-23.patch7.84 KBphjou
#20 scald_youtube-defer_videos_loading-2881646-20.patch7.53 KBphjou
#18 scald_youtube-defer_videos_loading-2881646-18.patch7.75 KBphjou
#16 scald_youtube-defer_videos_loading-2881646-16.patch3.05 KBphjou
#14 scald_youtube-defer_videos_loading-2881646-13.patch3.01 KBphjou
#7 scald_youtube-defer_videos_loading-2881646-7.patch3.02 KBphjou
#3 scald_youtube-defer_videos_loading-2881646-3.patch2.12 KBphjou
#2 scald_youtube-defer_videos_loading-2881646-2.patch1.36 KBphjou
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

phjou created an issue. See original summary.

phjou’s picture

phjou’s picture

FileSize
2.12 KB
nagy.balint’s picture

Hi!

Thanks for the patch!

Can you test what happens with these videos if you check them inside the wysiwyg?

I have a suspicion that neither the css or the js will apply inside the wysiwyg.

phjou’s picture

Indeed it's not working. The video is correctly loaded when the wysiwyg is rendered in front, but when editing the content in the backoffice it's broken.

I will correct this.

- We can disable the "defer loading" feature in the backoffice.

- We can listen to every change in the DOM and load the video when we see the scald-youtube class but it's heavy.
We can also listen only the wysiwyg div to detect changes.

I prefer the first solution, it's simplier. And the wywisyg already use a lots of JS, so I think it's better to avoid adding more. What do you think about this?

nagy.balint’s picture

Its fine for me.

phjou’s picture

So, it seems that we cannot test if we are in an admin page with is_admin_path function because the path "scald/library_dnd" used by the dnd library is not defined as an admin path.
So I've just tested directly the path in order to know if we are in a dnd context. Now dragging a video into the wysiwyg works :D

I also finally added a listener in order to support when the video is added dynamically in javascript. Videos are often in popins and the content of a popin is generally added by javascript, so I think it's important afterall.

nagy.balint’s picture

Hi!

Im afraid I have the same issue with this patch. It works fine on display, but when I'm on the node edit page, the wysiwyg will only show some iframe frameborders and nothing else.

Of course its not a big deal if we only show a placeholder instead of the playable video (if it looks good), but at least before this patch the video was there and playable, so it is what you see is what you get.

Although im not sure why checking for "scald/library_dnd" would work, as the current path should be like node/*/edit, or any edit form or pane where the dnd appears.

So it is possible if its not easy to detect whether this is needed or not, we might need to extend Scald core to provide this mechanism.

Until now we used hook_scald_wysiwyg_context_list_alter to detect when the dnd is active on a page. However in this case this might not be enough.

phjou’s picture

I agree that we can't accept a patch if it does not render the video correctly.

The problem could be corrected by adding the scald_youtube_player.js file into the wysiwyg iframe. But I've searched a little and it seems really complicated. If you know a way to do that, I'm interested. If we can do that, we can forget about detecting the dnd thing.

Concerning the path, I've printed the current path into the video template and it was returning "node/*/edit" when the video was rendered at the page loading and "scald/library_dnd" when we add a video using dnd.

I've tried to reproduce the problem of the iframe frameborders, but I can't for now.
I've updated scald to the last version because I was using 2.6 but it doesn't change anything. I also tried to disable the "Scald SAS conversion" into the wysiwyg profile, but it was not successfull either.

I will install a new drupal website to test the patch and try to reproduce the problem because it is working on my project but there are some patches on scald and some custom code to have ESI blocks on videos (normally not used when we're connected).

nagy.balint’s picture

Im using div attributes under "Wysiwyg store format".
Also im using the iframe mode of the ckeditor as it comes by default.

nagy.balint’s picture

Maybe the issue is that in the ck4 widget version which is the "div attributes", it will render the atoms in edit pages using ajax calls to
"atom/ajax-widget-expand/197?context=sdl_editor_representation&options=%257B%257D&align=none"

phjou’s picture

Yes, I've installed a brand new drupal website and the ajax calls is also done on "atom/ajax-widget-expand/1".

Checking "atom/ajax-widget-expand/*" and "scald/library_dnd" works in both cases, but the code seems pretty ugly...

nagy.balint’s picture

So maybe scald core could be extended to provide a way to detect that.

phjou’s picture

Searching the problem in the scald commits to find the difference, I found something interesting. Checking that the path is an admin path works.

I was with the scald 1.6 version and the 1.7 version includes this issue #2410373 that add "scald/library_dnd" as an admin path.

It works on my both websites after updating scald version. There is just one little problem, when we look at the patch of the issue that add "scald/library_dnd" as an admin path (#2410373 patch), we can see that we need to set the "dnd_modal_admin" variable to "1" in order to have an admin path. It can be set in "admin/config/content/dnd". I don't know why they let the choice to the administrator...

But if this config is not set to TRUE, we will have the problem of the iframe frameborders (only when we use "scald/library_dnd" path). Should we create a config form in order to enable/disable the "defer" feature manually and add a description to notice the administrator about the dnd_modal_admin variable?

phjou’s picture

I will search if scald core provide something which could help us.

phjou’s picture

I searched into scald core but I couldn't make it work using some hook from the core :(

It seems that the dnd library use admin paths to render atoms in ajax. So I just test that it is an admin path and I add an exception for the "scald/library_dnd" which depends on administrator choice. So it should work on all cases now.

nagy.balint’s picture

Unfortunately it still does not work for me.

On my instance the "atom/ajax-widget-expand" is not admin.

So we need a more robust solution.

We can add code to scald core to have a more consistent way of detecting it, but then of course the dependency of the next version will be the latest scald core.

phjou’s picture

I didn't manage to make this work, so I've worked on my original approach that is defer the videos into the wysiwyg too. It works pretty well on my configuration, I think it should be ok. I thought it was more complicated than disable into the backoffice but I was wrong.

So in order to test this:
- By default the defer features is disabled, you need to enable it in /admin/config/content/scald
- I've created a wysiwyg plugin that will add the JS we need into the iframe in order to load Youtube videos. So you also need to enable the plugin for your wysiwyg profile when the Defer features is enabled. I've written this in the description of the field in the configuration page.
- After that it should be working in all cases.

I've also corrected the javascript for Internet Explorer, I was using a function that was not defined in IE.

nagy.balint’s picture

Im not entirely sure why the "DOMSubtreeModified" is needed.

In theory the behaviors are called on markup that is inserted with js, and also when first displaying the page.

And if its not scald related popup that has a youtube video, then anyways this provider does not have to deal with that.

Can you describe which use case im missing?

phjou’s picture

I was thinking about when your render an atom in autoplay in the page but you want to stay hidden and quiet waiting for a click to open a popin. The developer can keep the rendering of the scald into a data-attribute and insert it when opening the popin.

But I think it is probably not the right way to do that, an ajax call to get the rendering of the atom is probably better. 'DOMSubtreeModified' could be quite heavy so removing it, is a good idea in order to avoid multiple calls to that javascript. You're right.

I've just removed it in the last patch.

phjou’s picture

I launch the test but I totally forgot that the patch needed the other one from #2879018

nagy.balint’s picture

Hi!

1) It seems to me that
"window.onload = initializeYoutubeVideos;"
Is not needed, cause the behavior anyways will only run when the DOM is loaded, and if the behavior is called again, this wont really work i think.

2) Also initializeYoutubeVideos should really only work inside the context (parameter of the behavior), and not call the function for the whole document every time the behavior is called.

3) "If this checkbox is checked, the loading of the Scald Youtube videos will be defered at the end. You must enable the 'Defer Youtube videos' plugin into your wysiwyg profile in order to see your videos into your wysiwyg."

=>

"If this checkbox is checked, the loading of the Scald Youtube videos will be deferred to the end. You must enable the 'Defer Youtube videos' plugin in your WYSIWYG profile in order to see your videos in your WYSIWYG."

4) There seem to be an empty class in the css file and no new line at the end
+.cke_button__scald_youtube_defer_button {
+
}

5) We should put the configuration in the Scald Youtube configuration fieldset:
$form['defaults']['scald_youtube'] = array(

I like the idea of making this an option, so its easier to commit the feature, and even if it causes any trouble, its just something that can be disabled.

phjou’s picture

I've corrected all your suggestions. I hope it's ok.

Conerning the CSS, I think I forgot to add the file for the previous patch. I'm hiding the ckeditor button which is required to add the JS but useless for the user.

nagy.balint’s picture

For me the js did not work after the "context" addition, so i rewrote it with jQuery, anyways we should have it present on all pages.

For me the plugin seems to be not needed, maybe the pre_render is enough there?

At least I turned on the defer, and it still works in ckeditor, and also outside.

I attach my version and interdiff, and we can test once more.

I also simplify the process and merge with the other patch.

nagy.balint’s picture

Status: Active » Needs review
nagy.balint’s picture

And I moved the defer option, as it should be in the scald video type edit form, where the rest of the config is for that type.

nagy.balint’s picture

Although I'm using the Ckeditor module, maybe the plugin is only needed for the wysiwyg module?

phjou’s picture

Status: Needs review » Active

I watched your modifications.
The configuration of the defer option is indeed in a better place now. I hadn't understood your comment, I thought it was just a field group.

I use the wysiwyg module and not the ckeditor one. It is not working anymore with your patch.
CKEditor uses an iframe so I suppose that the CkEditor module adds JS files put in the #attached inside the iframe otherwise I don't see how it could work.

I searched into the Wysiwyg module an issue concerning adding custom JS files. There is one (#1126656) but they say that the Wysiwyg module supports several editors that not use iframes, so if we want to add custom JS, we have to create a plugin. So I think we should keep the plugin in order to keep wysiwyg compatibility.
And if we don't keep compatibility with wysiwyg, we should merge scald_youtube_player_library.js and scald_youtube_player.js which were separated in order to be used again into the plugin.

phjou’s picture

I just did the patch again keeping the wysiwyg plugin, in case we keep it.

nagy.balint’s picture

Status: Active » Needs review

Thanks for all the work on this issue.

One last point and I think I will commit it:

in scald_youtube_scald_prerender the
drupal_get_path('module', 'scald_youtube') . '/js/scald_youtube_player_library.js',
drupal_get_path('module', 'scald_youtube') . '/js/scald_youtube_player.js'
Are attached even if the defer option is disabled.

Also i guess we could call those JS es scald_youtube_defer
and scald_youtube_defer_library, as because its possible to disable it, if we need other JS we will likely put it in another js file.

I guess we can add at the end here
"If this checkbox is checked, the loading of the Scald Youtube videos will be deferred to the end. The cache has to be cleared for the changes to take effect."

That
"If you use the WYSIWYG module, you must enable the 'Defer Youtube videos' plugin in your WYSIWYG profile."

phjou’s picture

Ok I've applied your modifications.

I've also noticed that it was buggy into the CkEditor iframe using wysiwyg. I didn't noticed it because of my browser cache. JQuery is not loaded into the iframe with wysiwyg, so we got an error when we call the 'initializeYoutubeVideos' function.

So I used my previous function written in native JS. And I've corrected the error about the context in comment #24. Native JS should work everywhere now.

Thanks a lot for your help, it is really formative and it shows me that it is very hard to think about all the cases.

nagy.balint’s picture

Status: Needs review » Needs work

Unfortunately for me this javascript does not work in iframe.

VM2835:10 Uncaught TypeError: Cannot read property 'querySelectorAll' of undefined
at initializeYoutubeVideos (eval at (jquery.min.js?v=1.7.2:2), :10:34)

nagy.balint’s picture

I have two text fields. Both have one youtube atom in it.

However it calls the function twice where i printed context, and contextUsed after the first line.
I got the following twice:
$.fn.init(1)
VM3524:11 div
VM3524:10 div.cke_widget_element.dnd-widget-wrapper.context-sdl_editor_representation.type-video
VM3524:11 undefined

phjou’s picture

In order to debug this, I'm interested to know your configuration. I was testing with Firefox 54 Linux.

var contextUsed = (typeof context !== 'undefined' && context !== document ? context[0] : document);

For me context can be the document itself or a jQuery object but I think there is a third case, it can be a DOM reference. I can't test this this week end but I will on Monday.

VM3524:10 div.cke_widget_element.dnd-widget-wrapper.context-sdl_editor_representation.type-video

This line is directly a reference to the DOM or a jQuery object? I think it is the first case by looking at your code which was working.

The code below could work, I will test it on Monday and see if I can reproduce your problem.

var contextUsed = (typeof context !== 'undefined' && context !== document ? context : document);
// If we have a jQuery object, extract the DOM element.
if (typeof context[0] !== 'undefined') {
  contextUsed = context[0];
}
phjou’s picture

phjou’s picture

Just failed to do a correct patch on Windows so I will do it again correctly on Linux on Monday and test it ;)

nagy.balint’s picture

Yes I think, thats the issue.

nagy.balint’s picture

Here is the patch with your code addition. Seems to be working for me.

nagy.balint’s picture

Status: Needs work » Needs review
phjou’s picture

I've corrected coding standards for JS and PHP files.

And I've just added one test in the JS because for some reason the JS is called with an empty context when I drag a scald and context[0] cause an error.

// If we have a jQuery object, extract the DOM element.
  if (typeof context !== 'undefined' && typeof context[0] !== 'undefined') {
    contextUsed = context[0];
  }

I think we finally reach the end of this issue :)

phjou’s picture

phjou’s picture

Sorry, I've uploaded the same patch twice, don't really know how I did that.

nagy.balint’s picture

And now i get "VM2096:17 Uncaught ReferenceError: initializeYoutubeVideos is not defined"
Not sure what changed that could cause that.

nagy.balint’s picture

Status: Needs review » Needs work

Using patch 38 it still works fine.

nagy.balint’s picture

Not sure what it could be, maybe use strict is an issue?

phjou’s picture

Sorry about the delay for my answer, I was very busy.

"use strict" is just a javascript coding standard, it is not an issue at all. But it is strange because it doesn't crash in my browser.
So I've done one version of the patch without the use strict if you want to test.

phjou’s picture

And I've also done a patch which add only the necessary JS test for me in addition to your patch.
Maybe I've done a modification in the coding standards that was buggy, so I've remove all the other modifications.

nagy.balint’s picture

"use strict" is not just a javascript coding standard.
It does modify how the engine interprets the javascript.

https://www.w3schools.com/js/js_strict.asp

With that it throws more errors that otherwise it would ignore.

phjou’s picture

I know but I can't reproduce the error on my environment ( Firefox 55 and Chrome 58 on Ubuntu 14).

So should we test the patch #46 wich just remove "use strict" ?
Or there is the patch #47 which is normally the same as yours in #38 but with an additionnal test in order to avoid an error when the context is not defined.

  • nagy.balint committed aa88465 on 7.x-1.x authored by phjou
    Issue #2881646 by phjou, nagy.balint: Defer Youtube video loading
    
nagy.balint’s picture

Status: Needs work » Fixed

Thanks!

Committed #46 as it works for me.

We can have follow up issues if needed.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.