100% of these suggestions are based on recent & relevant real world experience. We have, at least at one point, tried to use these patterns on our own & witnessed how the decision played out over years in production.
- K.I.S.S. - Less code > more code. No code > less code. KISS principle - Wikipedia
- M.V.C. Model–view–controller - Wikipedia )
- O.O.P Object-oriented programming - Wikipedia
- Single Responsibility Principal Single responsibility principle - Wikipedia
- Conway’s law - Wikipedia
- On Writing Software Well - Signal v. Noise (few hours of video here)
- Data should only be loaded in two places. No N +1, Eager Loading is good.
- Controller
- Asynchronous Worker
- 1 database hit per Table, per request.
- 1GB Dyno WEB_CONCURRENCY=4, 256MB < Awesome
- 256MB < Good
- 256MB-400MB Average
- +400MB Bad
“Shape” of memory over time
- Bloat - log function
- Leak - linear function
- Time - “leak” over 24 hrs or more?
max memory allocations
- < 200 k
- 80% of an applications work will happen in 20% of its code
- Only optimize largest bottlenecks
- Share both pre and post production metrics.
- https://www.speedshop.co/2015/10/15/ruby-app-performance-with-new-relic.html
- RESTful Resources OK
resources :investments, only: [:edit, :show] do`
resources :investment_payments, only: [:create, :new, :edit]
resources :subscription_agreements, only: [:index]
end
resources :photos, only: [:show, :create, :update, :destroy], controller:'images'
resources :fa_investors, only: [:update]
resources :manual_ach_infos, except: [:destroy]
resources :ach_auths, only: [:update]
resources :investor_payment_methods, only: [:new, :create, :update]
NOT OK
get 'payment_auth_edit_modal/:id', to: 'dashboard#payment_auth_edit_modal'
get 'edit_user/:id', to: 'dashboard#edit_user_modal'
get 'projects_metrics', to: 'dashboard#projects_metrics'
post 'projects_metrics', to: 'dashboard#projects_metrics', as: 'project_metrics_post'
get 'loan_metrics', to: 'dashboard#loan_metrics'
get 'brokers', to: 'dashboard#broker_applications'
- NO LOGIC IN THE CONTROLLER.
- REST & Single Responsibility *How DHH organizes his Rails controllers - Jerome’s Adventures in Software
- Logic in Models. Once Model hits line limit we can start abstracting.
- NOTHING THAT TRIGGERS A DATABASE CALL IN THE MODEL. 3 ActiveRecord Mistakes That Slow Down Rails Apps: Count, Where and Present
- Single responsibility.
- ’Service objects’ to keep 3rd party references out of the code. If we want to change a 3rd party service all code specific to that service should be in 1 place.
- Times when single responsibility needs to be violated. We put this type of “service object” in the support folder. (open to suggestions for improvement)
- Sidekiq worker is like a controller. No business logic in sidekiq worker.
- If you are writing asynchronous code with sidekiq you should know the documentation Home · mperham/sidekiq Wiki · GitHub
- Keeping jobs small, spacing them out. Sidekiq Best Practices – Nuts & Bolts – Medium
- Idempotency https://en.wikipedia.org/wiki/Idempotence
- Should be avoided whenever possible
- Always to be discussed during code reviews.
- Add serious complexity to debugging process.
- Commonly relied upon when common principals have been ignored.
- Rollback Database transaction when callback fails. (not sure if in rails 6)
- We have used callbacks successfully when we need to bind a certain slightly related 3rd party action to a certain event. even when working from the console.
- If gem that is not already being used, should be discussed with team.
- Support level, License, Ease of use, Risks.
- 100ms-2s Fast
- 2s - 4s Average
- 4s+ BAD
- 1MB < Good
- 1MB-2MB Average
- 2MB+ BAD
Here is a sass style guide to follow. https://css-tricks.com/sass-style-guide/
For PNG compression use ImageAlpha Settings can be adjusted by eye but “Median Cut(pngquant) at 256 is generally fine and will save you a bunch of bytes. The less colors in the image the more you can compress it.
For JPGS compression use 2 steps:
- Use save for web in Photoshop (command + option + shift + s) and set the quality to 60.
- Use ImageOptim to really crunch the image. In preferences,
- select strip JPEG metadata
- set optimization speed to “Insane”
- For @2x images set quality to 40%
- For @1x images set quality to 80%