$30 off During Our Annual Pro Sale. View Details »

[SymfonyLive Paris 2020] Pragmatic frontend for Symfony developers

[SymfonyLive Paris 2020] Pragmatic frontend for Symfony developers

Titouan Galopin

September 24, 2020
Tweet

More Decks by Titouan Galopin

Other Decks in Programming

Transcript

  1. Pragmatic
    frontend for
    Symfony
    developers
    Titouan GALOPIN
    SymfonyLive
    Paris 2020

    View Slide

  2. 2
    Titouan Galopin
    Product Manager
    SymfonyInsight
    insight.symfony.com

    View Slide

  3. 3
    The Why

    View Slide

  4. 4
    Why is frontend
    development
    so complex?

    View Slide

  5. 5
    Thinking about modern
    software architectures
    requires frontend choices

    View Slide

  6. 6
    Let’s discuss!

    View Slide

  7. Agenda
    1. A bit of history
    2. Modern frontend
    3. The least complex
    technology possible
    4. Approaches to
    frontend with
    Symfony
    7

    View Slide

  8. 8
    1.
    A bit of history

    View Slide

  9. 9
    1990–1995
    HTML, CSS and JavaScript
    are invented
    JavaScript aims at improving UX

    View Slide

  10. 10
    1996–1999
    Standardization efforts begin
    Browser compliance is terrible

    View Slide

  11. 2000–2004
    CSS frameworks begin to emerge
    jQuery is born
    11

    View Slide

  12. 2005–2009
    W3C specification is met
    Responsive designs and frameworks
    introduced
    12

    View Slide

  13. 13
    2010–2015
    JS frameworks are born (Backbone,
    Ember, Angular, React, Vue, ...)
    HTML5 is announced

    View Slide

  14. 14
    2016–2020
    New technologies and platforms built
    around modern frontend emerge:
    GraphQL, Service Workers, Cordova,
    Electron, React Native, …

    View Slide

  15. 15
    Modern frontend
    development is a direct
    consequence of this
    history

    View Slide

  16. 16
    What is Modern Frontend?

    View Slide

  17. 17
    2.
    Modern frontend

    View Slide

  18. 18
    Modern frontend is
    supposed to be about
    user experience

    View Slide

  19. 19
    “Nowadays, users expect
    more from websites
    (performance, help,
    productivity, …)”

    View Slide

  20. 20
    Ever wondered whether a
    loader was actually loading
    or was broken?

    View Slide

  21. 21
    Ever been frustrated about a
    Back button click returning
    to the wrong page?

    View Slide

  22. 22
    Ever been disappointed by
    a link you couldn’t
    open in a new tab?

    View Slide

  23. 23
    Ever been angered by a
    website you couldn’t open in
    multiple tabs without
    messing with the data?

    View Slide

  24. 24
    Ever had to disable your
    adblocker to make a website
    work?

    View Slide

  25. 25
    Ever had to use a screen
    reader on a fully
    Javascript interface?

    View Slide

  26. 26
    Full-page apps
    (for instance create-react-app)
    is not an answer to
    the UX problem

    View Slide

  27. 27
    It’s easy to do it
    really wrong
    and hurts UX a lot

    View Slide

  28. 28
    Modern frontend
    !=
    Full-page app

    View Slide

  29. 29
    Full-page app
    is a solution to a
    different problem

    View Slide

  30. 30
    How to build a website and
    a mobile application with
    the same backend?

    View Slide

  31. 31
    3.
    The least
    complex
    technology
    possible

    View Slide

  32. How many times did you
    experience PHP failing
    between a function call and
    the first line of the function?
    32

    View Slide

  33. How many times did you
    experience an AJAX call
    failing between the request
    and the response?
    33

    View Slide

  34. 34
    The network is a huge
    source of complexity

    View Slide

  35. How many times did you
    develop your own session
    system in PHP?
    35

    View Slide

  36. How many times did you
    develop your own session
    history stack in PHP?
    36

    View Slide

  37. 37
    Not using the features of
    the browser is a source of
    complexity

    View Slide

  38. How many developers in
    your team know perfectly
    well both React and
    Symfony?
    38

    View Slide

  39. 39
    Backend and Frontend are
    two different jobs:
    human complexity

    View Slide

  40. KISS
    Keep It Super Simple
    40

    View Slide

  41. By default, use the simplest
    option available
    Migrate to something more
    complex only if necessary
    41

    View Slide

  42. The simplest option
    =
    HTML + CSS built with PHP
    42

    View Slide

  43. But it’s sometimes not
    enough...
    43

    View Slide

  44. 44
    4.
    Approaches to
    frontend with
    Symfony

    View Slide

  45. 45
    No JS
    Misses the real UX gain of
    Javascript, but still possible

    View Slide

  46. 46
    Full-page app + API
    Has a lot of drawbacks but is
    the only option for multiple
    clients (web + mobile)

    View Slide

  47. 47
    Progressive enhancement
    A pragmatic in-between

    View Slide

  48. 48
    Basing Javascript
    behaviors on
    HTTP and HTML

    View Slide

  49. 49
    Most recent JS
    frameworks
    (React, Vue, …)
    can be used in limited
    parts of the page

    View Slide

  50. 50
    What about using React
    only where it brings actual
    improvements?

    View Slide

  51. 51
    Using React to enhance
    your Symfony application

    View Slide

  52. 52
    1. Develop your
    application
    as usual

    View Slide

  53. 53
    {# index.html.twig #}
    {% extends 'base.html.twig' %}
    {% block body %}

    Hello world

    placeholder="Color in hexadecimal" />


    {% endblock %}

    View Slide

  54. 54
    {# index.html.twig #}
    {% extends 'base.html.twig' %}
    {% block body %}

    Hello world

    placeholder="Color in hexadecimal" />


    {% endblock %}
    This could be a Symfony
    Form field

    View Slide

  55. 55
    2. Add React only
    where it’s useful

    View Slide

  56. 56
    composer req --dev webpack
    yarn install
    https://symfony.com/doc/current/frontend.html

    View Slide

  57. 57
    Webpack is a build tool
    It lets you manipulate your Javascript
    and CSS before using it in production
    (JSX, minification, …)

    View Slide

  58. 58
    Webpack Encore wraps
    Webpack around a nice API
    to improve its Developer
    Experience

    View Slide

  59. 59
    Webpack Encore is
    awesome to compile React
    apps to normal Javascript

    View Slide

  60. 60
    yarn add
    @babel/preset-react
    react
    react-dom
    prop-types

    View Slide

  61. 61
    // webpack.config.js
    Encore.enableReactPreset()

    View Slide

  62. 62
    {# index.html.twig #}
    {% extends 'base.html.twig' %}
    {% block body %}

    Hello world

    placeholder="Color in hexadecimal" />


    {% endblock %}
    Marker to find where to
    inject a React component

    View Slide

  63. 63
    // app.js
    import ReactDOM from 'react-dom';
    import {ColorChooser} from './ColorChooser/ColorChooser';
    $('div[data-color-chooser]').each((key, node) => {
    const input = $(node).find('input');
    ReactDOM.render(
    color={input.val()}
    onColorChange={(color) => input.attr('value', color)}
    />,
    node
    );
    });

    View Slide

  64. 64
    // app.js
    import ReactDOM from 'react-dom';
    import {ColorChooser} from './ColorChooser/ColorChooser';
    $('div[data-color-chooser]').each((key, node) => {
    const input = $(node).find('input');
    ReactDOM.render(
    color={input.val()}
    onColorChange={(color) => input.attr('value', color)}
    />,
    node
    );
    });
    Using a selector library to
    find the node

    View Slide

  65. 65
    // app.js
    import ReactDOM from 'react-dom';
    import {ColorChooser} from './ColorChooser/ColorChooser';
    $('div[data-color-chooser]').each((key, node) => {
    const input = $(node).find('input');
    ReactDOM.render(
    color={input.val()}
    onColorChange={(color) => input.attr('value', color)}
    />,
    node
    );
    });
    Replacing the content of
    the node by the React tree

    View Slide

  66. 66

    View Slide

  67. 67
    ✓ Allow to use great React components
    where it’s useful
    ✓ Do not add unnecessary complexity
    ✓ 100% compatible with Symfony Forms,
    HTTP, default browser behaviors, ...

    View Slide

  68. 68
    3. How to transfer data
    from the backend to the
    frontend?

    View Slide

  69. 69
    HTML5 is awesome

    View Slide

  70. 70
    ✓ HTML5 is scoped: data concerning a
    node is stored as attributes of the node
    ✓ HTML5 is semantic: many use cases are
    already considered in the standard
    ✓ HTML5 is flexible: you can add your own
    attributes

    View Slide

  71. 71
    {# index.html.twig #}
    {% extends 'base.html.twig' %}
    {% block body %}

    Hello world
    data-color-chooser-type="circles">
    placeholder="Color in hexadecimal" />


    {% endblock %}
    Option which could be coming
    from a Twig variable

    View Slide

  72. 72
    // app.js
    // ...
    $('div[data-color-chooser]').each((key, node) => {
    const input = $(node).find('input');
    ReactDOM.render(
    type={node.getAttribute('data-color-chooser-type')}
    color={input.val()}
    onColorChange={(color) => input.attr('value', color)}
    />,
    node
    );
    });
    Using the option from the data
    attribute is easy because it’s
    scoped to the node

    View Slide

  73. 73

    View Slide

  74. 74
    ✓ Easy to use (scoped and accessible in the
    appropriate Javascript context)
    ✓ Compatible with Content Security Policy
    ✓ Easy automatic testing

    View Slide

  75. 75
    4. How to transfer data
    from the frontend to the
    backend?

    View Slide

  76. 76
    Use an API focused on
    your Javascript needs

    View Slide

  77. 77
    fetch() is native in most browsers
    Polyfills exist for others

    View Slide

  78. 78
    Do not develop an API
    if you don’t need it!
    Keep things as simple as possible

    View Slide

  79. 79
    5. Avoiding page refresh
    without an SPA

    View Slide

  80. 80
    What is an API?
    A way to transfer data in a
    structured way

    View Slide

  81. 81
    HTML contains data, in a
    structured way, and is
    already made to be displayed
    by the browser

    View Slide

  82. 82
    What if we used our
    traditional HTML
    application instead of
    an API?

    View Slide

  83. 83
    Turbolinks
    A tiny library which replace links in
    your application with AJAX calls to
    switch the HTML on the fly

    View Slide

  84. 84
    yarn add turbolinks

    View Slide

  85. 85
    // app.js
    import Turbolinks from 'turbolinks';
    Turbolinks.start();

    View Slide

  86. 86
    ✓ Same “no-refresh” effect as SPA
    ✓ Fully compatible with browser history,
    sessions, cache, …
    ✓ Better SEO (HTML rendered on the server)
    ✓ No added complexity over traditional
    Symfony apps

    View Slide

  87. 87
    (by the way, that’s how Github works)

    View Slide

  88. 88
    Conclusion

    View Slide

  89. KISS
    Keep It Super Simple
    89

    View Slide

  90. The simplest option
    =
    HTML + CSS built with PHP
    90

    View Slide

  91. It useful for UX, add
    Javascript in some places
    91

    View Slide

  92. Using Javascript that relies
    on browser features
    decreases complexity
    92

    View Slide

  93. Full-page apps are useful in
    some situations …
    but not a solution for UX!
    93

    View Slide

  94. Thanks!
    94
    For any question:
    ▪ @titouangalopin
    on Twitter
    ▪ titouan.galopin
    @symfony.com

    View Slide