On this page
Blog

The 30-second test: what senior clients check on your portfolio

13 min readUpdated Oct 11, 2026

A silver stopwatch lying on a dark wooden surface

I have never run a session recorder on selim.services, and for most of this site’s life it carried no analytics at all. So I cannot tell you what any individual visitor did on it, and a post about how people read a page should say that in the first paragraph rather than the last.

What is measured - by someone else, on a much larger sample than I will ever have - is the shape of the behaviour. Jakob Nielsen’s How Long Do Users Stay on Web Pages? (Nielsen Norman Group, 2011) found that page visits follow a Weibull distribution with negative aging. The practical translation: the first ten seconds decide whether a visitor stays at all, the rate at which people leave drops sharply once they get past roughly half a minute, and the average visit lasts a little under a minute. “To gain several minutes of user attention, you must clearly communicate your value proposition within 10 seconds.”[1] The 30 seconds in the title is that threshold. It is not a metaphor, and it is not a number I timed.

Everything after this paragraph is judgement, not measurement, and it comes from a specific place: I sell development work, the people who hire me land on this page before they message me, and I have rebuilt it more than once to be read by someone doing exactly that. This post is the checklist I apply to my own portfolio and to the ones I get asked to look at. Where I claim something about what reviewers do, read it as an argument you can disagree with, and check it against your own inbound before you act on it.

It is targeted at the audience I belong to: freelancers, indie consultants, and contract developers who own their own personal site and want it to do more work than a LinkedIn profile can.

The first paragraph above the fold is doing all the work

Most portfolios think the hero is doing the work. The hero is not doing the work. The hero is the title bar of a window the visitor has not yet decided to read. A name and a job title prove nothing. “Senior Full Stack Developer” is a phrase a junior can also type.

What gets read is the first paragraph that contains a number. “Three years of production TypeScript”, “30 sites”, “Hono and Postgres on Hetzner”, “Vue, Nuxt, Tailwind, Cloudflare”. Numbers are how a senior reviewer checks reality, because numbers are falsifiable. They can open GitHub and verify the count. They can read a project repo and verify the stack. They cannot verify “passionate about clean code”. One sentence is doing 80% of the credibility work above the fold, and it is almost never the one the portfolio owner thinks it is.

The writing rule that follows from this is brutal: the first sentence on your page should be the one that contains the most checkable facts about your work. Not the warmest, not the cleverest, not the most narrative. The most checkable. If your hero says “I build modern web applications with care”, delete it and replace it with the sentence two paragraphs down that lists the actual stack and years of experience. Then delete the two paragraphs.

The stack list has to be falsifiable, or it is a tell

The stack list is the second thing that gets scanned. It is also the section where most senior reviewers form their first hard opinion, because the stack list is where credibility gets cheap.

“Full-stack JavaScript developer” is not a stack list. It is a job title pretending to be a stack list. It is unfalsifiable. A junior who has shipped one Next.js project can write that line. A senior who has shipped a hundred can also write that line. The line tells the reviewer nothing.

“Vue, Nuxt, Hono, Postgres, Drizzle, Cloudflare, Hetzner, Docker” is a stack list. It is falsifiable in two clicks. Open my GitHub. The repos either contain those technologies or they do not. The list is a contract. If you list Postgres and your only public projects use SQLite, the contract is broken and the visitor will spot it.

Specificity does the trick that buzzwords cannot. “Hetzner” is a higher-trust word than “Cloud” because almost nobody puts it in a portfolio unless they actually pay a Hetzner invoice. “Drizzle” is a higher-trust word than “ORM” for the same reason. The more specific your list, the more it reads as the inventory of a working professional, and the less it reads as a sales sheet. The rule is simple: the list on the page should match the dependencies in the repos, and a senior reviewer can tell when it does not.

The first project card is the entire portfolio

Senior reviewers do not read the project list. They look at the first card. If the first card answers two questions in two seconds - what is this and is it real - they may glance at the second. If the first card fails, the rest of the grid is invisible.

The two questions the card has to answer are not abstract. The name has to describe the project in roughly five words. “Meme template editor for designers” is a name. “Project Phoenix” is not a name, it is a code word. The visitor has no context for your internal naming conventions. Ship the description in the title.

The screenshot has to be a real screenshot of the live product, not a Figma mockup, not a stylized device frame floating in a gradient. Mockups read as marketing. Marketing reads as “this thing does not exist or is not finished”. A flat screenshot of the actual UI reads as “this is shipped”. The difference is enormous and almost nobody who ships their first portfolio gets it right.

