Published "A Tour of MPJ: Conclusion" post

also added link to intro
This commit is contained in:
Daniel J. Summers 2018-09-02 07:20:27 -05:00
parent 2fb25268dd
commit 580d123d5e
2 changed files with 37 additions and 20 deletions

View File

@ -4,29 +4,39 @@ title: "A Tour of myPrayerJournal: Conclusion"
date: 2018-09-02 07:10:00 date: 2018-09-02 07:10:00
author: Daniel author: Daniel
categories: categories:
- [ Programming, Go ]
- [ Programming, JavaScript ]
- [ Projects, myPrayerJournal ] - [ Projects, myPrayerJournal ]
- [ Series, A Tour of myPrayerJournal ] - [ Series, A Tour of myPrayerJournal ]
tags: tags:
- documentation - bootstrap
- github - bundle
- https - community
- jekyll - css
- lets encrypt - element ui
- liquid - flexbox
- go
- golang
- grid
- html
- jquery
- lodash
- markdown - markdown
- subdomain - moment
- tree-shaking
- vue
- webpack
- writing
--- ---
_NOTES:_ _NOTE: This is the final post of an 8-post series; see [the introduction][intro] for all of them, and the requirements for which this software was built._
- _This is the final post of an 8-post series; see [the introduction][intro] for all of them, and the requirements for which this software was built._
- _Links that start with the text "mpj:" are links to the 1.0.0 tag (1.0 release) of myPrayerJournal, unless otherwise noted._
Over the course of this tour, we've meandered through client side code, server side code, a database, and documentation. However, the experience of developing an application is usually more than just the sum of the assembled technologies and techniques. Let's take a look at some of these "lessons learned" and opinions formed through this process. (This post will use the first-person singular pronouns "I"/"me"/"my" a lot more than the previous ones.) Over the course of this tour, we've meandered through client side code, server side code, a database, and documentation. However, the experience of developing an application is more than just the sum of the assembled technologies and techniques. Let's take a look at some of these "lessons learned" and opinions formed through this process. (This post will use the first-person singular pronouns "I" / "me" / "my" a lot more than the previous ones.)
## Vue Is Awesome - But... ## Vue Is Awesome -- But...
As I tried different <abbr title="Single Page Application">SPA</abbr> frameworks, they were interesting and fun, but a lot more work than I expected. Then, I came across [Vue][], and its paradigm and flow just clicked. Single file components are great; it was so nice to not have to go digging through a site-wide CSS file looking for styles that affected the elements in the component. I just had to scroll down! While I did put the common CSS in `App.vue`, the application's top component, anything unique that component did was right there. There are also all kinds of Vue-aware packages that you can add and use, that add their own elements/components to the process; [Element UI][], [Bootstrap Vue][], and [Vue-Awesome][] were three of the ones I used at different points in development. Also, as it's a JavaScript framework, we used [moment.js][] to display relative dates ("last activity 8 minutes ago") and format dates for display. As I tried different <abbr title="Single Page Application">SPA</abbr> frameworks, they were interesting and fun, but a lot more work than I expected. Then, I came across [Vue][], and its paradigm and flow just clicked. Single file components are great; it was so nice to not have to go digging through a site-wide CSS file looking for styles that affected the elements in the component. I just had to scroll down! While I did put the common CSS in `App.vue`, the application's top component, anything unique that component did was right there. There are also all kinds of Vue-aware packages that you can add and use, that add their own elements/components to the process; [Element UI][], [Bootstrap Vue][], and [Vue-Awesome][] were three of the ones I used at different points in development. Since it's a JavaScript framework, you can use vanilla JS packages as well; myPrayerJournal uses [moment.js][] to display relative dates ("last activity 8 minutes ago") and format dates for display.
Then... I ran the build process, and the bundles were huge - as in, multiple megabytes huge! We changed our implementation of Vue-Awesome to only import the icons we used in the application; to be fair to them, that is the project's recommendation. Element also seemed to be rather heavy. One of the last issues I worked before final release was removing Bootstrap Vue and just using straight HTML/CSS for layout and flow (which is another lesson we'll explore below). There are guides on configuring [Webpack][] to help make moment's bundle smaller (and that project has an open issue to refactor so that it's more friendly to a "just import the part you need" paradigm). Then... I ran the build process, and the bundles were huge -- as in, multiple megabytes huge! We changed our implementation of Vue-Awesome to only import the icons we used in the application (to be fair to them, that is the project's recommendation). Element also seemed to be rather heavy. One of the last issues I worked before final release was removing Bootstrap Vue and just using straight HTML/CSS for layout and flow (which is another lesson we'll explore below). There are guides on configuring [Webpack][] to help make moment's bundle smaller (and that project has an open issue to refactor so that it's more friendly to a "just import the part you need" paradigm).
None of this is meant as a knock of any of the fine projects I've named up to this point. It was also near the end of the project when I converted to the Vue CLI v3 template, which uses a version of Webpack that has a much better "tree-shaking" algorithm. (This means that, if it can establish that code is never executed, it excludes it from the bundle.) myPrayerJournal v1.0's modern "vendor" bundle (the one with the libraries) is 283K, while the legacy bundle is 307K; while that's not lightning fast on mobile, it's also comparable to a lot of other sites, and since page updates happen through the API, it is fast once it's loaded.<a href="#note-1"><sup>1</sup></a> None of this is meant as a knock of any of the fine projects I've named up to this point. It was also near the end of the project when I converted to the Vue CLI v3 template, which uses a version of Webpack that has a much better "tree-shaking" algorithm. (This means that, if it can establish that code is never executed, it excludes it from the bundle.) myPrayerJournal v1.0's modern "vendor" bundle (the one with the libraries) is 283K, while the legacy bundle is 307K; while that's not lightning fast on mobile, it's also comparable to a lot of other sites, and since page updates happen through the API, it is fast once it's loaded.<a href="#note-1"><sup>1</sup></a>
@ -53,9 +63,9 @@ I used the last one quite a bit. I also extensively referred to [CSS Tricks' "A
## Learn Go ## Learn Go
> Ladies and gentlemen of the Internet class of 2018 - > Ladies and gentlemen of the Internet class of 2018 -
> Learn Go. > &nbsp; Learn Go.
> If I could offer you only one tip for the future, > If I could offer you only one tip for the future,
> Go would be it. > &nbsp; Go would be it.
> -- [with apologies to Baz Luhrmann][ws] > -- [with apologies to Baz Luhrmann][ws]
[Go][] is a systems programming language. It was developed at Google, to help them better utilize their hardware. It natively supports concurrent processing (which can be done in parallel, but is distinct from "parallel programming"); has an opinionated code formatter; forces you to address calls that may error; and is terribly efficient. When myPrayerJournal was running with the Go backend, the working size in RAM was around 10MB. Let me say that again, this time with feeling - **the working size for a database-accessing, HTTP-listening, dynamic web service was 10MB of RAM!** If you have ever profiled a web server process, you know that it's nearly ludicrous how small this is. For comparison, the process working set for the F#/Giraffe/EF Core version of the backend runs between 60-80MB, and includes another ~256MB of shared working set memory.<a href="note-2"><sup>2</sup></a> (An Apache2 process running PHP can run in the 256MB range as well.) [Go][] is a systems programming language. It was developed at Google, to help them better utilize their hardware. It natively supports concurrent processing (which can be done in parallel, but is distinct from "parallel programming"); has an opinionated code formatter; forces you to address calls that may error; and is terribly efficient. When myPrayerJournal was running with the Go backend, the working size in RAM was around 10MB. Let me say that again, this time with feeling - **the working size for a database-accessing, HTTP-listening, dynamic web service was 10MB of RAM!** If you have ever profiled a web server process, you know that it's nearly ludicrous how small this is. For comparison, the process working set for the F#/Giraffe/EF Core version of the backend runs between 60-80MB, and includes another ~256MB of shared working set memory.<a href="note-2"><sup>2</sup></a> (An Apache2 process running PHP can run in the 256MB range as well.)
@ -68,13 +78,21 @@ I also found the development process awkward, though not unwieldy. _(They're pro
**Lesson**: Learn Go. **Lesson**: Learn Go.
## Write about Your Code
This wasn't a lesson I learned on this project; this was one I'd known for a while. There are _(at least)_ two distinct benefits to writing about your code:
- It can help you learn even more than you may have learned when you were writing the code itself. As developers, we sometimes forget to step back and look at the body of work we've created. If you write about it, you have to form a coherent view about it so you can explain it to others; this helps you long-term. Also, people who know more about the environment can chime in on what you've written, which also not only helps you learn, ...
- It helps build community. If you hit a snag, and someone in the community around that technology helps you get past it, writing about your experience means that the next person to encounter that issue may not have to ask; if their searching leads them to your post, they can fix it and move on. This applies doubly if you could **not** get help from the community; you might be the one who surfaces this issue/technique, and moves the entire community forward.
**Lesson**: Write about your code; participate in the community around your technology to whatever extent you are able.
<p>&nbsp;</p> <p>&nbsp;</p>
If you've been with us for this entire tour -- thank you. I hope you've learned something; I know I have, not just through the development of [myPrayerJournal][], but through the course of writing about it. And, certainly, if you feel that this application could help you in any way, help yourself. It is and will always be free, and [Bit Badger Solutions][bbs] (and DJS Consulting before it) has, as of this writing, a 14-year streak of no known data breaches; your prayer requests are safe with us. If you've been with us for this entire tour -- thank you. I hope you've learned something; I know I have, not just through the development of [myPrayerJournal][], but through the course of writing about it. And, certainly, if you feel that this application could help you in any way, help yourself. It is and will always be free, and [Bit Badger Solutions][bbs] (and DJS Consulting before it) has, as of this writing, a 14-year streak of no known data breaches; your prayer requests are safe with us.
--- ---
<a name="note-1"><sup>1</sup></a> _There are chunk-splitting techniques that can be used to make the initial download smaller, and have the other "chunks" be loaded on-demand. The moment.js portion, for example, isn't needed for the default "Welcome to myPrayerJournal" page. With caching, we could defer that loading until the user has logged in; the journal page definitely needs it. Performance tweak opportunities exist, but 283K is just above the 244K suggested bundle size, so we went forward with it._ <a name="note-1"><sup>1</sup></a> _There are chunk-splitting techniques that can be used to make the initial download smaller, and load other portions on-demand. Moment.js, for example, isn't needed for the default "Welcome to myPrayerJournal" page. We could defer loading that until the user has logged in, as the journal page definitely needs it; we'd still have to download the same amount, but it would be spread out across 2 requests. Opportunities to save some size in the initial download are still out there, but 283K is just above the 244K suggested bundle size, so we went forward with it._
<a name="note-2"><sup>2</sup></a> _The server on which I host myPrayerJournal already has other .NET Core processes running on it, so the shared memory size has already been allocated._ <a name="note-2"><sup>2</sup></a> _The server on which I host myPrayerJournal already has other .NET Core processes running on it, so the shared memory size has already been allocated._

View File

@ -36,9 +36,7 @@ Recently, we released version 1.0 of [myPrayerJournal][], a minimalistic prayer
- **[Part 4: Authentication][part4]** - Auth0, using information in both app and API - **[Part 4: Authentication][part4]** - Auth0, using information in both app and API
- **[Part 5: The Data Store][part5]** - EF Core backed by PostgreSQL, with the `DbContext` defined in F# - **[Part 5: The Data Store][part5]** - EF Core backed by PostgreSQL, with the `DbContext` defined in F#
- **[Part 6: Documentation][part6]** - GitHub Pages generated on each commit - **[Part 6: Documentation][part6]** - GitHub Pages generated on each commit
- **Part 7: Conclusion** - Lessons learned and opinions based on the development experience - **[Part 7: Conclusion][part7]** - Lessons learned and opinions based on the development experience
_(these will be linked once each post has been published)_
From a technical perspective, this application was going to be a learning experience. We knew we wanted to use a Single Page Application (SPA) framework with an API; we'd built APIs before, but had yet to build a SPA. For front-end frameworks, we started with [Angular][], went through [Aurelia][] and [Elm][], then decided on [Vue][]. For the back-end API, we started with [Suave][], then went live on [Node.js][] with [Koa][]; later, we moved it to [Go][], and after .NET Core 2.1 was released, landed on [Giraffe][]. The "learning experience" part was a success; through all these attempts, we utilized 5 different languages and 3 different database access techniques. From a technical perspective, this application was going to be a learning experience. We knew we wanted to use a Single Page Application (SPA) framework with an API; we'd built APIs before, but had yet to build a SPA. For front-end frameworks, we started with [Angular][], went through [Aurelia][] and [Elm][], then decided on [Vue][]. For the back-end API, we started with [Suave][], then went live on [Node.js][] with [Koa][]; later, we moved it to [Go][], and after .NET Core 2.1 was released, landed on [Giraffe][]. The "learning experience" part was a success; through all these attempts, we utilized 5 different languages and 3 different database access techniques.
@ -66,6 +64,7 @@ Armed with these requirements, we will pick up next time with a look at the Vue
[part4]: /2018/a-tour-of-myprayerjournal/authentication.html "A Tour of myPrayerJournal: Authentication | The Bit Badger Blog" [part4]: /2018/a-tour-of-myprayerjournal/authentication.html "A Tour of myPrayerJournal: Authentication | The Bit Badger Blog"
[part5]: /2018/a-tour-of-myprayerjournal/the-data-store.html "A Tour of myPrayerJournal: The Data Store | The Bit Badger Blog" [part5]: /2018/a-tour-of-myprayerjournal/the-data-store.html "A Tour of myPrayerJournal: The Data Store | The Bit Badger Blog"
[part6]: /2018/a-tour-of-myprayerjournal/documentation.html "A Tour of myPrayerJournal: Documentation | The Bit Badger Blog" [part6]: /2018/a-tour-of-myprayerjournal/documentation.html "A Tour of myPrayerJournal: Documentation | The Bit Badger Blog"
[part7]: /2018/a-tour-of-myprayerjournal/conclusion.html "A Tour of myPrayerJournal: Conclusion | The Bit Badger Blog"
[Angular]: https://angular.io [Angular]: https://angular.io
[Aurelia]: https://aurelia.io [Aurelia]: https://aurelia.io
[Elm]: http://elm-lang.org [Elm]: http://elm-lang.org