SlideShare a Scribd company logo
1 of 67
Download to read offline
Engineering the New Profile
Josh Clemm
Tech Lead for the New Profile
March 2013 | LinkedIn
David Fleming!
Senior Product Manager at Zoomjax!
San Francisco Bay Area | Software!
!
Previous!
Education!
Golden Phase, FixDex!
Silicon Valley Business Academy!
Let's compare...
Really a brand new product
Refreshed Look & Feel
Simplified Design
Surfaced New &
Interactive
Modules
New Data Insights
New Features
 Improved in-line
editing experience
Modules with In-line
searching &
pagination
The New Profile - Goals
●  Represent your entire professional identity
o  Not just your resume
o  Activity, Groups, Following, Connections,
Insights about you and your network
The New Profile - Goals
●  Represent your entire professional identity
o  Not just your resume
o  Activity, Groups, Following, Connections,
Insights about you and your network

●  Needs to be more interactive
o  Keep users engaged on the page
o  Inline pagination, editing, searching
The New Profile - Goals
●  Represent your entire professional identity
o  Not just your resume
o  Activity, Groups, Following, Connections,
Insights about you and your network

●  Needs to be more interactive
o  Keep users engaged on the page
o  Inline pagination, editing, searching

●  Needs to be fluid, flexible, fast
o  Progressive rendering
o  Maintain high performance
So how did we achieve
all that?
Using a lot of Technologies
And in particular...
Let's look at our High Level
Frontend Architecture
Groups
Content
Service
Connections
Content
Service
Profile
Content
Service
Client/Browser
 CDN
Load Balancer
SCDS
Fizzy
Profile Web
App
Profile
Content
Service
Profile Web
App
Connections
Content
Service
Groups
Content
Service
Dust/JS/CSS
Server
Retrieve Data
Models from
Mid-tier
/profile/view?id=32
top_card.tl,
background.tl
/profile/topcard
 /profile/background
Groups
Content
Service
Connections
Content
Service
Profile
Content
Service
Client/Browser
 CDN
Load Balancer
SCDS
Fizzy
Profile Web
App
Profile
Content
Service
Profile Web
App
Connections
Content
Service
Groups
Content
Service
Dust/JS/CSS
Server
Retrieve Data
Models
/profile/view?id=32
top_card.tl,
background.tl
/profile/topcard
 /profile/background
Our new
architecture
uses new tech
at all layers
Groups
Content
Service
Connections
Content
Service
Profile
Content
Service
Client/Browser
 CDN
Load Balancer
SCDS
Fizzy
Profile Web
App
Profile
Content
Service
Profile Web
App
Connections
Content
Service
Groups
Content
Service
Dust/JS/CSS
Server
Retrieve Data
Models
/profile/view?id=32
top_card.tl,
background.tl
/profile/topcard
 /profile/background
