最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - JavaScript: Advantages and disadvantages of dynamically (on fly) creating style element - Stack Overflow

programmeradmin0浏览0评论

In JavaScript we can create <style> element dynamically and append to <head> section in order to apply CSS rule for huge number of elements.

  1. What is advantages or disadvantages of this approach?

  2. If it is really gives performance gain paring to javascript iteration over elements. What goes behind the scene (inside of browser)?

  3. Which one is faster or slower? Javascript iteration over elements or adding css dynamically in browser?

  4. What about processing time? processing load?

For better understanding the issue where I used this approach see following example:

Example: If I have table with 20 or more columns and 1000 rows or more as following html:

<table border="1" class='no-filter'>
    <thead>
        <tr>
            <th data-title='id'>Id</th>
            <th data-title='name'>Name</th>
            <th data-title='family_name'>Family Name</th>
            <th data-title='ssn'>SSN</th>
            //Other table data
        </tr>
    </thead>
    <tbody>
        <tr data-id='1' data-name='nick' data-famil_name='jackson' data-ssn='123456'>
            <td class="column column1">1</td>
            <td class="column column2">Nick</td>
            <td class="column column3">Jackson</td>
            <td class="column column4">123456</td>
            //Other table data
        </tr>
        //Other rows
        <tr data-id='809' data-name='helga' data-famil_name='jhonson' data-ssn='125648'>
            <td class="column column1">809</td>
            <td class="column column2">Helga</td>
            <td class="column column3">Jhonson</td>
            <td class="column column4">125648</td>
            //Other table data
        </tr>
        //Other rows
        <tr data-id='1001' data-name='nick' data-famil_name='jhonson' data-ssn='216458'>
            <td class="column column1">1001</td>
            <td class="column column2">Nick</td>
            <td class="column column3">Jhonson</td>
            <td class="column column4">216458</td>
            //Other table data
        </tr>
        //Other rows
    </tbody>
</table>

If somebody needs jsFiddle example I can create one later.

Case 1: If i want to dynamically hide only table column which contain SSN data. I can apply several approach to do this. This approach can be divided into two major category. In first category solutions I can iterate over td elements and dynamically change the style for the column. In second approach I can apply CSS by dynamically creating oneor use predefined CSS rules as given here by @Frits van Campen. (Note: @Frits van Campen is good solution for given case. But I want to discuss further more then manipulating table row showing and hiding.)

I can create dynamic CSS rule as following:

td:nth-child(3)
{
  display:none;
}

Or apply predefined CSS rule:

table.no-filter td.column3
{
   display:block;
}
table.filter3 td.column3 
{ 
   display: none; 
}

Here are jsFiddly examples:

  1. Iteration
  2. CSS on fly

Here is time parison using console.time method which I found here.

Left is dynamic css and right is iteration approach.

Perhaps, it is not appropriate one because it calculates appending style element vs iterating over elements. All iteration over element in dynamic CSS will be done by browsers internals. However if we think our script response time dynamic css is faster. Note: iteration approach will be faster in pure JavaScript paring to jQuery. But how much faster i do not have results. So you can more in your answers.

Case 2: Now, I want to highlight table row <tr> which contains user with name 'Nick'. Here you can note that table row has data attributes like name, family_name, id and etc. So, here again I can iterate over elements using javascript or any other library tools or can apply some dynamic rule (I do not know whether it is possible or not apply predefined filters as in case 1.)

CSS rule:

tr[data-name ~='nick']
{
    background-color:red;
}

In this case I can do a lot of fun filtering by applying CSS rule dynamically.

Update: Example given here is for simple overview of the problem. And some optimized iterations can perform equally fast in javascript. However I consider only table which does not have dipper child elements paratively nested ul elements where traversing in order to select element can be difficult.

Important: I only give tabel example here to make clarification with what kind of issue I faced if it is irrelevant feel free to edit the question and delete this part. Also please state your answers clearly in scope of question. Here I am not asking about 'Did I implemented in good way or not?' I am asking what is of advantages or disadvantages of dynamically creating style elements has in terms of browser internal mechanisms.

P.S. and example: Why I came with this idea? I answer recently for 'How to hide columns in very long html table' question. In this question OP asks about applying CSS rule for certain table columns in long table. I suggest to create style element with rules on fly and it works fine. I think this is because style applied by browsers internal mechanisms and gives better performance than iterating through elements and applying style to each item.

