api prefetching - html5devconf - oct. 21, 2014
DESCRIPTION
Single page apps and Front-end rendering are all the rage. They have a lot of benefits, but one major downside is the need to make an API call once the page is first loaded. This presentation shows off a trick (and library) to easily fix that problem, regardless of front-end framework.TRANSCRIPT
Front-End or Back-End Templating?
Getting the best of both
Jon Abrams (@JonathanAbrams)
Server Side Rendering
Jon Abrams (@JonathanAbrams)
e.g. Most PHP, Rails, and Django apps
Client Server
Goes to URL
Final HTML rendered
User interacts
Final HTML rendered
Entire web page reloaded
Jon Abrams (@JonathanAbrams)
Server Side Rendering
Client Side Rendering
Jon Abrams (@JonathanAbrams)
Loading…
Client Side Rendering
Jon Abrams (@JonathanAbrams)
e.g. AngularJS, Backbone, and EmberJS apps
Client Server
Goes to URL
Returns layout HTMLBrowser processes JS
Initiates API call
Returns JSON data
User interacts Another API call
Returns JSON data
Jon Abrams (@JonathanAbrams)
Client Side Rendering
Benefits: Server Side vs Client Side
Server Side: • Returns data + layout
in one go round-trip. • Doesn’t require
JavaScript support from client.
• Has great frameworks like Rails and Django.
Benefits: Server Side vs Client Side
Client: • Web app uses same API
as mobile apps. • No refreshing while
using the app. • Has great frameworks
like Angular and Ember.
API Pre-Fetching
Jon Abrams (@JonathanAbrams)
Client Server
Goes to URL
User interacts
Returns layout HTML + JSON data
Returns JSON data
Jon Abrams (@JonathanAbrams)
API Pre-Fetching
<script src="/jquery.js"></script> <script> window.apiPrefetchData = { "/api/posts": […], "/api/user": {…} }; </script> <script src="/main.js"></script>
API Pre-FetchingRendered index.html:
Front-end rendering without API prefetching
Final Rendering Step Start Time: 607 msJon Abrams (@JonathanAbrams)
Front-end rendering with API prefetching
Final Rendering Step Start Time: 519 ms17% Faster
apiPrefetch.jshttps://github.com/JonAbrams/apiPrefetch.js
Jon Abrams (@JonathanAbrams)
apiPrefetch.js
https://github.com/JonAbrams/apiPrefetch.js
<script src="/apiPrefetch.js"></script> <script src="/jquery.js"></script> <script> window.apiPrefetchData = { "/api/posts": […], "/api/user": {…} }; </script> <script src="/main.js"></script>
apiPrefetch.js
https://github.com/JonAbrams/apiPrefetch.js
<script> $.getJSON('/api/posts') // gets prefetched data $.getJSON('/api/posts') // hits server $.getJSON('/api/stuff') // uses prefetched data $.post('/api/user') // hits server $.getJSON('/api/user') // uses prefetched data </script>
Main.js:
Back-end Requirements for API Pre-fetching
Jon Abrams (@JonathanAbrams)
Escape ‘forward-slash’
1
Escape ‘forward-slash’
Or else users can inject code.
"</script><script>alert(“oh no!”)</script>”
To make it safe:
<\/script><script>Still a harmless string</script>
Jon Abrams (@JonathanAbrams)
Escape ‘forward-slash’
Jon Abrams (@JonathanAbrams)
JSON.stringify(obj).replace(/\//g, “\\/“);
Map your view URLs to your API URLs
2
Map your view URLs to your API URLs
For example:mysite.com/tweets -> mysite.com/api/tweets
Jon Abrams (@JonathanAbrams)
Your front-end app needs to run in HTML5 mode
3
Your front-end app needs to run in HTML5 mode
The server is not sent anything after the # character in a URL.
e.g.mysite.com/stuff is goodmysite.com/#stuff is bad
Jon Abrams (@JonathanAbrams)
Your API request handlers need to be invokable by
the server itself.
4
Your API request handlers need to be invokable by
the server itself.
The same code used to handle incoming API requests need to be invoked by your view request handler too.
Jon Abrams (@JonathanAbrams)
Use cookies for authentication
5
Use cookies for authentication
Or else the server doesn’t know if the user can access the data on initial fetch.
Jon Abrams (@JonathanAbrams)
Libraries / Frameworks• Front-end: apiPrefetch.js
• Node.js: Synth (synthjs.com)
• Rails: ?
• Java: ?
• Python: ?
• PHP: ?
Jon Abrams (@JonathanAbrams)
Why Pre-fetch API calls but not static assets?
• Assets are already cached by the browser.
• Assets can be served from a CDN.
• Can be fetched (or even pre-fetched) before the JS is executed.
• Assets can be sent down with the initial response when HTTP 2.0 is a thing.
Why Pre-fetch API calls but not static assets?
Jon Abrams (@JonathanAbrams)
LinksapiPrefetch.js: github.com/JonAbrams/apiPrefetch.js
Synth: synthjs.com
Me on Twitter: twitter.com/JonathanAbrams