+ All Categories
Home > Technology > [@IndeedEng] Building Indeed Resume Search

[@IndeedEng] Building Indeed Resume Search

Date post: 19-May-2015
Category:
Upload: indeedeng
View: 2,649 times
Download: 3 times
Share this document with a friend
Description:
Video available: http://youtu.be/qcnP5gQGBaU Software engineer David Tulig will dive into the architecture of Indeed’s Resume Instant Search and our use of the Google Closure tools. David will explain how we write maintainable, efficient JavaScript components for Resume Instant Search and other Indeed products. He will discuss how we create templates that run on both client and server, providing fast initial page load time and search engine-friendly pages with the responsiveness of client-side rendering. Speaker: David Tulig is a software engineer on the Job Search team at Indeed. David has worked on employer, resume, and job search products during his 4 years at Indeed.
Popular Tags:
160
Building Indeed Resume Search David Tulig
Transcript
Page 1: [@IndeedEng] Building Indeed Resume Search

Building Indeed Resume SearchDavid Tulig

Page 2: [@IndeedEng] Building Indeed Resume Search

DAVID TULIGTECH LEADJOB SEARCH TEAM

Page 3: [@IndeedEng] Building Indeed Resume Search

I help people get jobs.

Page 4: [@IndeedEng] Building Indeed Resume Search
Page 5: [@IndeedEng] Building Indeed Resume Search

Jobseekers Job

Page 6: [@IndeedEng] Building Indeed Resume Search

Jobseekers Job

Page 7: [@IndeedEng] Building Indeed Resume Search
Page 8: [@IndeedEng] Building Indeed Resume Search
Page 9: [@IndeedEng] Building Indeed Resume Search
Page 10: [@IndeedEng] Building Indeed Resume Search
Page 11: [@IndeedEng] Building Indeed Resume Search

We learned from Job Search

Page 12: [@IndeedEng] Building Indeed Resume Search

The web evolved

Page 13: [@IndeedEng] Building Indeed Resume Search

PRINCIPLES

SimpleFastComprehensiveRelevant

Page 14: [@IndeedEng] Building Indeed Resume Search

PRINCIPLES

SimpleFastComprehensiveRelevant

Page 15: [@IndeedEng] Building Indeed Resume Search

GOALS

Page 16: [@IndeedEng] Building Indeed Resume Search

Responsive user experience

Page 17: [@IndeedEng] Building Indeed Resume Search

javas

Page 18: [@IndeedEng] Building Indeed Resume Search

javas

javascriptjavascript jqueryjavascript htmljavascript html css

Page 19: [@IndeedEng] Building Indeed Resume Search

javascript

javascriptjavascript jqueryjavascript htmljavascript html css

Page 20: [@IndeedEng] Building Indeed Resume Search
Page 21: [@IndeedEng] Building Indeed Resume Search

Maintainable code

Page 22: [@IndeedEng] Building Indeed Resume Search

Re-usable components

Page 23: [@IndeedEng] Building Indeed Resume Search

Separate presentation and logic

Page 24: [@IndeedEng] Building Indeed Resume Search

Fast

Page 25: [@IndeedEng] Building Indeed Resume Search

GOALS

Responsive UXMaintainable codeFast

Page 26: [@IndeedEng] Building Indeed Resume Search

Library support

Page 27: [@IndeedEng] Building Indeed Resume Search

Google Closure Tools

Page 28: [@IndeedEng] Building Indeed Resume Search
Page 29: [@IndeedEng] Building Indeed Resume Search
Page 30: [@IndeedEng] Building Indeed Resume Search
Page 31: [@IndeedEng] Building Indeed Resume Search
Page 32: [@IndeedEng] Building Indeed Resume Search

Closure Library

Page 33: [@IndeedEng] Building Indeed Resume Search

array asserts async color crypt cssom date disposable dom ds editor events format functions fx gears global graphics history i18n iter json locale math messaging module net positioning proto proto2 pubsub result soy spell stats storage string structs style testing text tweak ui userAgent vec

Page 34: [@IndeedEng] Building Indeed Resume Search

array asserts async color crypt cssom date disposable dom ds editor events format functions fx gears global graphics history i18n iter json locale math messaging module net positioning proto proto2 pubsub result soy spell stats storage string structs style testing text tweak ui userAgent vec

Page 35: [@IndeedEng] Building Indeed Resume Search

Modular and independent

Page 36: [@IndeedEng] Building Indeed Resume Search

Application

dom events style

Page 37: [@IndeedEng] Building Indeed Resume Search