In JavaScript we can create <style> element dynamically and append to <head> section in order to apply CSS rule for huge number of elements.

  1. What is advantages or disadvantages of this approach?

  2. If it is really gives performance gain paring to javascript iteration over elements. What goes behind the scene (inside of browser)?

  3. Which one is faster or slower? Javascript iteration over elements or adding css dynamically in browser?

  4. What about processing time? processing load?

For better understanding the issue where I used this approach see following example:

Example: If I have table with 20 or more columns and 1000 rows or more as following html:

<table border="1" class='no-filter'>
    <thead>
        <tr>
            <th data-title='id'>Id</th>
            <th data-title='name'>Name</th>
            <th data-title='family_name'>Family Name</th>
            <th data-title='ssn'>SSN</th>
            //Other table data
        </tr>
    </thead>
    <tbody>
        <tr data-id='1' data-name='nick' data-famil_name='jackson' data-ssn='123456'>
            <td class="column column1">1</td>
            <td class="column column2">Nick</td>
            <td class="column column3">Jackson</td>
            <td class="column column4">123456</td>
            //Other table data
        </tr>
        //Other rows
        <tr data-id='809' data-name='helga' data-famil_name='jhonson' data-ssn='125648'>
            <td class="column column1">809</td>
            <td class="column column2">Helga</td>
            <td class="column column3">Jhonson</td>
            <td class="column column4">125648</td>
            //Other table data
        </tr>
        //Other rows
        <tr data-id='1001' data-name='nick' data-famil_name='jhonson' data-ssn='216458'>
            <td class="column column1">1001</td>
            <td class="column column2">Nick</td>
            <td class="column column3">Jhonson</td>
            <td class="column column4">216458</td>
            //Other table data
        </tr>
        //Other rows
    </tbody>
</table>

If somebody needs jsFiddle example I can create one later.

Case 1: If i want to dynamically hide only table column which contain SSN data. I can apply several approach to do this. This approach can be divided into two major category. In first category solutions I can iterate over td elements and dynamically change the style for the column. In second approach I can apply CSS by dynamically creating oneor use predefined CSS rules as given here by @Frits van Campen. (Note: @Frits van Campen is good solution for given case. But I want to discuss further more then manipulating table row showing and hiding.)

I can create dynamic CSS rule as following:

td:nth-child(3)
{
  display:none;
}

Or apply predefined CSS rule:

table.no-filter td.column3
{
   display:block;
}
table.filter3 td.column3 
{ 
   display: none; 
}

Here are jsFiddly examples:

  1. Iteration
  2. CSS on fly

Here is time parison using console.time method which I found here.

Left is dynamic css and right is iteration approach.

Perhaps, it is not appropriate one because it calculates appending style element vs iterating over elements. All iteration over element in dynamic CSS will be done by browsers internals. However if we think our script response time dynamic css is faster. Note: iteration approach will be faster in pure JavaScript paring to jQuery. But how much faster i do not have results. So you can more in your answers.

Case 2: Now, I want to highlight table row <tr> which contains user with name 'Nick'. Here you can note that table row has data attributes like name, family_name, id and etc. So, here again I can iterate over elements using javascript or any other library tools or can apply some dynamic rule (I do not know whether it is possible or not apply predefined filters as in case 1.)

CSS rule:

tr[data-name ~='nick']
{
    background-color:red;
}

In this case I can do a lot of fun filtering by applying CSS rule dynamically.

Update: Example given here is for simple overview of the problem. And some optimized iterations can perform equally fast in javascript. However I consider only table which does not have dipper child elements paratively nested ul elements where traversing in order to select element can be difficult.

Important: I only give tabel example here to make clarification with what kind of issue I faced if it is irrelevant feel free to edit the question and delete this part. Also please state your answers clearly in scope of question. Here I am not asking about 'Did I implemented in good way or not?' I am asking what is of advantages or disadvantages of dynamically creating style elements has in terms of browser internal mechanisms.

P.S. and example: Why I came with this idea? I answer recently for 'How to hide columns in very long html table' question. In this question OP asks about applying CSS rule for certain table columns in long table. I suggest to create style element with rules on fly and it works fine. I think this is because style applied by browsers internal mechanisms and gives better performance than iterating through elements and applying style to each item.

