Preprocess is improperly set to TRUE in system_library for jquery and jquery.once. The patch here fixes this.

I marked this as critical because of the front end performance impact.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sun’s picture

Title: Preprocess is misdefined in system_library() » drupal_add_library() requires $options to set 'preprocess'
Component: system.module » base system
Status: Needs review » Needs work

#769226-189: Optimize JS/CSS aggregation for front-end performance and DX:
As mentioned over there, instead of changing this, we have to fix drupal_add_library() instead. Libraries being shipped with code are buried into code. They cannot decide upfront whether they are going to be used on all pages or only some pages, and whether aggregation would make sense, and therefore, a registered library cannot do any judgment on as to whether 'preprocess' should be TRUE or FALSE.

Only the caller knows. Therefore, we have to introduce $options for drupal_add_library().

mfer’s picture

Title: drupal_add_library() requires $options to set 'preprocess' » Preprocess is misdefined in system_library()
Component: base system » system.module
Status: Needs work » Needs review

@sun - This is a bug that exists in core. Updating drupal_add_library() to add a feature that introduces an API change which there is not even a patch for yet is something else.

Let's get this bug fix in here and see where the feature/API change happens on the other issue. It may not happen until D8. The bug fix should not be held up because of that.

sun’s picture

Status: Needs review » Needs work

You don't seem or want to understand. We have to fix the cause, not the effect. Your patch replaces a bug with a bug.

Fixing the real bug is a matter of minutes.

mfer’s picture

Status: Needs work » Needs review

@sun I do understand what you are pointing out with drupal_add_library(). I see a bug in the current implementation and an issue with the nature of drupal_add_library(). I am clear on what you mean.

But, we are after the code freeze, what you propose is an API change, and we do not know if that API change will be allowed in D7. So, in the meantime lets fix this bug.

If the other issue gets handled, great. If not, this needs to be fixed.

The other issue is not moving on a clear path, is lacking code, and is running out of time. It may well have to wait until D8. This bug needs to be fixed in D7.

sun’s picture

Issue tags: +API change
FileSize
1.3 KB

Stepping through the code, I just see that we have some more bugs, so an API change is required.

http://api.drupal.org/api/function/drupal_add_library/7 calls into
http://api.drupal.org/api/function/drupal_process_attached/7 with special arguments (that should be $options), but which is also called from

http://api.drupal.org/api/function/drupal_render/7 as well as
http://api.drupal.org/api/function/drupal_render_cache_get/7, which both do not pass the special arguments.

Effectively, #attached][library behaves differently when an element is served and rendered from cache, entirely losing the originally intended weight and dependency check.

I wasn't aware that the current implementation is that fragile. But now we apparently have even more reasons to require a proper $options handling for libraries.

mfer’s picture

@sun nice catch on the bug in drupal_render_cache_get(). This can be fixed without changing the API. Is there a reason the API change cannot wait until D8?

sun’s picture

Status: Needs review » Needs work

The caller has to decide and specify whether a library needs to be aggregated or not. It is utterly wrong and impossible to decide that upfront and hardcode it into hook_library().

The same applies to the weight.

mfer’s picture

Issue tags: -API change

@sun I have two issues with changing the API:

  1. The API is frozen. Not everything is perfect. If we wait for everything to be perfect we will never release.
  2. Adding an $options array with weight and preprocess at the caller level is not so simple. There are architectural decisions that have been made and would need to be altered and discussed. For example, should the caller or definer of a library specify the weight? Should the definer provide a default weight that can be overridden? Or, something else? This takes time to work out and is an API change to implement. By our place in the cycle this waits for D8.

I'm inclined to say the functionality is what it is. We are now fixing bugs in that functionality. New features or feature changes go in D8. That means the $options array needs to wait and bug fixes go in for now. Unless Dries or webchick say differently and give this change a pass.

tstoeckler’s picture

I think sun's very point is that it makes absolutely no sense for the definer to specify a weight, because he cannot know when and how and why a library is being loaded.

Also in #5 sun outlines that currently a library is inconstently loaded, depending on whether it goes through the render pipeline or not. So in order for the preprocess functionality to be remotely useful (and yes, we want that in D7!), it seems, we need to fix that behavior anyway. So instead of making a broken behavior consistently broken, we should fix it.

