Nestoria New Design Savio Dimatteo Perl Developer, Lokku Ltd. Commercial Computing Lecture Series Birmingham University 5 December 2013
May 08, 2015
Nestoria New DesignSavio Dimatteo
Perl Developer,
Lokku Ltd.
Commercial Computing Lecture Series
Birmingham University
5 December 2013
Who am I?
● Savio Dimatteo
● Perl Developer at Nestoria property search engine
● working on a LAMP stack since 2 years [ “P” = “Perl” ]
● maintenance/frontend/backend projects
● currently working on: “Nestoria New Design”
Lokku
● dev team: 6 people● product team: 2 people● commercial team: 8 people
Nestoria
● property search engine
● 8 countries, 6 languages
● 1.3 million search requests per day
● 10 million properties indexed every day
Nestoria
Nestoria Internally
Nestoria Internally
Nestoria Externally
Nestoria Externally
Nestoria Externally
Nestoria Externally
Nestoria Stack
● HTML::Mason
● jQuery/jQueryUI
● XHTML Strict
● Apache, mod_perl
● MySQL
Nestoria Over Time
Nestoria Over Time
Legible Listings Layout
Legible Listings Layout
● ~200KB more CSS
● + ~6% daily clicks than in previous design
● exception: India
○ older devices
■ lower resolutions
■ slower connections
Nestoria New Design
Nestoria New Design
Setting and Resources
● ~4 months time
Nestoria New Design
Challenges
Challenge #1Getting the Design Right
What you get:
○ spacing
○ fonts
○ colors
○ sizes
● Looks good!
New Design Specs
What you get:
○ spacing
○ fonts
○ colors
○ sizes
● Looks good! BUT
New Design Specs
Improvement via user tests
Improvement via user tests
Smaller Graphical Tweaks
Logic not yet implemented
Exact dimensions
“Australian” Prices?
● Offers Above $545,000
● $439,950-$469,950
● POA
● Supurb Value offers above $1.49M
“Australian” Prices?
Implementing “impossible” specs
1. stick to the spec as much as possible
2. follow the principles the spec is based on
3. be inventive
4. talk to people
Implementing “impossible” specs
1. stick to the spec as much as possible
2. follow the principles the spec is based on
3. be inventive
4. talk to people
Australian prices!
Australian Prices!
● no collision
● leave as is
Australian Prices!
● collision
● detect collision (Javascript)
if ($titleLink.position().left + $titleLink.width() >= $titleAside.position().left) {
}
Australian Prices!
● detect collision (Javascript)
if ($titleLink.position().left + $titleLink.width() >= $titleAside.position().left) {
… $listingContainer.addClass(‘nst-collision-detected’); …
}
● Add ‘nst-collision-detected’ CSS rule to fix the issue
Challenge #2Building UI components
New Sliders
New Sliders
● disabled (any price allowed)
New Sliders
● left-bounded range
New Sliders
● bounded range
New Sliders
● single value
New Sliders - click
New Sliders - click
New Sliders - click and drag
New Sliders - touch
New Sliders - touch and drag
How would you do create a slider like that?
jQueryUI
“ jQuery UI is a curated set of user interface interactions,
effects, widgets, and themes built on top of the jQuery
JavaScript Library. ”
jQueryUI - sliders
jQueryUI - sliders
jQueryUI - sliders
Can’t click!
jQueryUI - sliders
Can’t click!
Can’t touch!
jQueryUI - touch support
● jQuery UI Touch Punch
“ jQuery UI Touch Punch is a small hack that enables the
use of touch events on sites using the jQuery UI user
interface library. ”
● Can’t touch sliders on Silk Browser (Kindle Fire HD).
Why building our own sliders?
● complex yet specific user interactions
● it’s tempting to hack into jQuery UI sliders to add touch
support (forbidden!)
● would need to include jQuery UI (23KB, minified)
● we already plan to increase complexity of slider UI!
jquery.nstSlider.js - usage
<div class="nst-slider-outer" data-step="20" data-min="20” data-max="220">
<div class="nst-slider-inner">
<div class="nst-slider-grip-left"></div>
<div class="nst-slider-grip-right"></div>
</div>
</div>
jquery.nstSlider.js - usage
$('.nst-slider-outer').nstSlider({
'valueChangedCallback' : function(min, max) {
$('.nst-slider-min').text(min);
$('.nst-slider-max').text(max);
}
});
jquery.nstSlider.js - Idea
outer bar(gray bar)
leftgrip
rightgrip
position:absolute;left: 0px;
position:absolute;right: 0px;
inner barposition:relative;
jquery.nstSlider.js - Idea
outer bar(gray bar)
leftgrip inner bar
leftgrip
rightgripinner bar
jquery.nstSlider.js - Idea
outer bar(gray bar)
leftgrip
rightgripinner bar
left: <sth>px;
<sth>
jquery.nstSlider.js - Idea
outer bar(gray bar)
leftgrip
rightgripinner bar
left: <sth>px;width: <sthElse>px;
<sth> <sthElse>
jquery.nstSlider.js - Moving left handle
leftgrip
rightgripinner bar
jquery.nstSlider.js - Moving left handle
leftgrip
rightgripinner bar
jquery.nstSlider.js - Moving left handle
leftgrip
rightgripinner bar
deltaPx
● track deltaPx
jquery.nstSlider.js - Moving left handle
leftgrip
rightgripinner bar
● track deltaPx
● add deltaPx to left CSS property of inner bar
deltaPx
jquery.nstSlider.js - Moving left handle
leftgrip
rightgripinner bar
● track deltaPx
● add deltaPx to left CSS property of inner bar
deltaPx
jquery.nstSlider.js - Moving left handle
leftgrip
rightgripinner bar
● track deltaPx
● add deltaPx to left CSS property of inner bar
● remove deltaPx from width CSS property of inner bar
- deltaPx
jquery.nstSlider.js - Moving left handle
leftgrip
rightgrip
● track deltaPx
● add deltaPx to left CSS property of inner bar
● remove deltaPx from width CSS property of inner bar
● map left , left + width into [rangeMin, rangeMax]
inner bar
left left + width
jquery.nstSlider.js - Moving left handle
leftgrip
rightgrip
● track deltaPx
● add deltaPx to left CSS property of inner bar
● remove deltaPx from width CSS property of inner bar
● map left , left + width into [rangeMin, rangeMax]
→ notify values have changed
inner bar
jquery.nstSlider.js
● easy to use as others jQuery plugins
● highly cross-browser (IE7+, iPhones, not Windows Phones
though)
● ~6KB minified (Closure compiler)
● easily customisable
● more code to maintain
● fixed size for now
Challenge #3Javascript Mistakes
Javascript
● more interactive compontents → more Javascript code
● Javascript:
○ Interacting with the DOM
○ Asynchronous event-handling
○ Single threaded
○ Multiple browsers and devices
○ many libraries out there
Scopingvar result = 1;
function oneOrMore(n) {
result = n;
if (n <= 0) {
var result = Math.abs(n);
result = 1 + result;
}
return result;
}
Scopingvar result = 1;
function oneOrMore(n) {
result = n;
if (n <= 0) {
var result = Math.abs(n);
result = 1 + result;
}
return result;
}
var result = 1;
function oneOrMore(n) {
var result;
result = n;
if (n <= 0) {
result = Math.abs(n);
result = 1 + result;
}
return result;
}
How to not iterate through Javascript arrays
Array.prototype.extraFunc = function () { … };
var myArray = [1, 2, 3, 4];
for (var x in myArray) {
console.log(x);
}
How to not iterate through Javascript arrays
Array.prototype.extraFunc = function () { … };
var myArray = [1, 2, 3, 4];
for (var x in myArray) {
console.log(x);
}
1
2
3
4
extraFunc
How to iterate through Javascript arrays
Array.prototype.extraFunc = function () { … };
var myArray = [1, 2, 3, 4];
for (var i=0; i<myArray.length; i++) {
console.log(myArray[i]);
}
How to not iterate through Javascript objects
var myObj = {
‘key1’ : 1, ‘key2’ : 2, ‘key3’ : 3
};
var k;
for (k in myObj) {
console.log(k, myObj[k]);
}
How to iterate through Javascript objects
var myObj = {‘key1’ : 1, ‘key2’ : 2, ‘key3’ : 3
};
var k;for (k in myObj) {
if (myObj.hasOwnProperty(k)) {
console.log(k, myObj[k]);
}
}
Javascript Code Validation - JSHint● Java-based tool
● parser-based validation
● easy to configure
● very flexible configuration
○ trailing whitespaces
○ naming conventions
○ undeclared variables
JSHint configuration{
"curly" : true,
"camelcase": false,
"eqeqeq" : true,
"forin" : true,
"unused" : true,
"es3" : true,
"trailing" : false,
"devel" : false,
"undef" : true,
"jquery" : true,
"browser" : true,
"globals" : {
"Modernizr" : true,
"$j" : true,
"google" : true,
"LokkuMap" : true,
"GoogleLokkuMap" : true,
"LeafletLokkuMap" : true,
"L": true
}
}
Conclusions
● talk to members of your team during your project
● changing a component completely? just build your own!
● Javascript → mistakes!
○ use code quality tools to avoid mistakes
Conclusions: Nestoria New Design● New design is now live
○ ~3% more daily clicks (all countries)
○ users feel it’s fast (i.e., more clicks per users)
○ we can improve its speed further
○ works in India too!
● the amount Javascript in our codebase is going to grow
○ old motto: “avoid Javascript as much as possible”
○ new motto: “write better Javascript”
Thank you!http://www.nestoria.com - find a property
http://www.github.com/lokku - open source code
http://www.lokku.com/jobs - work with us!