Share Improve this question edited May 23, 2017 at 12:03 CommunityBot 11 silver badge asked Jan 8, 2014 at 1:38 KhamidullaKhamidulla 2,9736 gold badges38 silver badges59 bronze badges 6
  • 1 I do not understand somebody want to close the question why? Does it have some problems? – Khamidulla Commented Jan 8, 2014 at 1:48
  • SO's Q&A nature usually doesn't make it a really good fit for heavily opinion-based posts like this. Methinks it's within bounds, someone else apparently doesn't. – Niels Keurentjes Commented Jan 8, 2014 at 1:52
  • 1 @NielsKeurentjes I think it is not opinion based question because I am clearly stating that advantages or disadvantages using on fly creation of style element in terms of technical and internal mechanisms of web browser. It is not like I like this approach and I am using kind of question. I really want to know why iterating over elments using javascript is gives less performance than creating css rule with css selector and applying it to elements? – Khamidulla Commented Jan 8, 2014 at 1:56
  • Don't tell me, I didn't vote for close and even answered :) – Niels Keurentjes Commented Jan 8, 2014 at 1:58
  • 1 It's really hard to follow your question -- Blockquotes are meant for quoting other people, not for adding emphasis to your own post. Also, the code you're referring to should really be an SSCCE and be in this question; not just menting on another question. – George Stocker Commented Jan 8, 2014 at 2:23
 |  Show 1 more ment

3 Answers 3

Reset to default 4

Apart from some scoping issues (there might be more tables on the page...) there is nothing inherently wrong with this approach - the style elements are there in the DOM to be edited as you see fit, the browsers are following standards by respecting it. In your test case, there's not really a valid other approach since indeed colgroup has extremely messy support - there are 78 duplicate bugs on the subject in Bugzilla, and Mozilla has been refusing to implement it properly since the first related bug report in 1998.

The reason it's faster is simply one of overhead - once the plete DOM is assembled a relatively minor stylesheet can be applied in native C++ much faster than a Javascript interpreter can ever loop over all rows and cells. This is because historically CSS rules are applied in reverse, and the browser keeps a dictionary inside quickly allowing it to find all td elements. Native C++ will always beat more plex interpreter-based code.

In the future, the scoping issue can also be resolved with scoped styles (currently only in FF, rather typical), you'd be coding like this:

<table>
  <style id="myTableStyle" scoped>
    td:nth-child(1) { display:none }
  </style>
  <tbody>
     ...
  </tbody>
</table>

The scoped attribute makes the contained styles only valid for its containing element, the table in this case, and of course all its contained elements. And since you can access it by ID the contents are easily replaced/reconstructed.

While this would be preferable to your approach, as long as there's no universal browser support for this creating style elements in the head is the best workaround.

Dynamically generating CSS is bad. Don't do it.

A solution that works by generating dynamic CSS can converted to a solution that doesn't require dynamic CSS.

If you need an example, see my answer here: jQuery to update actual CSS


To respond directly about the case you linked:

This seems like a very strange use-case to me. A page that has a table with 1000 rows is already a bad starting position. You can't reasonably fit 1000 rows on your screen and expect any kind of useful interaction. CSS is not the problem here. If the table were smaller the performance concerns disappear.

There are possibly other approaches than the on OP suggests. You don't need to (dynamically) add a class to each cell, you can put the class there on generation time, like:

<table class="no-filter">
...
  <td class="filter1 filter2"></td>
...
</table>

Then have something like:

table.filter1 td.filter2 { display: none; }
table.filter2 td.filter1 { display: none; }

You only change the class on the table to say which filter applies.

CSS is more than just a hammer, it's a whole tool-set of very refined and very powerful tools. Make sure you use the right ones.


The advantages of having static CSS should be self-apparent:

  • Much easier to understand, test, debug and maintain.
  • The CSS is actually in CSS (not in JavaScript).
  • You can do templating, maybe add some visual regression tests.

There are also some performance concerns. I can see browser vendors optimizing AGAINST dynamic CSS. By this I mean if there is an optimization for static CSS that reduces performance of dynamic CSS you just might make this tradeoff.

There's a library called less.js which lets you manipulate css with variables in in your.css file.It's a very good library and you might want to take a look into that. http://www.lesscss/

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>