The link has to open a live thing. Not a 404. Not a “coming soon”. Not a GitHub README with no demo URL. If the project is dead, do not list it. If the project is live but private, replace the link with a screenshot gallery and say so. A 404 on a portfolio link is the single fastest way to lose a senior reviewer, because it converts a credibility question into a settled answer.

Senior reviewers open DevTools

This is the part of the test that almost no portfolio owner accounts for, because the portfolio owner is not the visitor.

A senior developer reviewing a senior contractor opens DevTools. Sometimes for two seconds, sometimes for ten, but they open it. They are not running a code review. They are checking five things in parallel, and they are checking them fast.

They glance at the Network tab to see bundle weight and request count. A 4MB hero image on a personal site is a tell. A page that loads 60 third-party scripts is a tell. They open Console to see if there are red errors on a static page. There should not be any; if there are, they were left there by someone who does not check their own work. They look at the Elements panel for the structure - whether the markup is semantic or a wall of divs, whether the headings nest correctly, whether <html> has a lang attribute. On a multilingual site they specifically look for hreflang links, because the absence of them on a site that ships in two languages is diagnostic of a developer who never ran their own SEO audit.

They check Lighthouse, or at least eyeball the metrics they would expect Lighthouse to surface. The two web.dev articles on Largest Contentful Paint and Cumulative Layout Shift describe the two numbers that show up most in casual pre-engagement reviews, because they are the two numbers a visitor can feel without measuring.[2][3] A page that flashes content into place at 1.5 seconds and then jumps when the font loads has already lost a credibility tax that no copy can buy back.

Finally, they paste the URL into a chat. Slack, Telegram, iMessage. They want to see the OG image preview. If the preview is a default screenshot of the page, or worse, blank, the credibility tax is real. The OG image is the only piece of your portfolio the reviewer can share with a colleague, and they will not share something that previews as a blank rectangle. Tuning this is a one-hour task. Almost nobody does it.

There is also a class of portfolio that scrolljacks, animates every section into view from below, attaches a custom cursor that lags 200ms behind the real one, and lets a Lottie hero loop forever in the background. The visitor cannot articulate why they distrust the page; they can only feel that it is trying too hard. The senior tell is restraint. Motion exists to acknowledge an action - a button press, a tab change, a hover - never to entertain. A page that animates on entry is taxing the reader’s attention to perform a personality, and a senior reviewer registers it in two seconds.

What does not get looked at, and trying to message you

A surprising amount of a portfolio does not get read at all. The “About me” essay does not get read in 30 seconds, and probably not on the second visit either; the visitor is not interested in your origin story, they are interested in whether you can do their job. The testimonials block does not get read because self-curated quotes from clients you chose to highlight are advertising, not evidence. Skill percentage bars get noticed once and actively reduce credibility, because nobody who has actually shipped Vue for six years would represent that as “Vue 87%”. The giant headshot does nothing. The contact form with six fields does not get filled out. A blog with one post titled “My first blog post” damages credibility by demonstrating a project that was started and abandoned in public. This is not a minimalism argument; it is a signal-to-noise argument. The visitor only has 30 seconds of attention - spend it on the things that move the needle.

The last test inside that window is not visual. It is the visitor trying to imagine the act of contacting you. Multiple equal-weight CTAs are the most common failure: “Contact me”, “Hire me”, “Let’s chat”, “Book a call”, “Email me” - five buttons, five paths, no obvious primary. The visitor does not have to choose; they leave. The site is the resume, and the resume should make the next action obvious. One next step per surface; multiple equal-weight CTAs are a failure of nerve.

The contact form is the second-most-common failure. Six fields, a captcha, a “subject” dropdown, a 1000-character description. A senior client closing the tab in 30 seconds is not going to fill it out. They want a Telegram handle, an email address, or a marketplace profile they recognize. Every inbound conversation I can trace started in Telegram or on a marketplace, and none of them started in a contact form I built - which is weak evidence, but it is the evidence I have, and it points the same way as the mechanism: a handle converts “I might message this person” into “I am already typing in a familiar interface”. The link target matters as much as the label - hovering “Contact” and seeing /contact produces the same close-the-tab response as a 404; hovering “Telegram” and seeing https://t.me/... produces the opposite.

The senior tells, in detail

These are the things a visitor cannot articulate but registers in 1-2 seconds.

Type scale and rhythm. You do not have to be a designer to feel inconsistent spacing. A page where every section uses a slightly different padding, a slightly different heading size, and a slightly different line-height feels off without the reader knowing why. The fix is not picking better numbers; it is picking fewer numbers and reusing them everywhere.

Touch targets on mobile. A senior reviewer often arrives on mobile, especially via Telegram link. If your project cards are 28px tall and the tap accidentally hits the wrong card, you have lost the visit. The fix is a single rule: nothing tappable smaller than 44px on a side, ever.

