Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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.

Siddharth Kshetrapal

October 07, 2017
Tweet

More Decks by Siddharth Kshetrapal

Other Decks in Technology

Transcript

  1. Building
    real time data heavy
    interfaces for SaaS

    View full-size slide

  2. Siddharth Kshetrapal

    View full-size slide

  3. @siddharthkp

    View full-size slide

  4. @siddharthkp
    javascript architect

    View full-size slide

  5. @siddharthkp
    javascript architect
    past: practo

    View full-size slide

  6. @siddharthkp
    interfaces, web performance, open source

    View full-size slide

  7. bit.ly/siddharthkpshow

    View full-size slide

  8. Building
    real time data heavy
    interfaces for SaaS

    View full-size slide

  9. Building
    real time data heavy
    interfaces for SaaS

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  13. shot by Joshua Sortino

    View full-size slide

  14. shot by Petr Knoll

    View full-size slide

  15. shot by Imran Khan

    View full-size slide

  16. shot by Rajat Kashyap

    View full-size slide

  17. shot by Eric Hoffman

    View full-size slide

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

    View full-size slide

  19. would this scale?
    lol no

    View full-size slide

  20. 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)
    })
    })

    View full-size slide

  21. 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)
    })
    })

    View full-size slide

  22. 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)
    })
    })

    View full-size slide

  23. 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)
    })
    })

    View full-size slide

  24. 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)
    })
    })

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  29. 10x developers

    View full-size slide

  30. shot by Imran Khan

    View full-size slide

  31. npm install idb-wrapper

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  34. 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)

    View full-size slide

  35. 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)

    View full-size slide

  36. 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)

    View full-size slide

  37. apptStore.get(1, callback, errorCB)
    apptStore.getAll
    apptStore.query
    apptStore.remove
    apptStore.clear

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  40. eager fetching

    View full-size slide

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

    View full-size slide

  42. const io = require('socket.io-client')
    const socket = io('http://localhost:3000')
    socket.on('appointment', data => {
    apptStore.put(data)
    })

    View full-size slide

  43. main thead locked?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  49. @siddharthkp
    DM is open, say hi!

    View full-size slide

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

    View full-size slide