This is about dev as well as 7.1.1.

I looked into 'sites\default\files\css' dir and noticed that there are big CSS files: 100+ kb. I looked at them and noticed that they are big because they contain css code which repeats 4 - 5 times in the file. Same code repeats in one file and makes it very big. What can be the reason of this behavior?

CommentFileSizeAuthor
#1 css_pNpXnubWfr.css_.txt7.45 KBralf.strobel

Comments

ralf.strobel’s picture

Title: Duplicates same css code multiple times in a css file » Same css code multiple times in one file
Priority: Critical » Major
StatusFileSize
new7.45 KB

Confirmed. What I often see is that a generated file contains the exact same content twice.

I'm attaching an example. It seems like the source file (system.admin.css) was processed twice.

ralf.strobel’s picture

Status: Active » Needs review

Ok, I have identified the problem...

agrcache_build_aggregate_cache() uses two different hash functions to create $key and $uri. The key is based on the raw data structure ($files), while the aggregated file uri is based on the generated content ($data).

In some cases, it happens that two different $files structures lead to the same $data output. (In my case it was due to some simple rounding deviation in weight attributes, which made the file sets appear different.) At this point, two different values for $key point to the same $uri.

The problem then continues in agrcache_add_to_variable(), which uses array_merge_recursive() on the uri-keyed callback map array. And since the contained file entries are stored with numeric keys, array_merge will append them so that they appear multiple times (once for each key associated with the uri).

The first part seemed difficult to fix, and the behavior is actually correct, so instead I wrote a replacement for the add function, which only merges the arrays one level deep...

function agrcache_add_to_variable($name, $values, $default = array()) {
  // ...
  $result = db_query('SELECT value FROM {variable} WHERE name = :name', array(':name' => $name))->fetchField();
  if ($result) {
    $variable = unserialize($result);
  } else {
    $variable = $default;
  }
  foreach ($values as $key => $value){
      $variable[$key] = !empty($variable[$key]) && is_array($variable[$key]) ? array_merge($variable[$key], $value) : $value;
  }
  variable_set($name, $variable);
}

That has fully fixed the problem for me.

catch’s picture

Status: Needs review » Closed (duplicate)

The array merge bug was fixed in another commit some time ago, marking duplicate.