Nullable columns or jsonb for storing user profile?
You can use "best of both worlds". Implement every regular column you know of as dedicated column (with exact proper data type, possibly with NOT NULL / CHECK / PK / FK etc. constraints to enforce detailed rules, default values and comment for documentation) and add a "catch-all" jsonb column for very rare cases / later additions / highly volatile attributes that do not need any of the features mentioned above.

To be clear: "highly volatile" does not mean the value is updated a lot, which would clearly speak against any document type like jsonb, making updates more complex and expensive. It means the attribute per se (on the meta level) changes a lot (different names, rare and and pops in and out of existence over time or similar).

Most people underestimate how cheap NULL storage really is:


Do nullable columns occupy additional space in PostgreSQL?
Measure the size of a PostgreSQL table row


Related:


Does it make sense to store a couple of Boolean values as array?
Is there a name for this database structure?
jsonb and primary/foreign keys: which performs better in PostgreSQL?
Does JSONB make PostgreSQL arrays useless?