Application

dom events style

arrayobject

Page 38: [@IndeedEng] Building Indeed Resume Search

Application

dom events style

arrayobject string

Page 39: [@IndeedEng] Building Indeed Resume Search

Application

dom events style

arrayobject string

Page 40: [@IndeedEng] Building Indeed Resume Search

Application

dom events style

arrayobject string

Page 41: [@IndeedEng] Building Indeed Resume Search

Application

dom

events

style

array

object

string

Page 42: [@IndeedEng] Building Indeed Resume Search

goog.provide('indeed.Search');

goog.require('goog.dom');goog.require('goog.events');

/* Search */indeed.Search.validateLocation =

function() {...};

Page 43: [@IndeedEng] Building Indeed Resume Search

goog.provide('indeed.Search');

goog.require('goog.dom');goog.require('goog.events');

/* Search */indeed.Search.validateLocation =

function() {...};

Page 44: [@IndeedEng] Building Indeed Resume Search

Application

dom events style

arrayobject string

Page 45: [@IndeedEng] Building Indeed Resume Search

Unit testing

Page 46: [@IndeedEng] Building Indeed Resume Search
Page 47: [@IndeedEng] Building Indeed Resume Search
Page 48: [@IndeedEng] Building Indeed Resume Search

Closure Templates

Page 49: [@IndeedEng] Building Indeed Resume Search
Page 50: [@IndeedEng] Building Indeed Resume Search
Page 51: [@IndeedEng] Building Indeed Resume Search

Closure Compiler

Page 52: [@IndeedEng] Building Indeed Resume Search
Page 53: [@IndeedEng] Building Indeed Resume Search

whitespace_only

Page 54: [@IndeedEng] Building Indeed Resume Search

simple_optimizations

Page 55: [@IndeedEng] Building Indeed Resume Search
Page 56: [@IndeedEng] Building Indeed Resume Search
Page 57: [@IndeedEng] Building Indeed Resume Search
Page 58: [@IndeedEng] Building Indeed Resume Search

advanced_optimizations

Page 59: [@IndeedEng] Building Indeed Resume Search
Page 60: [@IndeedEng] Building Indeed Resume Search

Type checking

Page 61: [@IndeedEng] Building Indeed Resume Search
Page 62: [@IndeedEng] Building Indeed Resume Search

Unused code removal

Page 63: [@IndeedEng] Building Indeed Resume Search

/** Alias for getElementById. If a DOM node ispassed in then we just return */goog.dom.getElement = function(element) {...};

/** Looks up elements by both tag and class name,using browser native functions */goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {...};

/** Returns an array of all the elementswith the provided className. */goog.dom.getElementsByClass = function(className, opt_el) {...};

/** Returns the first element with the provided className. */goog.dom.getElementByClass = function(className, opt_el) {...};

/** Alias for getElementById. If a DOM node ispassed in then we just return */goog.dom.getElement = function(element) {...};

/** Looks up elements by both tag and class name,using browser native functions */goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {...};

/** Returns the first element with the provided className. */goog.dom.getElementByClass = function(className, opt_el) {...};

Page 64: [@IndeedEng] Building Indeed Resume Search

/** Alias for getElementById. If a DOM node ispassed in then we just return */goog.dom.getElement = function(element) {...};

/** Looks up elements by both tag and class name,using browser native functions */goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {...};

/** Returns an array of all the elementswith the provided className. */goog.dom.getElementsByClass = function(className, opt_el) {...};

/** Returns the first element with the provided className. */goog.dom.getElementByClass = function(className, opt_el) {...};

/** Alias for getElementById. If a DOM node ispassed in then we just return */goog.dom.getElement = function(element) {...};

/** Looks up elements by both tag and class name,using browser native functions */goog.dom.getElementsByTagNameAndClass = function(opt_tag, opt_class, opt_el) {...};

/** Returns the first element with the provided className. */goog.dom.getElementByClass = function(className, opt_el) {...};

Page 65: [@IndeedEng] Building Indeed Resume Search

/** Alias for getElementById. If a DOM node ispassed in then we just return */goog.dom.getElement = function(element) {...};

/** Returns an array of all the elementswith the provided className. */goog.dom.getElementsByClass = function(className, opt_el) {...};

Page 66: [@IndeedEng] Building Indeed Resume Search

Aggressive renaming

Page 67: [@IndeedEng] Building Indeed Resume Search
Page 68: [@IndeedEng] Building Indeed Resume Search
Page 69: [@IndeedEng] Building Indeed Resume Search
Page 70: [@IndeedEng] Building Indeed Resume Search
Page 71: [@IndeedEng] Building Indeed Resume Search

