jQuery Is not the answer
Ed Kim
@edwardjkim
jquery is everywhere (almost)
56%
of all websites
92%
of javascript websites
Source: W3Tech
A common pitfall
I want to show/hide content when a user clicks on a link
"Nice that was pretty easy!"
I want to show data depending on what the user inputs
"Not too bad"
Now I want to let users manipulate the data
"This is getting harder but I'll keep going because I'm really good at jQuery."
Data - View - logic
Getting data out of the dom
As humans, it's easy to process data in this form
But for machines, it actually takes a lot of work to extract the data and start computing
A simple example
Sort this table by the price of beer
The Html
We get HTML for each table row from the server.
Each table row has the class "bar".
<table id="bar-table">
...stuff...
<tbody>
<tr class="bar">
<td class="name">McGinty's Public House</td>
<td class="price">$4.00</td>
<td class="address">911 Ellsworth Drive</td>
</tr>
...more rows with class "bar"...
Sorting ain't easy
sortByPrice = function(a,b) {
return $(a).children('.price').html() >
$(b).children('.price').html() ? 1 : -1; }
var bars = $(‘.bar’)
//bars is now an array of <tr> elements
bars.sort(sortByPrice);
//bars is now a sorted array of <tr> elements
Now you have to find the parent <tbody> element and rearrange the rows.
Manipulating the DOM
$.each(bars, function(index, bar) {
$('#bar-table').children('tbody').append(bar);
}); // Very Bad!!!
The whole solution
Source: Stack Overflow
$(document).ready(function() { $('table.sortable').each(function() { var $table = $(this); $('th', $table).each(function(column) { var $header = $(this); $header.click(function() { var rows = $table.find('tbody > tr').get(); rows.sort(function(a, b) { var keyA = $(a).children('td').eq(column).text().toUpperCase();
var keyB = $(b).children('td').eq(column).text().toUpperCase(); if(keyA < keyB) return -1; if(keyA > keyB) return 1; return 0; }); $.each(rows, function(index, row) { $table.children('tbody').append(row); }); }); }); }); })
<tr class="bar">
<td class="name">
TGI Friday's
</td> <td class="price">
$4.00
</td> <td class="address">
911 Ellsworth Drive
</td> </tr>
...more rows...
A GROWING RIFT BETWEEN VIEW AND LOGIC
bars = $('.bar'); bars.sort(sortByPrice); $.each(bars,
function(index, bar) { $('tbody').append(bar);
});
HTML Javascript
Not at all obvious how these are connected
WHAT ABOUT COMPLEX VIEWS?
Bars within 2 miles of the Civic Center
jquery is not a framework
MV* to the rescue
Data - View - Logic
Model - View - Controller (MVC)
Model - View - ViewModel (MVVM)
Table Sorting in knockout
<table> ...stuff... <tbody data-bind="foreach: bars">
<tr class="bar"> <td data-bind="text: name" /> <td data-bind="text: price" /> <td data-bind="text: address" /> </tr>
function sortByPrice (a,b) {
return a.price > b.price ? 1 : -1;
}
barData = [{name: "Piratz Tavern", price: "3.50", ... }];
sortedBarData = barData.sort(sortByPrice);
viewModel.sortedBars = ko.observableArray(sortedBarData);
When performance matters
remember this?
$.each(rows, function(index, row) {
$table.children('tbody').append(row);
});
Heavy DOM traversal eats up time.
Let's compare performance to a framework like knockout.js
Time trials
FILE SIZe
jQuery 2.0.3 - 30kb gzipped
Zepto.js - 10kb gzipped
knockout.js - 16kb gzipped
backbone.js - 7kb gzipped
jquery does have good parts
- Browser compatibility
- Ajax
- Handling Events
Some good use cases
- Small Self-contained widgets (jQuery UI)
- Scraping Websites
- Rapid Prototyping (arguably)
In Summary
-
jQuery is not a framework
-
jQuery can be slow
It's a great tool. Just be careful how you use it!
jQuery is Not the Answer
By Edward Kim
jQuery is Not the Answer
- 1,169