Let's start at the bottom
with Mappers
Mappers - JSON endpoints
●  Convert data models from mid-tier services
into JSON
●  Each have an unique endpoint URL 
( /profile/positions?id=42 )
Positions
Mapper
JSON
"positions": [{
"position": {"id:
{}"},
]}
Biz Profile
Model
Profile
Model
Rich Media
Rest Model
References
Model
Profile Flex
Model
Mappers - an example
public class PictureMapper extends ProfileParametersAwareMapper!
{!
private PictureContentMap pictureContentMap;!
private static final int ZOOMABLE_DIMENSION = 225;!
!
@Override!
public void doService()!
{!
PictureContentModel picCM = getContent(PictureContentModel.class); //declare content needs!
picCM.criteria().setId(getVieweeId()); //supply any input params!
!
assemble(); //invoke framework to retrieve declared content!
!
if (isResolvedWithoutErrors(picCM))!
{!
//all went well, create new content map to hold output (JavaBean-like objects)!
pictureContentMap = ContentMap.proxyNew(PictureContentMap.class);!
!
Integer pictureWidth = picCM.getPictureWidth(); !
pictureContentMap.setIsZoomable(pictureWidth >= ZOOMABLE_DIMENSION);!
!
if(pictureWidth != null && pictureWidth > 0)!
{!
pictureContentMap.setWidth(pictureWidth);!
pictureContentMap.setHeight(picCM.getPictureHeight());!
}!
pictureContentMap.setPictureID(picCM.getPictureID());!
}!
}!
// tell framework to add our map to final output (uses Jackson to process into JSON)!
addOutput(pictureContentMap);!
}!
1!
2!
3!
4!
5!
6!
7!
8!
9!
10!
11!
12!
13!
14!
15!
16!
17!
18!
19!
20!
21!
22!
23!
24!
25!
26!
27!
28!
29!
30!
31!
32!
Mappers - an example
public class PictureMapper extends ProfileParametersAwareMapper!
{!
private PictureContentMap pictureContentMap;!
private static final int ZOOMABLE_DIMENSION = 225;!
!
@Override!
public void doService()!
{!
PictureContentModel picCM = getContent(PictureContentModel.class); //declare content needs!
picCM.criteria().setId(getVieweeId()); //supply any input params!
!
assemble(); //invoke framework to retrieve declared content!
!
if (isResolvedWithoutErrors(picCM))!
{!
//all went well, create new content map to hold output (JavaBean-like objects)!
pictureContentMap = ContentMap.proxyNew(PictureContentMap.class);!
!
Integer pictureWidth = picCM.getPictureWidth(); !
pictureContentMap.setIsZoomable(pictureWidth >= ZOOMABLE_DIMENSION);!
!
if(pictureWidth != null && pictureWidth > 0)!
{!
pictureContentMap.setWidth(pictureWidth);!
pictureContentMap.setHeight(picCM.getPictureHeight());!
}!
pictureContentMap.setPictureID(picCM.getPictureID());!
}!
}!
// tell framework to add our map to final output (uses Jackson to process into JSON)!
addOutput(pictureContentMap);!
}!
1!
2!
3!
4!
5!
6!
7!
8!
9!
10!
11!
12!
13!
14!
15!
16!
17!
18!
19!
20!
21!
22!
23!
24!
25!
26!
27!
28!
29!
30!
31!
32!
Declare the data you need
Set the data you want
coming back as JSON
Mappers - features
●  Modular
o  A single mapper can retrieve data for a section
§  Positions, Educations, Groups, etc. 

●  Reusable & Combinable
o  Mappers can be used more than once
§  Positions Mapper is used for Positions section and the
positions part of Top Card

o  You can Aggregate Mappers under a common
root element and a new URL endpoint
Profile's Many Mappers
●  Each section on Profile has either a single Mapper
or Aggregated Mapper (like Top Card) for its data
Profile's Many Mappers
●  Each section on Profile has either a single Mapper
or Aggregated Mapper (like Top Card) for its data
Summary
Mapper
Positions
Mapper
Educations
Mapper
Picture
Mapper
Top Card
Mapper
"TopCard": {
"positions": {},
"educations":{},
"picture":{}}
Profile Web App
Connections
Mapper
JSON
"Summary":
{ "summary":
"I'm an
experienced..."}
JSON
So we have these Mappers that
return JSON for each section.

Who calls each one?
Groups
Content
Service
Connections
Content
Service
Profile
Content
Service
Client/Browser
 CDN
Load Balancer
SCDS
Fizzy
Profile Web
App
Profile
Content
Service
Profile Web
App
Connections
Content
Service
Groups
Content
Service
Dust/JS/CSS
Server
Retrieve Data
Models
/profile/view?id=32
top_card.tl,
background.tl
/profile/topcard
 /profile/background
Fizzy - the UI aggregator
Fizzy
●  Fizzy is an UI aggregator in 2 parts:
o  Fizzy Server fetches the content you
want
o  Fizzy Client renders it when ready

●  Your base page defines its structure and
which UI components it needs (called
"embeds")
*Fizzy Server is an Apache Traffic Server Plugin, Fizzy Client is a JS library
Profile's Embeds
Top Card Embed
Activity Embed
Embed
Embed
Embed
Embed
Yet another embed
Profile's Embeds in code
<html>
<body>
...
<div id=“wrapper”>
<div id=“profile”>
<script type=“embed” fs-id=“topcard” fs-uri=“/profile/topcard”/>
<script type=“embed” fs-id=“background” fs-uri=“/profile/background”/>
...
<script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/>
</div>
<div id=“insights”>
<script type=“embed” fs-id=“people_you_may_know” fs-uri=“/profile/pymk”/>
<script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/>
...
<script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/>
</div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Profile's Embeds in code
<html>
<body>
...
<div id=“wrapper”>
<div id=“profile”>
<script type=“embed” fs-id=“topcard” fs-uri=“/profile/topcard”/>
<script type=“embed” fs-id=“background” fs-uri=“/profile/background”/>
...
<script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/>
</div>
<div id=“insights”>
<script type=“embed” fs-id=“people_you_may_know” fs-uri=“/profile/pymk”/>
<script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/>
...
<script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/>
</div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Each embed specifies a
Mapper endpoint that
Fizzy will fetch
Fizzy fetches data and sends it
to the browser.

What's rendering the actual
markup?
Groups
Content
Service
Connections
Content
Service
Profile
Content
Service
Client/Browser
 CDN
Load Balancer
SCDS
Fizzy
Profile Web
App
Profile
Content
Service
Profile Web
App
Connections
Content
Service
Groups
Content
Service
Dust/JS/CSS
Server
Retrieve Data
Models
/profile/view?id=32
top_card.tl,
background.tl
/profile/topcard
 /profile/background
You guessed it...
Dust client templates
{Dust} client templates
●  LinkedIn's latest and greatest rendering
layer
●  Logic-less client template language
●  Profile page made up of many* templates
●  Templates + JSON = full markup!
*over 400 actually
{Dust} - what it looks like
<div id="top_card">
<h4>{name}</h4>
<h5>{headline}</h5>
{#info}
<h6>{location} | {industry}</h6>
{/info}
</div>
{
"name": "Frank Stallone",
"headline": "Actor and Less Famous Brother",
"info":{
"location": "Hollywood",
"industry": "Entertainment"
}
}
{Dust} - why it's cool for profile
●  Cached markup in CDNs and browsers
o  Members browse many profiles in a row

●  Very DRY and reusable
o  Improved development speed
o  Templates within templates within templates...
§  date range, degree badge, formatted summary field

●  Super easy to refresh a section on the page
o  Re-render and replace
o  Useful in pagination, inline searching, and inline
editing
{Dust} on profile
<hgroup>
{>"tl/apps/profile/v2/embed/company_logo"/}
<h4>
<a href="{link_title_pivot}" name='title'>{title_highlight|s}</a>
{?selfView}
<span class="edit-tools">
<a class="edit-section">{i18n_Edit}</a>
</span>
{/selfView}
</h4>
<h5>
{?companyName}
{>"tl/apps/profile/v2/embed/company_link" track_param="prof-exp"/}
{/companyName}
</h5>
</hgroup>
<span class="experience-date-locale">
{>"tl/apps/profile/v2/partial/daterange"/}
{! Location !}
{@pre.fmt key="fmt_location" type="geo.region" value="{location}" render="false"/}
{?fmt_location}<span class="locality">{fmt_location}</span>
{:else}
{?locationName}
<span class="locality">{locationName}</span>
{/locationName}
{/fmt_location}
</span>
{>"tl/apps/profile/v2/partial/summary_field" _summary=summary/}
{>"tl/apps/profile/v2/partial/associated_content" trkCodePrefix="exp"/}
{Dust} on profile
<hgroup>
{>"tl/apps/profile/v2/embed/company_logo"/}
<h4>
<a href="{link_title_pivot}" name='title'>{title_highlight|s}</a>
{?selfView}
<span class="edit-tools">
<a class="edit-section">{i18n_Edit}</a>
</span>
{/selfView}
</h4>
<h5>
{?companyName}
{>"tl/apps/profile/v2/embed/company_link" track_param="prof-exp"/}
{/companyName}
</h5>
</hgroup>
<span class="experience-date-locale">
{>"tl/apps/profile/v2/partial/daterange"/}
{! Location !}
{@pre.fmt key="fmt_location" type="geo.region" value="{location}" render="false"/}
{?fmt_location}<span class="locality">{fmt_location}</span>
{:else}
{?locationName}
<span class="locality">{locationName}</span>
{/locationName}
{/fmt_location}
</span>
{>"tl/apps/profile/v2/partial/summary_field" _summary=summary/}
{>"tl/apps/profile/v2/partial/associated_content" trkCodePrefix="exp"/}
Partial templates like this are
used on almost all the
background sections
We have our Mappers, Fizzy,
and Dust templates...

Let's bring it all together.
Feature: Inline Editing
●  Dust + Mappers make this easy
●  Dust templates for view and edit
●  Mappers return just the data we need to refresh
"View" template
"Edit" template
Summary Section
Feature: Inline Editing
●  Dust + Mappers make this easy
●  Dust templates for view and edit
●  Mappers return just the data we need to refresh
"View" template
"Edit" template
Summary Section
When edit link is
clicked, render
"edit" template
Feature: Inline Editing
●  Dust + Mappers make this easy
●  Dust templates for view and edit
●  Mappers return just the data we need to refresh
"View" template
"Edit" template
Summary Section
On submit, our
endpoint sends
back JSON, and
we re-render
Inline editing - Example
Either the "view" or
"edit" template is
shown at a time
Inline editing sounds easy...
●  Issue: Profile data is highly coupled with different
sections.
o  Adding/editing a position needs to be reflected
on Top Card...
o  Deleting a project needs to also be removed
from any associated position...

●  Solution: since we have mappers for each section,
we know which to re-fetch upon a save and
refresh the respective templates
What about pagination, search?
●  Same idea but easier (not coupled with other sections)
●  Mappers can take URL offset params
Switch out a
partial template
containing just list
of profiles
Let's talk performance
High Performance Page
●  Profile is the most trafficked page on
LinkedIn
●  Profile fetches 48+ different types of
content on each page load
o  This content results in 250+ total
downstream calls
High Performance Page
●  Profile is the most trafficked page on
LinkedIn
●  Profile fetches 48+ different types of
content on each page load
o  This content results in 250+ total
downstream calls
Bottom Line: We need to be fast, but
need to consider downstream fanout
High Performance - Parallel Requests
Fizzy
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
In the beginning, Profile had 15
embeds with 15 different endpoints
which is great for speed...
High Performance - Parallel Requests
Fizzy
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
That's a lot of downstream calls, often
requesting the same data too.
Content
Service
Content
Service
High Performance - Parallel Requests
Fizzy
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
and those calls call more and more... until...
High Performance - Parallel Requests
Fizzy
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Profile
App
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
Content
Service
aaaaand the site's down
High Performance - Parallel Requests
●  Tradeoff: Speed vs Scalability
●  15 parallel calls will be fast but with
Profile's load will take down site
High Performance - Parallel Requests
●  Tradeoff: Speed vs Scalability
●  15 parallel calls will be fast but with
Profile's load will take down site
Batched Endpoints to the rescue
Batching Calls to Mappers
Originally, we had
separate endpoints (URIs)
for each embed
<html>
<body>
...
<div id=“wrapper”>
<div id=“profile”>
<script type=“embed” fs-id=“topcard” fs-uri=“/profile/topcard”/>
<script type=“embed” fs-id=“background” fs-uri=“/profile/background”/>
...
<script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/>
</div>
<div id=“insights”>
<script type=“embed” fs-id=“peeps_you_may_know” fs-uri=“/profile/pymk”/>
<script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/>
...
<script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/>
</div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Batching Calls to Mappers
We now tell framework to batch
these two endpoints
(Fizzy knows how to deliver the
right data to the right embed)
<html>
<body>
...
<div id=“wrapper”>
<div id=“profile”>
<script type=“embed” fs-id=“topcard” fs-uri=“/profile/mappers?a=topcard,background”/>
<script type=“embed” fs-id=“background” fs-uri=“/profile/mappers?a=topcard,background”/>
...
<script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/>
</div>
<div id=“insights”>
<script type=“embed” fs-id=“peeps_you_may_know” fs-uri=“/profile/pymk”/>
<script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/>
...
<script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/>
</div>
</div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Batching Calls in Profile
●  Today, we use between 3-5 parallel
requests to Profile
●  It's a good balance of speed vs.
scalability
●  Batching requests that need the same
data has the added benefit of less
downstream calls
Progressive Rendering
With parallel fetch, Profile modules render when
ready for improved perceived performance
Progressive Rendering
With parallel fetch, Profile modules render when
ready for improved perceived performance
How else to improve page load
times?
Profiles can be long...
Embed
Embed
Embed
Embed
Embed
Embed
Embed
Profile Page
Optimize for Above the Fold
Embed
Embed
Embed
Embed
Embed
Embed
Embed
Profile Page
The fold
No need
to render
No need
to render
or fetch
Optimize for Above the Fold
●  The New Profile renders above the fold
as fast as we can
o  Deferring everything at the bottom
o  Reduces the static content we need to initially
download
Optimize for Above the Fold
●  The New Profile renders above the fold
as fast as we can
o  Deferring everything at the bottom
o  Reduces the static content we need to initially
download
Sorry guys, we’ll
get to you later
Optimize for Above the Fold
●  The New Profile defers fetching the
modules at the bottom of the page
o  Improves server side assembly times
o  Lowers payload and improves network time
o  Improves client rendering times
Optimize for Above the Fold
●  The New Profile defers fetching the
modules at the bottom of the page
o  Improves server side assembly times
o  Lowers payload and improves network time
o  Improves client rendering times
Go fetch!
So we covered the product,
technologies, and some
features... let's revisit our goals.
Revisiting the New Profile Goals
●  Needs to surface your entire professional identity
o  Easily expose new data endpoints

●  Needs to be more interactive
o  Inline editing, searching

●  Needs to be
o  Fluid
o  Flexible
o  Fast
Revisiting the New Profile Goals
●  Needs to surface your entire professional identity
o  Easily expose new data endpoints (Mappers)

●  Needs to be more interactive
o  Inline editing, searching (Dust + Mappers)

●  Needs to be
o  Fluid (Fizzy progressive rendering)
o  Flexible (Fizzy deferred rendering)
o  Fast (Fizzy parallel calls + defer fetch, batching
Mappers, Dust template caching)
Takeaways
●  Mappers for each module makes sense
o  You can combine and reuse with ease
o  A must if refreshing part of page

●  When structuring your page, start with many
embeds 
o  You can control number of requests, when
embeds are rendered, and when to fetch data

●  Many partial templates are a good thing
o  Allows you finer control over what to re-render
o  Improves developer speed
Takeaways cont.
●  Make these technologies work for you

o  Our Mappers are structured to guarantee
minimal downstream calls

o  Take advantage of decoupling rendering layer
with server side endpoints
§  Engineers can build endpoints
§  Web devs can start the templates with
mocked JSON data
Questions?

More Related Content

What's hot

Disrupting the application eco system with progressive web applications
Disrupting the application eco system with progressive web applicationsDisrupting the application eco system with progressive web applications
Disrupting the application eco system with progressive web applicationsChris Love
 
HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1James Pearce
 
10 things you can do to speed up your web app today 2016
10 things you can do to speed up your web app today 201610 things you can do to speed up your web app today 2016
10 things you can do to speed up your web app today 2016Chris Love
 
Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt AEM HUB
 
jQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesjQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesMark Roden
 
Service workers your applications never felt so good
Service workers   your applications never felt so goodService workers   your applications never felt so good
Service workers your applications never felt so goodChris Love
 
Using Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the WebUsing Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the Webphilogb
 
WHAT IS HTML5? (at CSS Nite Osaka)
WHAT IS HTML5? (at CSS Nite Osaka)WHAT IS HTML5? (at CSS Nite Osaka)
WHAT IS HTML5? (at CSS Nite Osaka)Shumpei Shiraishi
 
State of jQuery June 2013 - Portland
State of jQuery June 2013 - PortlandState of jQuery June 2013 - Portland
State of jQuery June 2013 - Portlanddmethvin
 
Building single page applications
Building single page applicationsBuilding single page applications
Building single page applicationsSC5.io
 
Adobe AEM CQ5 - Developer Introduction
Adobe AEM CQ5 - Developer IntroductionAdobe AEM CQ5 - Developer Introduction
Adobe AEM CQ5 - Developer IntroductionYash Mody
 
How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...
How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...
How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...David Kaneda
 
jQuery Conference Boston 2011 CouchApps
jQuery Conference Boston 2011 CouchAppsjQuery Conference Boston 2011 CouchApps
jQuery Conference Boston 2011 CouchAppsBradley Holt
 
WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!
WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!
WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!Evan Mullins
 
December 4 SDForum Java Sig Presentation
December 4 SDForum Java Sig PresentationDecember 4 SDForum Java Sig Presentation
December 4 SDForum Java Sig PresentationJonathan Abrams
 
Professional Frontend Engineering
Professional Frontend EngineeringProfessional Frontend Engineering
Professional Frontend EngineeringNate Koechley
 
From Monoliths to Services: Paying Your Technical Debt
From Monoliths to Services: Paying Your Technical DebtFrom Monoliths to Services: Paying Your Technical Debt
From Monoliths to Services: Paying Your Technical DebtTechWell
 

What's hot (20)

Disrupting the application eco system with progressive web applications
Disrupting the application eco system with progressive web applicationsDisrupting the application eco system with progressive web applications
Disrupting the application eco system with progressive web applications
 
HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1HTML5 and the dawn of rich mobile web applications pt 1
HTML5 and the dawn of rich mobile web applications pt 1
 
10 things you can do to speed up your web app today 2016
10 things you can do to speed up your web app today 201610 things you can do to speed up your web app today 2016
10 things you can do to speed up your web app today 2016
 
Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt
 
jQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesjQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPages
 
Service workers your applications never felt so good
Service workers   your applications never felt so goodService workers   your applications never felt so good
Service workers your applications never felt so good
 
Using Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the WebUsing Web Standards to create Interactive Data Visualizations for the Web
Using Web Standards to create Interactive Data Visualizations for the Web
 
WHAT IS HTML5? (at CSS Nite Osaka)
WHAT IS HTML5? (at CSS Nite Osaka)WHAT IS HTML5? (at CSS Nite Osaka)
WHAT IS HTML5? (at CSS Nite Osaka)
 
Crx 2.2 Deep-Dive
Crx 2.2 Deep-DiveCrx 2.2 Deep-Dive
Crx 2.2 Deep-Dive
 
State of jQuery June 2013 - Portland
State of jQuery June 2013 - PortlandState of jQuery June 2013 - Portland
State of jQuery June 2013 - Portland
 
Building single page applications
Building single page applicationsBuilding single page applications
Building single page applications
 
Adobe AEM CQ5 - Developer Introduction
Adobe AEM CQ5 - Developer IntroductionAdobe AEM CQ5 - Developer Introduction
Adobe AEM CQ5 - Developer Introduction
 
How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...
How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...
How to Develop a Rich, Native-quality User Experience for Mobile Using Web St...
 
jQuery Conference Boston 2011 CouchApps
jQuery Conference Boston 2011 CouchAppsjQuery Conference Boston 2011 CouchApps
jQuery Conference Boston 2011 CouchApps
 
Naked and afraid Offline Mobile
Naked and afraid Offline MobileNaked and afraid Offline Mobile
Naked and afraid Offline Mobile
 
WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!
WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!
WordCamp Asheville 2017 - So You Wanna Dev? Join the Team!
 
December 4 SDForum Java Sig Presentation
December 4 SDForum Java Sig PresentationDecember 4 SDForum Java Sig Presentation
December 4 SDForum Java Sig Presentation
 
Professional Frontend Engineering
Professional Frontend EngineeringProfessional Frontend Engineering
Professional Frontend Engineering
 
From Monoliths to Services: Paying Your Technical Debt
From Monoliths to Services: Paying Your Technical DebtFrom Monoliths to Services: Paying Your Technical Debt
From Monoliths to Services: Paying Your Technical Debt
 
mashraqi_farhan
mashraqi_farhanmashraqi_farhan
mashraqi_farhan
 

Viewers also liked

How Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting PlatformHow Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting Platformlucenerevolution
 
Data presentation with dust js technologies backing linkedin
Data presentation with dust js   technologies backing linkedinData presentation with dust js   technologies backing linkedin
Data presentation with dust js technologies backing linkedinRuhaim Izmeth
 
Harvesting the Power of Samza in LinkedIn's Feed
Harvesting the Power of Samza in LinkedIn's FeedHarvesting the Power of Samza in LinkedIn's Feed
Harvesting the Power of Samza in LinkedIn's FeedMohamed El-Geish
 
Since...
Since...Since...
Since...Anna *
 
Memorial Day Pps
Memorial Day PpsMemorial Day Pps
Memorial Day PpsBeckys47201
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSVisual Engineering
 
LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...
LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...
LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...Cory Scott
 
Crossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid World
Crossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid WorldCrossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid World
Crossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid WorldOneLogin
 
LinkedIn OAuth: Zero To Hero
LinkedIn OAuth: Zero To HeroLinkedIn OAuth: Zero To Hero
LinkedIn OAuth: Zero To HeroTaylor Singletary
 
Integrated Cloud Security
Integrated Cloud SecurityIntegrated Cloud Security
Integrated Cloud SecurityOneLogin
 
LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?phegaro
 
HBase: How to get MTTR below 1 minute
HBase: How to get MTTR below 1 minuteHBase: How to get MTTR below 1 minute
HBase: How to get MTTR below 1 minuteHortonworks
 
Using Cloud in an Enterprise Environment
Using Cloud in an Enterprise EnvironmentUsing Cloud in an Enterprise Environment
Using Cloud in an Enterprise EnvironmentMike Crabb
 
Identity and Access Management (IAM)
Identity and Access Management (IAM)Identity and Access Management (IAM)
Identity and Access Management (IAM)Identacor
 
(MBL310) Alexa Voice Service Under the Hood
(MBL310) Alexa Voice Service Under the Hood(MBL310) Alexa Voice Service Under the Hood
(MBL310) Alexa Voice Service Under the HoodAmazon Web Services
 

Viewers also liked (20)

How Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting PlatformHow Lucene Powers the LinkedIn Segmentation and Targeting Platform
How Lucene Powers the LinkedIn Segmentation and Targeting Platform
 
Dust.js
Dust.jsDust.js
Dust.js
 
Data presentation with dust js technologies backing linkedin
Data presentation with dust js   technologies backing linkedinData presentation with dust js   technologies backing linkedin
Data presentation with dust js technologies backing linkedin
 
Linkedin Profile_V2 (1)
Linkedin Profile_V2 (1)Linkedin Profile_V2 (1)
Linkedin Profile_V2 (1)
 
Harvesting the Power of Samza in LinkedIn's Feed
Harvesting the Power of Samza in LinkedIn's FeedHarvesting the Power of Samza in LinkedIn's Feed
Harvesting the Power of Samza in LinkedIn's Feed
 
Since...
Since...Since...
Since...
 
Memorial Day Pps
Memorial Day PpsMemorial Day Pps
Memorial Day Pps
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
 
LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...
LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...
LinkedIn Information Security Talent Pool Research - Black Hat CISO Summit 20...
 
Crossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid World
Crossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid WorldCrossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid World
Crossing the Chasm from On-prem to Cloud: Managing Identities in a Hybrid World
 
LinkedIn OAuth: Zero To Hero
LinkedIn OAuth: Zero To HeroLinkedIn OAuth: Zero To Hero
LinkedIn OAuth: Zero To Hero
 
Integrated Cloud Security
Integrated Cloud SecurityIntegrated Cloud Security
Integrated Cloud Security
 
LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?LinkedIn Mobile: How do we do it?
LinkedIn Mobile: How do we do it?
 
HBase: How to get MTTR below 1 minute
HBase: How to get MTTR below 1 minuteHBase: How to get MTTR below 1 minute
HBase: How to get MTTR below 1 minute
 
DevOps with Chef
DevOps with ChefDevOps with Chef
DevOps with Chef
 
Using Cloud in an Enterprise Environment
Using Cloud in an Enterprise EnvironmentUsing Cloud in an Enterprise Environment
Using Cloud in an Enterprise Environment
 
Identity and Access Management (IAM)
Identity and Access Management (IAM)Identity and Access Management (IAM)
Identity and Access Management (IAM)
 
Amazon Alexa and AWS Lambda
Amazon Alexa and AWS LambdaAmazon Alexa and AWS Lambda
Amazon Alexa and AWS Lambda
 
(MBL310) Alexa Voice Service Under the Hood
(MBL310) Alexa Voice Service Under the Hood(MBL310) Alexa Voice Service Under the Hood
(MBL310) Alexa Voice Service Under the Hood
 
Whats new in web methods 9.12
Whats new in web methods 9.12Whats new in web methods 9.12
Whats new in web methods 9.12
 

Similar to Engineering the New LinkedIn Profile

A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...
A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...
A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...DataLeader.io
 
How We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADFHow We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADFSeanGraham5
 
Pinkoi Mobile Web
Pinkoi Mobile WebPinkoi Mobile Web
Pinkoi Mobile Webmikeleeme
 
Creating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn APICreating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn APIKirsten Hunter
 
Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13MongoDB
 
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack SissonMongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack SissonHakka Labs
 
The Future of CSS with Web components
The Future of CSS with Web componentsThe Future of CSS with Web components
The Future of CSS with Web componentsdevObjective
 
The Future of CSS with Web Components
The Future of CSS with Web ComponentsThe Future of CSS with Web Components
The Future of CSS with Web ComponentsColdFusionConference
 
Headless CMS. Sitecore JSS getting started, tips and tricks
Headless CMS. Sitecore JSS getting started, tips and tricksHeadless CMS. Sitecore JSS getting started, tips and tricks
Headless CMS. Sitecore JSS getting started, tips and tricksArtsem Prashkovich
 
Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...
Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...
Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...Amazon Web Services
 
Getting started with titanium
Getting started with titaniumGetting started with titanium
Getting started with titaniumNaga Harish M
 
Node in Production at Aviary
Node in Production at AviaryNode in Production at Aviary
Node in Production at AviaryAviary
 
(Updated) SharePoint & jQuery Guide
(Updated) SharePoint & jQuery Guide(Updated) SharePoint & jQuery Guide
(Updated) SharePoint & jQuery GuideMark Rackley
 
Getting started with Appcelerator Titanium
Getting started with Appcelerator TitaniumGetting started with Appcelerator Titanium
Getting started with Appcelerator TitaniumTechday7
 
So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017
So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017 So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017
So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017 Evan Mullins
 
Frontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterationsFrontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterationsKarthik Ramgopal
 

Similar to Engineering the New LinkedIn Profile (20)

A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...
A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...
A Microsoft Silverlight User Group Starter Kit Made Available for Everyone to...
 
How We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADFHow We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADF
 
Pinkoi Mobile Web
Pinkoi Mobile WebPinkoi Mobile Web
Pinkoi Mobile Web
 
Creating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn APICreating Professional Applications with the LinkedIn API
Creating Professional Applications with the LinkedIn API
 
Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13Content Delivery at Aviary - NYC MUG 11/19/13
Content Delivery at Aviary - NYC MUG 11/19/13
 
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack SissonMongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
MongoDB and Content Delivery at Aviary by Nir Zicherman and Jack Sisson
 
The Future of CSS with Web components
The Future of CSS with Web componentsThe Future of CSS with Web components
The Future of CSS with Web components
 
The Future of CSS with Web Components
The Future of CSS with Web ComponentsThe Future of CSS with Web Components
The Future of CSS with Web Components
 
Headless CMS. Sitecore JSS getting started, tips and tricks
Headless CMS. Sitecore JSS getting started, tips and tricksHeadless CMS. Sitecore JSS getting started, tips and tricks
Headless CMS. Sitecore JSS getting started, tips and tricks
 
Nodejs.meetup
Nodejs.meetupNodejs.meetup
Nodejs.meetup
 
Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...
Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...
Expedite the development lifecycle with MongoDB and serverless - DEM02 - Sant...
 
Getting started with titanium
Getting started with titaniumGetting started with titanium
Getting started with titanium
 
AspNetWhitePaper
AspNetWhitePaperAspNetWhitePaper
AspNetWhitePaper
 
AspNetWhitePaper
AspNetWhitePaperAspNetWhitePaper
AspNetWhitePaper
 
Building Web Hack Interfaces
Building Web Hack InterfacesBuilding Web Hack Interfaces
Building Web Hack Interfaces
 
Node in Production at Aviary
Node in Production at AviaryNode in Production at Aviary
Node in Production at Aviary
 
(Updated) SharePoint & jQuery Guide
(Updated) SharePoint & jQuery Guide(Updated) SharePoint & jQuery Guide
(Updated) SharePoint & jQuery Guide
 
Getting started with Appcelerator Titanium
Getting started with Appcelerator TitaniumGetting started with Appcelerator Titanium
Getting started with Appcelerator Titanium
 
So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017
So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017 So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017
So, You Wanna Dev? Join the Team! - WordCamp Raleigh 2017
 
Frontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterationsFrontend APIs powering fast paced product iterations
Frontend APIs powering fast paced product iterations
 

Recently uploaded

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 

Recently uploaded (20)

Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 

Engineering the New LinkedIn Profile

  • 1. Engineering the New Profile Josh Clemm Tech Lead for the New Profile March 2013 | LinkedIn David Fleming! Senior Product Manager at Zoomjax! San Francisco Bay Area | Software! ! Previous! Education! Golden Phase, FixDex! Silicon Valley Business Academy!
  • 3. Really a brand new product Refreshed Look & Feel Simplified Design Surfaced New & Interactive Modules New Data Insights
  • 4. New Features Improved in-line editing experience Modules with In-line searching & pagination
  • 5. The New Profile - Goals ●  Represent your entire professional identity o  Not just your resume o  Activity, Groups, Following, Connections, Insights about you and your network
  • 6. The New Profile - Goals ●  Represent your entire professional identity o  Not just your resume o  Activity, Groups, Following, Connections, Insights about you and your network ●  Needs to be more interactive o  Keep users engaged on the page o  Inline pagination, editing, searching
  • 7. The New Profile - Goals ●  Represent your entire professional identity o  Not just your resume o  Activity, Groups, Following, Connections, Insights about you and your network ●  Needs to be more interactive o  Keep users engaged on the page o  Inline pagination, editing, searching ●  Needs to be fluid, flexible, fast o  Progressive rendering o  Maintain high performance
  • 8. So how did we achieve all that?
  • 9. Using a lot of Technologies
  • 11. Let's look at our High Level Frontend Architecture
  • 12. Groups Content Service Connections Content Service Profile Content Service Client/Browser CDN Load Balancer SCDS Fizzy Profile Web App Profile Content Service Profile Web App Connections Content Service Groups Content Service Dust/JS/CSS Server Retrieve Data Models from Mid-tier /profile/view?id=32 top_card.tl, background.tl /profile/topcard /profile/background
  • 13. Groups Content Service Connections Content Service Profile Content Service Client/Browser CDN Load Balancer SCDS Fizzy Profile Web App Profile Content Service Profile Web App Connections Content Service Groups Content Service Dust/JS/CSS Server Retrieve Data Models /profile/view?id=32 top_card.tl, background.tl /profile/topcard /profile/background Our new architecture uses new tech at all layers
  • 14. Groups Content Service Connections Content Service Profile Content Service Client/Browser CDN Load Balancer SCDS Fizzy Profile Web App Profile Content Service Profile Web App Connections Content Service Groups Content Service Dust/JS/CSS Server Retrieve Data Models /profile/view?id=32 top_card.tl, background.tl /profile/topcard /profile/background Let's start at the bottom with Mappers
  • 15. Mappers - JSON endpoints ●  Convert data models from mid-tier services into JSON ●  Each have an unique endpoint URL ( /profile/positions?id=42 ) Positions Mapper JSON "positions": [{ "position": {"id: {}"}, ]} Biz Profile Model Profile Model Rich Media Rest Model References Model Profile Flex Model
  • 16. Mappers - an example public class PictureMapper extends ProfileParametersAwareMapper! {! private PictureContentMap pictureContentMap;! private static final int ZOOMABLE_DIMENSION = 225;! ! @Override! public void doService()! {! PictureContentModel picCM = getContent(PictureContentModel.class); //declare content needs! picCM.criteria().setId(getVieweeId()); //supply any input params! ! assemble(); //invoke framework to retrieve declared content! ! if (isResolvedWithoutErrors(picCM))! {! //all went well, create new content map to hold output (JavaBean-like objects)! pictureContentMap = ContentMap.proxyNew(PictureContentMap.class);! ! Integer pictureWidth = picCM.getPictureWidth(); ! pictureContentMap.setIsZoomable(pictureWidth >= ZOOMABLE_DIMENSION);! ! if(pictureWidth != null && pictureWidth > 0)! {! pictureContentMap.setWidth(pictureWidth);! pictureContentMap.setHeight(picCM.getPictureHeight());! }! pictureContentMap.setPictureID(picCM.getPictureID());! }! }! // tell framework to add our map to final output (uses Jackson to process into JSON)! addOutput(pictureContentMap);! }! 1! 2! 3! 4! 5! 6! 7! 8! 9! 10! 11! 12! 13! 14! 15! 16! 17! 18! 19! 20! 21! 22! 23! 24! 25! 26! 27! 28! 29! 30! 31! 32!
  • 17. Mappers - an example public class PictureMapper extends ProfileParametersAwareMapper! {! private PictureContentMap pictureContentMap;! private static final int ZOOMABLE_DIMENSION = 225;! ! @Override! public void doService()! {! PictureContentModel picCM = getContent(PictureContentModel.class); //declare content needs! picCM.criteria().setId(getVieweeId()); //supply any input params! ! assemble(); //invoke framework to retrieve declared content! ! if (isResolvedWithoutErrors(picCM))! {! //all went well, create new content map to hold output (JavaBean-like objects)! pictureContentMap = ContentMap.proxyNew(PictureContentMap.class);! ! Integer pictureWidth = picCM.getPictureWidth(); ! pictureContentMap.setIsZoomable(pictureWidth >= ZOOMABLE_DIMENSION);! ! if(pictureWidth != null && pictureWidth > 0)! {! pictureContentMap.setWidth(pictureWidth);! pictureContentMap.setHeight(picCM.getPictureHeight());! }! pictureContentMap.setPictureID(picCM.getPictureID());! }! }! // tell framework to add our map to final output (uses Jackson to process into JSON)! addOutput(pictureContentMap);! }! 1! 2! 3! 4! 5! 6! 7! 8! 9! 10! 11! 12! 13! 14! 15! 16! 17! 18! 19! 20! 21! 22! 23! 24! 25! 26! 27! 28! 29! 30! 31! 32! Declare the data you need Set the data you want coming back as JSON
  • 18. Mappers - features ●  Modular o  A single mapper can retrieve data for a section §  Positions, Educations, Groups, etc. ●  Reusable & Combinable o  Mappers can be used more than once §  Positions Mapper is used for Positions section and the positions part of Top Card o  You can Aggregate Mappers under a common root element and a new URL endpoint
  • 19. Profile's Many Mappers ●  Each section on Profile has either a single Mapper or Aggregated Mapper (like Top Card) for its data
  • 20. Profile's Many Mappers ●  Each section on Profile has either a single Mapper or Aggregated Mapper (like Top Card) for its data Summary Mapper Positions Mapper Educations Mapper Picture Mapper Top Card Mapper "TopCard": { "positions": {}, "educations":{}, "picture":{}} Profile Web App Connections Mapper JSON "Summary": { "summary": "I'm an experienced..."} JSON
  • 21. So we have these Mappers that return JSON for each section. Who calls each one?
  • 22. Groups Content Service Connections Content Service Profile Content Service Client/Browser CDN Load Balancer SCDS Fizzy Profile Web App Profile Content Service Profile Web App Connections Content Service Groups Content Service Dust/JS/CSS Server Retrieve Data Models /profile/view?id=32 top_card.tl, background.tl /profile/topcard /profile/background Fizzy - the UI aggregator
  • 23. Fizzy ●  Fizzy is an UI aggregator in 2 parts: o  Fizzy Server fetches the content you want o  Fizzy Client renders it when ready ●  Your base page defines its structure and which UI components it needs (called "embeds") *Fizzy Server is an Apache Traffic Server Plugin, Fizzy Client is a JS library
  • 24. Profile's Embeds Top Card Embed Activity Embed Embed Embed Embed Embed Yet another embed
  • 25. Profile's Embeds in code <html> <body> ... <div id=“wrapper”> <div id=“profile”> <script type=“embed” fs-id=“topcard” fs-uri=“/profile/topcard”/> <script type=“embed” fs-id=“background” fs-uri=“/profile/background”/> ... <script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/> </div> <div id=“insights”> <script type=“embed” fs-id=“people_you_may_know” fs-uri=“/profile/pymk”/> <script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/> ... <script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/> </div> </div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  • 26. Profile's Embeds in code <html> <body> ... <div id=“wrapper”> <div id=“profile”> <script type=“embed” fs-id=“topcard” fs-uri=“/profile/topcard”/> <script type=“embed” fs-id=“background” fs-uri=“/profile/background”/> ... <script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/> </div> <div id=“insights”> <script type=“embed” fs-id=“people_you_may_know” fs-uri=“/profile/pymk”/> <script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/> ... <script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/> </div> </div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Each embed specifies a Mapper endpoint that Fizzy will fetch
  • 27. Fizzy fetches data and sends it to the browser. What's rendering the actual markup?
  • 28. Groups Content Service Connections Content Service Profile Content Service Client/Browser CDN Load Balancer SCDS Fizzy Profile Web App Profile Content Service Profile Web App Connections Content Service Groups Content Service Dust/JS/CSS Server Retrieve Data Models /profile/view?id=32 top_card.tl, background.tl /profile/topcard /profile/background You guessed it... Dust client templates
  • 29. {Dust} client templates ●  LinkedIn's latest and greatest rendering layer ●  Logic-less client template language ●  Profile page made up of many* templates ●  Templates + JSON = full markup! *over 400 actually
  • 30. {Dust} - what it looks like <div id="top_card"> <h4>{name}</h4> <h5>{headline}</h5> {#info} <h6>{location} | {industry}</h6> {/info} </div> { "name": "Frank Stallone", "headline": "Actor and Less Famous Brother", "info":{ "location": "Hollywood", "industry": "Entertainment" } }
  • 31. {Dust} - why it's cool for profile ●  Cached markup in CDNs and browsers o  Members browse many profiles in a row ●  Very DRY and reusable o  Improved development speed o  Templates within templates within templates... §  date range, degree badge, formatted summary field ●  Super easy to refresh a section on the page o  Re-render and replace o  Useful in pagination, inline searching, and inline editing
  • 32. {Dust} on profile <hgroup> {>"tl/apps/profile/v2/embed/company_logo"/} <h4> <a href="{link_title_pivot}" name='title'>{title_highlight|s}</a> {?selfView} <span class="edit-tools"> <a class="edit-section">{i18n_Edit}</a> </span> {/selfView} </h4> <h5> {?companyName} {>"tl/apps/profile/v2/embed/company_link" track_param="prof-exp"/} {/companyName} </h5> </hgroup> <span class="experience-date-locale"> {>"tl/apps/profile/v2/partial/daterange"/} {! Location !} {@pre.fmt key="fmt_location" type="geo.region" value="{location}" render="false"/} {?fmt_location}<span class="locality">{fmt_location}</span> {:else} {?locationName} <span class="locality">{locationName}</span> {/locationName} {/fmt_location} </span> {>"tl/apps/profile/v2/partial/summary_field" _summary=summary/} {>"tl/apps/profile/v2/partial/associated_content" trkCodePrefix="exp"/}
  • 33. {Dust} on profile <hgroup> {>"tl/apps/profile/v2/embed/company_logo"/} <h4> <a href="{link_title_pivot}" name='title'>{title_highlight|s}</a> {?selfView} <span class="edit-tools"> <a class="edit-section">{i18n_Edit}</a> </span> {/selfView} </h4> <h5> {?companyName} {>"tl/apps/profile/v2/embed/company_link" track_param="prof-exp"/} {/companyName} </h5> </hgroup> <span class="experience-date-locale"> {>"tl/apps/profile/v2/partial/daterange"/} {! Location !} {@pre.fmt key="fmt_location" type="geo.region" value="{location}" render="false"/} {?fmt_location}<span class="locality">{fmt_location}</span> {:else} {?locationName} <span class="locality">{locationName}</span> {/locationName} {/fmt_location} </span> {>"tl/apps/profile/v2/partial/summary_field" _summary=summary/} {>"tl/apps/profile/v2/partial/associated_content" trkCodePrefix="exp"/} Partial templates like this are used on almost all the background sections
  • 34. We have our Mappers, Fizzy, and Dust templates... Let's bring it all together.
  • 35. Feature: Inline Editing ●  Dust + Mappers make this easy ●  Dust templates for view and edit ●  Mappers return just the data we need to refresh "View" template "Edit" template Summary Section
  • 36. Feature: Inline Editing ●  Dust + Mappers make this easy ●  Dust templates for view and edit ●  Mappers return just the data we need to refresh "View" template "Edit" template Summary Section When edit link is clicked, render "edit" template
  • 37. Feature: Inline Editing ●  Dust + Mappers make this easy ●  Dust templates for view and edit ●  Mappers return just the data we need to refresh "View" template "Edit" template Summary Section On submit, our endpoint sends back JSON, and we re-render
  • 38. Inline editing - Example Either the "view" or "edit" template is shown at a time
  • 39. Inline editing sounds easy... ●  Issue: Profile data is highly coupled with different sections. o  Adding/editing a position needs to be reflected on Top Card... o  Deleting a project needs to also be removed from any associated position... ●  Solution: since we have mappers for each section, we know which to re-fetch upon a save and refresh the respective templates
  • 40. What about pagination, search? ●  Same idea but easier (not coupled with other sections) ●  Mappers can take URL offset params Switch out a partial template containing just list of profiles
  • 42. High Performance Page ●  Profile is the most trafficked page on LinkedIn ●  Profile fetches 48+ different types of content on each page load o  This content results in 250+ total downstream calls
  • 43. High Performance Page ●  Profile is the most trafficked page on LinkedIn ●  Profile fetches 48+ different types of content on each page load o  This content results in 250+ total downstream calls Bottom Line: We need to be fast, but need to consider downstream fanout
  • 44. High Performance - Parallel Requests Fizzy Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App In the beginning, Profile had 15 embeds with 15 different endpoints which is great for speed...
  • 45. High Performance - Parallel Requests Fizzy Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service That's a lot of downstream calls, often requesting the same data too. Content Service Content Service
  • 46. High Performance - Parallel Requests Fizzy Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service and those calls call more and more... until...
  • 47. High Performance - Parallel Requests Fizzy Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Profile App Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service Content Service aaaaand the site's down
  • 48. High Performance - Parallel Requests ●  Tradeoff: Speed vs Scalability ●  15 parallel calls will be fast but with Profile's load will take down site
  • 49. High Performance - Parallel Requests ●  Tradeoff: Speed vs Scalability ●  15 parallel calls will be fast but with Profile's load will take down site Batched Endpoints to the rescue
  • 50. Batching Calls to Mappers Originally, we had separate endpoints (URIs) for each embed <html> <body> ... <div id=“wrapper”> <div id=“profile”> <script type=“embed” fs-id=“topcard” fs-uri=“/profile/topcard”/> <script type=“embed” fs-id=“background” fs-uri=“/profile/background”/> ... <script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/> </div> <div id=“insights”> <script type=“embed” fs-id=“peeps_you_may_know” fs-uri=“/profile/pymk”/> <script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/> ... <script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/> </div> </div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  • 51. Batching Calls to Mappers We now tell framework to batch these two endpoints (Fizzy knows how to deliver the right data to the right embed) <html> <body> ... <div id=“wrapper”> <div id=“profile”> <script type=“embed” fs-id=“topcard” fs-uri=“/profile/mappers?a=topcard,background”/> <script type=“embed” fs-id=“background” fs-uri=“/profile/mappers?a=topcard,background”/> ... <script type=“embed” fs-id=“connections” fs-uri=“/profile/connections”/> </div> <div id=“insights”> <script type=“embed” fs-id=“peeps_you_may_know” fs-uri=“/profile/pymk”/> <script type=“embed” fs-id=“strength_meter” fs-uri=“/profile/strength”/> ... <script type=“embed” fs-id=“in_common” fs-uri=“/profile/incommon”/> </div> </div> </body> </html> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
  • 52. Batching Calls in Profile ●  Today, we use between 3-5 parallel requests to Profile ●  It's a good balance of speed vs. scalability ●  Batching requests that need the same data has the added benefit of less downstream calls
  • 53. Progressive Rendering With parallel fetch, Profile modules render when ready for improved perceived performance
  • 54. Progressive Rendering With parallel fetch, Profile modules render when ready for improved perceived performance
  • 55. How else to improve page load times?
  • 56. Profiles can be long... Embed Embed Embed Embed Embed Embed Embed Profile Page
  • 57. Optimize for Above the Fold Embed Embed Embed Embed Embed Embed Embed Profile Page The fold No need to render No need to render or fetch
  • 58. Optimize for Above the Fold ●  The New Profile renders above the fold as fast as we can o  Deferring everything at the bottom o  Reduces the static content we need to initially download
  • 59. Optimize for Above the Fold ●  The New Profile renders above the fold as fast as we can o  Deferring everything at the bottom o  Reduces the static content we need to initially download Sorry guys, we’ll get to you later
  • 60. Optimize for Above the Fold ●  The New Profile defers fetching the modules at the bottom of the page o  Improves server side assembly times o  Lowers payload and improves network time o  Improves client rendering times
  • 61. Optimize for Above the Fold ●  The New Profile defers fetching the modules at the bottom of the page o  Improves server side assembly times o  Lowers payload and improves network time o  Improves client rendering times Go fetch!
  • 62. So we covered the product, technologies, and some features... let's revisit our goals.
  • 63. Revisiting the New Profile Goals ●  Needs to surface your entire professional identity o  Easily expose new data endpoints ●  Needs to be more interactive o  Inline editing, searching ●  Needs to be o  Fluid o  Flexible o  Fast
  • 64. Revisiting the New Profile Goals ●  Needs to surface your entire professional identity o  Easily expose new data endpoints (Mappers) ●  Needs to be more interactive o  Inline editing, searching (Dust + Mappers) ●  Needs to be o  Fluid (Fizzy progressive rendering) o  Flexible (Fizzy deferred rendering) o  Fast (Fizzy parallel calls + defer fetch, batching Mappers, Dust template caching)
  • 65. Takeaways ●  Mappers for each module makes sense o  You can combine and reuse with ease o  A must if refreshing part of page ●  When structuring your page, start with many embeds o  You can control number of requests, when embeds are rendered, and when to fetch data ●  Many partial templates are a good thing o  Allows you finer control over what to re-render o  Improves developer speed
  • 66. Takeaways cont. ●  Make these technologies work for you o  Our Mappers are structured to guarantee minimal downstream calls o  Take advantage of decoupling rendering layer with server side endpoints §  Engineers can build endpoints §  Web devs can start the templates with mocked JSON data

Editor's Notes

  1. New &amp; interactive modules like: Connections, Following, Activity, PYMK, Similar profiles, Data insights, and improved Recommendations and Groups modules.
  2. Profile 2.0 high level architectural diagram. The old page used to make 1 request to the profile web app, where a JSP with its various data was rendered, returning HTML. In the new architecture, we have a base page specifying which content we want on the page, and a new layer called Fizzy makes the requests for us. This results in parallel asynchronous calls to our Profile web app, retreiving JSON instead. Fizzy then streams back that JSON and uses Dust client templates to finally render page in the browser.
  3. Convert incoming data models from mid-tier services into JSON
  4. Convert incoming data models from mid-tier services into JSON