A largely forgettable game finally came to life in the 70th minute, Zaniolo angling a right-footed shot beyond Iker Casillas to put the Serie A side on their way to a first win over Porto in European competition.
Edin Dzeko created the opener and was also involved in the second too, his low drive striking the post before his team-mate tucked home the rebound.
Teenager Zaniolo's brace gives Roma a lead to take into the return fixture next month, though Adrian Lopez's half-volleyed finish from Tiquinho Soares' accidental assist means Porto picked up what could be a crucial away goal.
There was little sign of the drama to come in a sedate first-half, even with the dangerous Dzeko hitting the woodwork shortly before the break.
The striker's superb piece of control to kill a long pass allowed him to cut inside from Roma's left channel, bringing the ball onto his stronger right foot, but he thumped his drive against the near post.
Lorenzo Pellegrini had earlier fired tamely at goalkeeper Casillas from the edge of the penalty area, while Porto's solitary attempt in the first 45 minutes saw Fernando force Antonio Mirante - deputising for the injured Robin Olsen, who was only on the bench – into a low save to his left.
Bryan Cristante worked Casillas with a rising drive early in the second half, but Roma's fire appeared to have fizzled out until Zaniolo struck, his initial poor touch inadvertently setting him up to shoot across Porto's veteran goalkeeper.
The midfielder's second - turned in with his left foot as the ball broke kindly into his path - delighted an otherwise nervy Stadio Olimpico crowd, though they fell silent soon after when Soares' attempt at an ambitious volley ended up setting up substitute Lopez.
All of us before watching Zaniolo play— AS Roma English (@ASRomaEN) February 12, 2019
after watching him play pic.twitter.com/d00xTcp4Iy
What does it mean? Di Francesco gets much-needed boost
A positive result at home was just what Roma boss Eusebio Di Francesco needed, with the club's vocal fans still unhappy prior to kick-off following the 7-1 Coppa Italia humiliation to Fiorentina at the end of January.
They watched their team huff and puff to little effect until Zaniolo found the net twice in the space of six minutes, albeit conceding has left the tie in the balance.
As for Porto, they will just be pleased to still be alive going into the return fixture of their last-16 clash this year. A year ago, they were thrashed 5-0 at home by Liverpool in the first leg.
E-din shoulders above the rest
Zaniolo took centre stage with his brace, yet Dzeko was the architect for both goals during a performance that demonstrated just how crucial he is to a Roma side suffering with fragile confidence. He will feel unlucky not to have scored, denied twice by the woodwork.
Pepe caught out
Signed in January to add experience to the squad, Pepe knows exactly what it takes to win in Europe following his successes with Real Madrid in previous years. However, the veteran centre-back was bullied by Dzeko in the build-up to Roma's first before his failure to react quickly to the deflection off the post allowed Zaniolo to double the lead.
Key Opta Facts
- Roma have won eight of their last nine Champions League home matches (L1), conceding just five goals in the process.
- Porto are winless in their last six Champions League knockout matches (D1 L5).
- Dzeko has been directly involved in more Champions League goals than any other Roma player this season (5 goals, 3 assists).
- Zaniolo is the second youngest (19y 225d) player to score a brace in a Champions League knockout match behind Kylian Mbappe in April 2017 for Monaco (18y 113d).
- Casillas has appeared in the Champions League knockout stage for the 18th different season, at least three more than any other player.
Before the teams meet again on March 6, Roma take on Bologna and Frosinone ahead of a pivotal derby against city rivals Lazio. As for Porto, they host Vitoria Setubal next and have the small matter of a home game against Benfica before the return leg in Lisbon.