mfer’s picture

@tstoeckler The render pipeline issue is a bug in the current system. The $options is something different and it is in fact a place the definer may know more.

For example, say a library consists of 3 JavaScript files with a specific dependency ordering. A library is not a file, it's a collection of JS and CSS. The definer can know the dependency order of the JS files and provide the proper weighting. How can the caller of the library properly specify the weight for all the files? Should the caller even care about the ordering of the dependent files or just that adding the library works as expected?

This is not a simple problem. Working through it means we need to make certain assumptions. It is a change in functionality rather than a bug that needs to be fixed. The current system works on a different set of assumptions from the one he specified.

The preprocessing issue is interesting because the preprocess changes were brought in late in the game. They are, also, not so simple to deal with. Should all the JS files in a library be preprocessed? If two invocations call two different preprocess settings who wins?

While I do believe we need to work through all of this that does not mean it is right for D7. We are frozen and bug fixing. Working out the ins and outs of features is done unless granted an exception.

Damien Tournoud’s picture

The caller has to decide and specify whether a library needs to be aggregated or not. It is utterly wrong and impossible to decide that upfront and hardcode it into hook_library().

The same applies to the weight.

I cannot disagree more. Libraries are generic, shared code. As a consequence:

  • They can be loaded several times by different modules on the same page. As a consequence, their weight has to be fixed and cannot be defined by the caller.
  • jQuery is used in mostly every page, as a consequence it should be preprocess => FALSE. On the other hand, most of the other libraries will be seldom used, they should define themselves preprocess => TRUE.
mfer’s picture

Status: Needs work » Needs review

@Damien The current preprocess effort is about limiting the number of preprocess files to avoid downloading duplicates. So, all the common stuff should be included on every page and part of a preprocessed file while the files included on a limited number of pages are not preprocessed. This avoids downloading duplicate content. If you disagree with this please see #769226: Optimize JS/CSS aggregation for front-end performance and DX.

Until Dries or Webchick give the $options direction a go ahead I'm pursuing fixing the bugs in the current implementation. For another else please open a different issue as this is not the appropriate place.

It turns out there is no issue in #5 and the usage is consistent. Both drupal_render and drupal_render_cache_get use the same arguments for drupal_process_attached. If there is a library in either case they are both passed into drupal_add_library which is consistent in its use both times. There should not be an issue of weights. That means the original patch of system_library_preprocess_oops.patch is still good. I tested and it still applies against head.

Can we please fix this issue and deal with other aspects, features, and possibilities in other issues.

Damien Tournoud’s picture

@Damien The current preprocess effort is about limiting the number of preprocess files to avoid downloading duplicates. So, all the common stuff should be included on every page and part of a preprocessed file while the files included on a limited number of pages are not preprocessed. This avoids downloading duplicate content.

No. Big stuff included in every page: preprocess => FALSE. If you preprocess a big stuff included in every page, you will download it several times.

sun’s picture

@Damien, that's only true, if aggregates happen to be broken up unexpectedly. That's the whole point of why we're discussing that remaining challenge over in #769226: Optimize JS/CSS aggregation for front-end performance and DX. It definitely makes no sense to not aggregate libraries that are unconditionally loaded on all pages. It's the (un)conditional loading that matters, not the library size.

ksenzee’s picture

Status: Needs review » Reviewed & tested by the community

This issue was meant to be a simple fix for an oversight in #769226: Optimize JS/CSS aggregation for front-end performance and DX. Everyone on that issue agreed it was an oversight. Let's get that taken care of before we debate anything else. #0 is RTBC.

Damien Tournoud’s picture

webchick’s picture

Status: Reviewed & tested by the community » Fixed

I got a bit turned around by this issue, but consulted mfer and ksenzee on IRC. The point of this patch (#0 anyway) is to fix a simple syntax issue where 'preprocess' => TRUE is in the wrong place. That seems like a straight-forward fix, with anything fancier than that being covered in The Soul Sucking Critical That Would Not Die, aka #769226: Optimize JS/CSS aggregation for front-end performance and DX.

Committed #0 to HEAD.

Status: Fixed » Closed (fixed)

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