Skip to content

Sample task/time-tracking web-app to evaluate Snowpack (build, dev), React (reactive UI), Chakra (UI component lib), Prisma (typed DB query builder), grant (auth)

License

Notifications You must be signed in to change notification settings

vogler/tasktime-2021

Repository files navigation

tasktime_snowpack-react-chakra-prisma

Demo: https://vogler-track-time.herokuapp.com

This is a test project building some todo/time-tracking app using:

  • Snowpack as a fast build tool (instead of webpack, Parcel)
  • React for a reactive UI
    • Recoil
      • to avoid re-render of non-running timers (value-dependent dependency via selectorFamily)
      • to avoid re-mount of InputForm while adding a new item (decouple state from component tree)
    • react-router for routing in the browser (routes are redirected to / by the server)
  • chakra-ui as UI component library
  • Prisma as ORM (instead of TypeORM which I had some issues [1] [2] with in https://github.com/vogler/syncmine)
    • PostgreSQL (or sqlite etc.) as database
    • missing some values/types, no trees, see notes below
  • grant for OAuth with google; requires little code, dynamic json config. Discarded alternatives:
    • auth0 free plan has 7k users and 2 social connections; their React example uses hook, so page first loads, then checks auth and then loads rest -> too many round trips (same as with firebase)
    • passport has passport-local for username+password and normalized profile information, but requires way too much code

Tried Svelte and Firebase in an older iteration: https://github.com/vogler/tasktime_svelte-firebase. By now Svelte seems to officially support TypeScript: https://svelte.dev/blog/svelte-and-typescript.

Setup

Run npm install. If you want to use sqlite instead of PostgreSQL, edit backend/schema.prisma.

  • setup DB: brew install postgresql && brew services start postgresql && createdb tasktime
  • set DATABASE_URL, e.g. create .env file with DATABASE_URL = 'postgresql://user@localhost:5432/tasktime'
  • setup tables: npm run db-push

Use npm start to start the server with reload on changes and HMR via snowpack. For production see heroku.com example in Procfile.

Notes

SSR

Maybe check out Next.js for easier SSR; example: https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-nextjs-api-routes

DRY: server+client API from schema

Seems strange that there is no framework/library that only requires the database schema and automatically provides an API on the server for it. Also, no one seems to care about duplication. GraphQL just introduces more boilerplate for little benefit compared to just calling database functions on the client (can also select subset of fields to save data; authentication/authorization can be a middleware on the server, just need some access annotations for the schema). Use row-level security in PostgreSQL for authorization and https://jwt.io to authenticate API requests as in PostgREST's auth? Would need to CREATE ROLE for every user?

Was not happy with

Based on the generated code from Prisma, we define a generic server endpoint /db/:model/:action and a generic db object on the client that has Prisma's types but just relays the call to the server.

Prisma

Typescript

FP/types/meta:

Performance

Before adding auth, Chrome Dev Tools' network tab said ~300ms/350ms for DOM/Load in incognito mode with npm start (snowpack dev), and ~600ms in normal mode.

Noticed that the longer time was due to extensions (Surfingkeys, React dev tools, others?) -> only measure in incognito mode.

After adding auth, not logged in, at 350ms/360ms. Can see in waterfall that it's due to pending websocket request to hmr-client.js -- strange that affects load time despite staying open forever.

With npm run start-prod at 200ms/206ms (no bundler yet) -> no more hmr-client.

Seems like favicon.ico (and manifest.webmanifest only when not in incognito) are loaded after load is done. However, last request is started at 120ms and done in 8ms, but then there's nothing in the waterfall and result is 208ms/213ms -> not changed by removing favicon.ico/manifest.webmanifest.

https://web.dev/measure for https://vogler-track-time.herokuapp.com performance 40, accessibility 85, best practices 100, SEO 100.

First Contentful Paint 5.2 s, Time to Interactive 8.8 s, Speed Index 10.1 s
Estimated Savings: Enable text compression: 4.2 s (@chakra-ui/react.js 555.9 KB / 731.4 KB), Remove unused JavaScript 3.6 s, Use HTTP/2 2.91 s, Minify JavaScript 1.95 s

Load time >= with compression. Probably because it re-compresses every time. With shrink-ray 791 kB -> 740 kB transferred (both 460 kB with cache). Did not compile on heroku when installing via ssh, but then worked on automatic deploy. Encoding is br for bigger files.

Bundlers: bundle, but don't minify for now since we replace variables on the server. Values from dev tools with 'disable cache'. First row is not logged in, second is logged in.

bundle transferred resources finish DOMContentLoaded Load
none
dev
861 kB
940 kB
4.1 MB
4.7 MB
190 ms
1.60 s
351 ms
1.25 s
366 ms
1.61 s
none
build
250 kB
287 kB
1.1 MB
1.3 MB
126 ms
327 ms
201 ms
275 ms
206 ms
334 ms
esbuild
es2018
208 kB
213 kB
1.1 MB
1.1 MB
59 ms
279 ms
183 ms
258 ms
196 ms
366 ms
webpack

https://web.dev/measure with esbuild es2018:

First Contentful Paint 2.2 s, Time to Interactive 2.7 s, Speed Index 4.2 s
Estimated Savings: Remove unused JavaScript: 0.75 s, Reduce initial server response time: 0.7 s, Minify JavaScript: 0.3 s

✨ Bootstrapped with Create Snowpack App (CSA).

npx create-snowpack-app tasktime_snowpack-react-chakra-prisma --template @snowpack/app-template-react-typescript

Available Scripts

npm start

Runs the app in the development mode. Open http://localhost:8080 to view it in the browser.

The page will reload if you make edits. You will also see any lint errors in the console.

npm run build

Builds a static copy of your site to the build/ folder. Your app is ready to be deployed!

For the best production performance: Add a build bundler plugin like "@snowpack/plugin-webpack" to your snowpack.config.js config file.

About

Sample task/time-tracking web-app to evaluate Snowpack (build, dev), React (reactive UI), Chakra (UI component lib), Prisma (typed DB query builder), grant (auth)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published