Building real time data heavy interfaces for SaaS

Building real time data heavy interfaces for SaaS

SaaS products are fundamentally different from mass consumer products when it comes to performance. Because the content is tailored to the user and changes rapidly, most of our textbook strategies don't help.
But, the web is for everyone 🙂 Come, find out the platform features you can leverage to build great UX for your SaaS users.

Ea26ebbe66c3bb6afb5f711cfe766dff?s=128

Siddharth Kshetrapal

October 07, 2017
Tweet

Transcript

  1. Building real time data heavy interfaces for SaaS

  2. Siddharth Kshetrapal

  3. @siddharthkp

  4. @siddharthkp javascript architect

  5. @siddharthkp javascript architect past: practo

  6. @siddharthkp interfaces, web performance, open source

  7. bit.ly/siddharthkpshow

  8. Building real time data heavy interfaces for SaaS

  9. Building real time data heavy interfaces for SaaS

  10. - user tailored content - N users - data changes

    fast
  11. - user tailored content - N users - data changes

    fast
  12. - user tailored content - N users - data changes

    fast
  13. shot by Joshua Sortino

  14. shot by Petr Knoll

  15. shot by Imran Khan

  16. None
  17. shot by Rajat Kashyap

  18. None
  19. shot by Eric Hoffman

  20. - user tailored content - N users - data changes

    fast
  21. None
  22. real time

  23. 2012

  24. 2012

  25. polling

  26. None
  27. None
  28. would this scale? lol no

  29. socket.io@1.0.0

  30. const server = require('http').createServer().listen(3000) const io = require('socket.io')(server) io.on('connection', socket

    => { socket.on('appointment', data => { socket.broadcast.emit('appointment', data) }) })
  31. const server = require('http').createServer().listen(3000) const io = require('socket.io')(server) io.on('connection', socket

    => { socket.on('appointment', data => { socket.broadcast.emit('appointment', data) }) })
  32. const server = require('http').createServer().listen(3000) const io = require('socket.io')(server) io.on('connection', socket

    => { socket.on('appointment', data => { socket.broadcast.emit('appointment', data) }) })
  33. const server = require('http').createServer().listen(3000) const io = require('socket.io')(server) io.on('connection', socket

    => { socket.on('appointment', data => { socket.broadcast.emit('appointment', data) }) })
  34. const server = require('http').createServer().listen(3000) const io = require('socket.io')(server) io.on('connection', socket

    => { socket.on('appointment', data => { socket.broadcast.emit('appointment', data) }) })
  35. const io = require('socket.io-client') const socket = io('http://localhost:3000') socket.on('appointment', data

    => { // update calendar })
  36. const io = require('socket.io-client') const socket = io('http://localhost:3000') socket.on('appointment', data

    => { // update calendar })
  37. const io = require('socket.io-client') const socket = io('http://localhost:3000') socket.on('appointment', data

    => { // update calendar })
  38. const io = require('socket.io-client') const socket = io('http://localhost:3000') socket.on('appointment', data

    => { // update calendar })
  39. None
  40. None
  41. None
  42. None
  43. 10x developers

  44. 10x doctors

  45. None
  46. None
  47. shot by Imran Khan

  48. None
  49. None
  50. npm install idb-wrapper

  51. const IDBStore = require('idb-wrapper') const apptStore = new IDBStore({ dbVersion:

    1, storeName: 'appointments', keyPath: 'id', autoIncrement: true })
  52. const IDBStore = require('idb-wrapper') const apptStore = new IDBStore({ dbVersion:

    1, storeName: 'appointments', keyPath: 'id', autoIncrement: true })
  53. apptStore.put({ id: 1, patient_name: 'Siddharth', doctor_id: 2, start_time: '2017-10-07 10:00:00',

    end_time: '2017-10-07 10:30:00' }, callback, errorCallback) apptStore.batch(arrayOfAppointments, callback, errorCB)
  54. apptStore.put({ id: 1, patient_name: 'Siddharth', doctor_id: 2, start_time: '2017-10-07 10:00:00',

    end_time: '2017-10-07 10:30:00' }, callback, errorCallback) apptStore.batch(arrayOfAppointments, callback, errorCB)
  55. apptStore.put({ id: 1, patient_name: 'Siddharth', doctor_id: 2, start_time: '2017-10-07 10:00:00',

    end_time: '2017-10-07 10:30:00' }, callback, errorCallback) apptStore.batch(arrayOfAppointments, callback, errorCB)
  56. apptStore.get(1, callback, errorCB) apptStore.getAll apptStore.query apptStore.remove apptStore.clear

  57. None
  58. get('/api/appointments?from=2017-10-06&till=2017-10-13') .then(appointments => { apptStore.batch(appointments, callback, errorCB) })

  59. get('/api/appointments?from=2017-10-06&till=2017-10-13') .then(appointments => { apptStore.batch(appointments, callback, errorCB) })

  60. eager fetching

  61. None
  62. get('/api/appointments?updated_after=2017-10-06 10:30:00') .then(appointments => { apptStore.batch(appointments, callback, errorCB) })

  63. const io = require('socket.io-client') const socket = io('http://localhost:3000') socket.on('appointment', data

    => { apptStore.put(data) })
  64. main thead locked?

  65. None
  66. const worker = new Worker('sync.js') worker.postMessage({trigger: 'start_sync'})

  67. const worker = new Worker('sync.js') worker.postMessage({trigger: 'start_sync'})

  68. // sync.js self.onMessage(message => if (message.trigger === 'start_sync') { //

    fetch data from api // batch update indexedDB } })
  69. // sync.js self.onMessage(message => if (message.trigger === 'start_sync') { //

    fetch data from api // batch update indexedDB } })
  70. // sync.js self.onMessage(message => if (message.trigger === 'start_sync') { //

    fetch data from api // batch update indexedDB } })
  71. None
  72. @siddharthkp DM is open, say hi!

  73. @siddharthkp DM is open, say hi! bit.ly/react-training