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

jquery - Does javascript getAttribute affects performance or triggers layout? - Stack Overflow

programmeradmin4浏览0评论

I'm practicing parallax, so during the scroll i need element's offsetTop and height. And i know, that it's triggers layout each time, when you "get" this style properties, so it's affects overall perfomance. I decided to set custom attributes for each element with function and update it on window resize:

function setAttrs() {
  $sections.each(function() {
    var offsetTop = $(this).offset().top,
        height = $(this).height();
    $(this).attr({"data-offset": offsetTop, "data-height": height});
  });
}

setAttrs();

$(window).on("resize", function() {
  setAttrs();
});

So, my question is - does attribute getter inside scroll handler affects perfomance somehow? Something like this:

var height = $(this).attr("data-height");

I'm sort of 90% sure that this is good way, but i need to be sure.

I'm practicing parallax, so during the scroll i need element's offsetTop and height. And i know, that it's triggers layout each time, when you "get" this style properties, so it's affects overall perfomance. I decided to set custom attributes for each element with function and update it on window resize:

function setAttrs() {
  $sections.each(function() {
    var offsetTop = $(this).offset().top,
        height = $(this).height();
    $(this).attr({"data-offset": offsetTop, "data-height": height});
  });
}

setAttrs();

$(window).on("resize", function() {
  setAttrs();
});

So, my question is - does attribute getter inside scroll handler affects perfomance somehow? Something like this:

var height = $(this).attr("data-height");

I'm sort of 90% sure that this is good way, but i need to be sure.

Share Improve this question asked Mar 26, 2015 at 14:58 Nikolay TalanovNikolay Talanov 7174 silver badges15 bronze badges 6
  • Instead of var height = $(this).attr("data-height");, use var height = $(this).data("height");. jQuery has a getter / setter for data attributes. – Cerbrus Commented Mar 26, 2015 at 15:01
  • @Cerbrus I think both .attr() and .data() methods of fetching HTML5 data- attributes are legit. The only issue is that .data() does not allow for writing (which OP doesn't need in this case, but good to know), and that it fetches the value at runtime and dynamic changes to the attribute value will not be reflected in .data(), but will do so in .attr(). – Terry Commented Apr 11, 2015 at 20:02
  • 1 @Terry: Since when doesn't .data() allow write actions? And since when doesn't it reflect the latest state of the DOM? That's just silly... – Cerbrus Commented Apr 11, 2015 at 20:11
  • @Cerbrus It does allow write, but does not modify the DOM: stackoverflow./questions/17762906/… It writes to the jQuery data object instead. – Terry Commented Apr 11, 2015 at 21:00
  • And why is that a problem? If you're using data attributes, you generally want to get / set it using the same library any way. – Cerbrus Commented Apr 11, 2015 at 21:01
 |  Show 1 more ment

3 Answers 3

Reset to default 3

First, that's not really the best way to set the value of data-* attributes:

$(this).data({ offset: offsetTop, height: height });

That doesn't touch the DOM - jQuery maintains the values in its own data structure. It will read data-* attributes when they're first referenced from a particular element, but it won't update them in the DOM. References should also be made with .data():

var savedHeight = $(this).data("height");

Note that you drop the "data-" prefix when using the .data() API.

Second, anything you do with the DOM in a "resize" handler will affect performance, because browsers fire "resize" extremely rapidly while a window is being interactively resized. It's usually a good idea to make sure that your "resize" handler only does any work once every 50 or 100 milliseconds at most. There are a few different approaches to doing that, depending on the effect you're trying to achieve.

When you're talking about performance:

As your using $(this) in three places in that each callback, its better to store it in a variable. It would avoid some overhead as well.

function setAttrs() {
  $sections.each(function() {
    var $self = $(this);
    var offsetTop = $self.offset().top,
        height = $self.height();
        $self.data({"offset": offsetTop, "height": height});
  });
}

Other things as @Pointy mentioned.

Late to the party – but I have some benchmarks up my sleeve.

As for the raw Element.getAttribute, it never causes a reflow. In some browsers it’s still significantly slower than accessing cached data, in others not (jsPerf).

However, jQuery’s $().attr is always much slower than the native Element.getAttribute (jsPerf). Probably wrapping DOM methods with another function prevents browsers from optimizations – I’ve already run across this thing.

As others pointed out, $().data should be much faster than $().attr. Here’s a jsPerf for that, though I couldn’t access the results due to network problems.

发布评论

评论列表(0)

  1. 暂无评论