Let's build Resume Search

Page 72: [@IndeedEng] Building Indeed Resume Search

Resume Search architecture

Page 73: [@IndeedEng] Building Indeed Resume Search
Page 74: [@IndeedEng] Building Indeed Resume Search

Browser Server

q=javasc

Page 75: [@IndeedEng] Building Indeed Resume Search

Browser Server

q=javasc

{ "suggestions" : [ "javascript", "javascript jquery", "javascript html", "javascript html css", "javascript ajax" ]}

Page 76: [@IndeedEng] Building Indeed Resume Search
Page 77: [@IndeedEng] Building Indeed Resume Search
Page 78: [@IndeedEng] Building Indeed Resume Search
Page 79: [@IndeedEng] Building Indeed Resume Search
Page 80: [@IndeedEng] Building Indeed Resume Search
Page 81: [@IndeedEng] Building Indeed Resume Search
Page 82: [@IndeedEng] Building Indeed Resume Search

AutoCompleteAutoComplete

Page 83: [@IndeedEng] Building Indeed Resume Search

Search

Page 84: [@IndeedEng] Building Indeed Resume Search

Preview

Page 85: [@IndeedEng] Building Indeed Resume Search

AutocompleteSearchPreview

Page 86: [@IndeedEng] Building Indeed Resume Search

LocationAutocomplete

Search Preview

QueryAutocomplete

A Possible Approach: Tightly Coupled Modules

Page 87: [@IndeedEng] Building Indeed Resume Search

Use events

Page 88: [@IndeedEng] Building Indeed Resume Search
Page 89: [@IndeedEng] Building Indeed Resume Search
Page 90: [@IndeedEng] Building Indeed Resume Search

{ "suggestions" : [ "javascript", "javascript jquery", "javascript html", "javascript html css", "javascript ajax" ]}

Page 91: [@IndeedEng] Building Indeed Resume Search
Page 92: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

Page 93: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

Page 94: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

1. N

ew te

xt "j

avas

c"

Page 95: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

2. Get suggestions

Page 96: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

3. Suggestions

Page 97: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

4. Render

Page 98: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

6. Click on "javascript"

Page 99: [@IndeedEng] Building Indeed Resume Search

Autocomplete

Text HandlerDrop Down

HandlerRPC Handler

6. S

et te

xt to

"jav

ascr

ipt"

Page 100: [@IndeedEng] Building Indeed Resume Search

Search App

AutoComplete

Text HandlerDrop Down

Handler

Search

RPC Handler

Page 101: [@IndeedEng] Building Indeed Resume Search

Search App

AutoComplete

Text HandlerDrop Down

Handler

Search

RPC Handler

Awesome

Page 102: [@IndeedEng] Building Indeed Resume Search
Page 103: [@IndeedEng] Building Indeed Resume Search
Page 104: [@IndeedEng] Building Indeed Resume Search

Search App

AutoComplete

Text HandlerDrop Down

Handler

Search

RPC Handler

Page 105: [@IndeedEng] Building Indeed Resume Search

Search App

AutoComplete

Text HandlerDrop Down

Handler

Search

RPC Handler

Page 106: [@IndeedEng] Building Indeed Resume Search

Search App

AutoComplete

Text HandlerDrop Down

Handler

Search

RPC Handler

Page 107: [@IndeedEng] Building Indeed Resume Search

User interface

Page 108: [@IndeedEng] Building Indeed Resume Search
Page 109: [@IndeedEng] Building Indeed Resume Search

Templates

Page 110: [@IndeedEng] Building Indeed Resume Search

Server or client?

Page 111: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

Page 112: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

HTML

Time

Page 113: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

LOAD JSHTML

Time

Page 114: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

AJAX RESULTSLOAD JSHTML

Page 115: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

JS REQ JS RESP AJAX REQ AJAX RESPHTML + DATA AJAX RESULTSLOAD JS

Time

Page 116: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

JS REQ JS RESPHTML + DATA LOAD JS

Page 117: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

HTML + RESULTS

Time

Page 118: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

HTML + RESULTS JS REQ JS RESPLOAD JS

Page 119: [@IndeedEng] Building Indeed Resume Search

indeed.com/resumes?q=java

HTML + RESULTS JS RESPLOAD JS

Page 120: [@IndeedEng] Building Indeed Resume Search

Server or client?

Page 121: [@IndeedEng] Building Indeed Resume Search