First contentful paint. A flash of unstyled content on a portfolio is a credibility hit, because it is the kind of thing a senior reviewer assumes you would catch on your own page first. If you want the mechanism behind that rather than the metric names, I took four real sites apart and timed where the wait actually goes - almost none of it is where the standard advice points.

Dark mode that is actually tuned. The accent color usually has to change between light and dark; a hex value that reads as “calm sky blue” in light mode often reads as “neon” in dark mode. A portfolio with a dark mode that respects this small thing is doing one of the most effective credibility moves available.

i18n that reads as native. If your site ships in two languages and the second language reads as a Google Translate fallback, every Russian-speaking visitor will close the tab. The bilingual claim is a feature, not a setting. The Russian copy on this site is hand-tuned line by line and the Russian reviewers I have heard from notice it specifically; how the second locale is wired up is its own post, because the routing decision is what makes hand-tuning affordable.

The portfolios that fail the senior-tells test all fail for predictable reasons. The Bootstrap-template “Hi I am a passionate developer” page reads as “I bought a template”. The dark-plus-neon dev-influencer aesthetic - purple gradients, glow shadows, animated particles - reads as “junior trying very hard”. The Behance-style decorative animation reel - oversized illustrations, parallax everything, scroll-triggered reveals on every paragraph - reads as “wrong audience”; the visitor came to evaluate a developer and found a designer’s portfolio. The personal-brand-coach giant CTA - massive headshot, “let’s build something amazing together” in 80px type, testimonials with stock photos - reads as “this is a salesperson, not a developer”. Each of these fails for a structural reason: they fill the space with content that does not change a senior reviewer’s decision, and they crowd out the things that would.

How to test your own portfolio in 30 seconds

Hand your phone to a non-technical friend. Open the page. Ask “what does this person do, and how would you message them”. Time it. If the answer is not in 30 seconds, the page does not work. Notice that this test does not ask whether they liked it.

Run Lighthouse on mobile. Anything below 95 across performance, accessibility, best practices, and SEO is a tell on a portfolio - not because the score itself matters to a client, but because the things the score measures are exactly the things a senior reviewer notices in DevTools. A 78 on accessibility means a missing lang attribute or unlabelled buttons, and that is the kind of finding that ends an evaluation.

Paste your URL into a Telegram message and a Slack message. Look at the preview. If the OG image is a default screenshot, your share preview is doing nothing for you, and your share preview is the asset most likely to get forwarded inside a hiring team. Fix it once. It pays for itself.

Open the page on a 4G throttled connection in DevTools. Watch what happens in the first 1.5 seconds. If you see a flash, a layout shift, or a long blank screen, fix that before you write any new copy. Performance is the cheapest credibility multiplier you have access to, and the most often skipped.

Try to message yourself. Pretend you are a stranger. Count the clicks from landing to message-sent. If it is more than two, you have a problem. If it is more than three, you have lost the inbound entirely.

The reason all of these tests work is the same reason the 30-second test is the only test that matters for inbound. A portfolio for a senior contractor is not a content destination. Nobody is here to browse a gallery, read your essays, or admire your typography for its own sake. They are here to close one open question: is this person worth a message. The site is the resume; proof beats claim; one next step per surface. Those three rules survive the test because they describe what the test is actually measuring.

Long copy, dense bios, and elaborate project narratives are content for visitors you do not have. The visitor you do have will close the tab in 30 seconds unless you give them a reason not to. The reason is not a story. It is a number, a stack, a screenshot, and a single CTA that lands them in a chat with you. Build for that visitor. Cut everything that is not for them.

If you want to compare notes, my own homepage is at selim.services. It is written under the same constraint as this post: it has to survive a 30-second scan by a stranger who is about to decide whether I am real.

Sources

Every claim below about something outside this site traces to a source in this list. Where a claim could not be sourced, it was removed rather than softened.

  1. How Long Do Users Stay on Web Pages?

    Primary sourceNielsen Norman Group

    The load-bearing claim of the whole article: page visits follow a Weibull distribution with negative aging, the first 10 seconds decide whether a visitor stays, and the average visit lasts a little under a minute.

  2. Largest Contentful Paint (LCP)

    Primary sourceweb.dev, Google

    The definition of LCP and the 2.5s good threshold quoted for the green band.

  3. Cumulative Layout Shift (CLS)

    Primary sourceweb.dev, Google

    The definition of CLS and the 0.1 good threshold, and that unsized images and late-injected banners are the common causes.

New posts by email

One email when something new lands here. No schedule, no digest, no sales sequence - and you can leave from any of them.

Your address is used for these posts and nothing else.