Server AND client!

Page 122: [@IndeedEng] Building Indeed Resume Search

Don't repeat yourself

Page 123: [@IndeedEng] Building Indeed Resume Search

Closure Templates

Page 124: [@IndeedEng] Building Indeed Resume Search

template.soy

Closure Template Compilernew TofuRenderer()

template.js

one template. all requests.

Page 125: [@IndeedEng] Building Indeed Resume Search

/resumes?q=javascript Server Rendering

Page 126: [@IndeedEng] Building Indeed Resume Search

/resumes?q=javascript Server Rendering

Controller

Page 127: [@IndeedEng] Building Indeed Resume Search

/resumes?q=javascript

Controller

Model

Server Rendering

Page 128: [@IndeedEng] Building Indeed Resume Search

/resumes?q=javascript

Controller

Model

new TofuRenderer()

Server Rendering

Page 129: [@IndeedEng] Building Indeed Resume Search

/resumes?q=javascript

Controller

Model

new TofuRenderer()

HTML

Server Rendering

Page 130: [@IndeedEng] Building Indeed Resume Search

/instant?q=javascriptClient Rendering

Page 131: [@IndeedEng] Building Indeed Resume Search

/instant?q=javascript

Controller

Client Rendering

Page 132: [@IndeedEng] Building Indeed Resume Search

/instant?q=javascript

Controller

Model

Client Rendering

Page 133: [@IndeedEng] Building Indeed Resume Search

/instant?q=javascript

Controller

Model

JSON

Client Rendering

Page 134: [@IndeedEng] Building Indeed Resume Search

/instant?q=javascript

Controller

Model

template.js

JSON

Client Rendering

Page 135: [@IndeedEng] Building Indeed Resume Search

/instant?q=javascript

Controller

Model

template.js

JSON

Client Rendering

HTML

Page 136: [@IndeedEng] Building Indeed Resume Search

/resumes?q=javascript /instant?q=javascript

Controller

Model

new TofuRenderer()

HTML

template.js

JSON

Page 137: [@IndeedEng] Building Indeed Resume Search

Don't repeat yourself

Page 138: [@IndeedEng] Building Indeed Resume Search

Application

Page 139: [@IndeedEng] Building Indeed Resume Search

Application

Browser

Page 140: [@IndeedEng] Building Indeed Resume Search

Library

Browser

Page 141: [@IndeedEng] Building Indeed Resume Search

Library

Browser

Templates

Page 142: [@IndeedEng] Building Indeed Resume Search

Library

Browser

Templates Application

Page 143: [@IndeedEng] Building Indeed Resume Search

HTML LIBRARY TEMPLATES APPLICATION

Time

Page 144: [@IndeedEng] Building Indeed Resume Search

COMBINED

Time

HTML

Page 145: [@IndeedEng] Building Indeed Resume Search

COMPILED

Time

HTML

Page 146: [@IndeedEng] Building Indeed Resume Search

Application size

Page 147: [@IndeedEng] Building Indeed Resume Search

whitespace_only 126k

Page 148: [@IndeedEng] Building Indeed Resume Search

whitespace_only 126k

simple_optimizations 108k

Page 149: [@IndeedEng] Building Indeed Resume Search

whitespace_only 126k

simple_optimizations 108k

49k advanced_optimizations

Page 150: [@IndeedEng] Building Indeed Resume Search

RESUME SEARCH

Re-usable componentsResponsive UXFast initial load

Page 151: [@IndeedEng] Building Indeed Resume Search

[video of http://www.indeed.com/resumes]

Page 152: [@IndeedEng] Building Indeed Resume Search

We learned from Resume Search

Page 153: [@IndeedEng] Building Indeed Resume Search

jobsearch.js

Page 154: [@IndeedEng] Building Indeed Resume Search

jobsearch.js 41k

Page 155: [@IndeedEng] Building Indeed Resume Search

jobsearch.js 41k

jobsearch_v2.js 35k

Page 156: [@IndeedEng] Building Indeed Resume Search

6K MATTERS

Page 157: [@IndeedEng] Building Indeed Resume Search

6K MATTERS

6k reduction

Page 158: [@IndeedEng] Building Indeed Resume Search

6K MATTERS

6k reduction546 GB / month

Page 159: [@IndeedEng] Building Indeed Resume Search

6K MATTERS

6k reduction546 GB / month428 hours / month

Page 160: [@IndeedEng] Building Indeed Resume Search

david tuligtwitter: @dtulig

indeed.com/resumes

engineering.indeed.com


Recommended