Led by Stephen Milne, who kicked four first-half goals in his 200th game, the Saints built a 37-point lead halfway through the third term and held on to win 12.13 (85) to 10.7 (67).
Fremantle mounted a courageous late challenge, kicking five of the last six goals, but the Saints wouldn’t be denied, cementing themselves in the top three ahead of their mid-season bye.
Milne didn’t kick a goal after half-time, but his four first-half majors were important in a low-scoring clash.
Goddard was also superb for the visitors, winning 20 of his 33 possessions as a loose defender in the first half, and moving into the midfield to have an impact at the stoppages in the second.
The star playmaker was able to position himself in front of Matthew Pavlich, and alongside Sam Fisher the Saints didn’t concede a single scoring shot to the Freo skipper in the first half.
With Pavlich well held, Hayden Ballantyne shaped as Fremantle’s most dangerous weapon, but the goalsneak missed a number of opportunities, finishing with 2.3 and five inside 50s from his 19 possessions.
Michael Barlow (26 possessions) continued his stellar debut season, while Aaron Sandilands (42 hit-outs and five clearances) got his regular numbers, but Fremantle had to commit to shutting down the Saints’ star midfielders and was constantly on the back foot.
Adam McPhee restricted Lenny Hayes’ influence, while Ryan Crowley did the same to Leigh Montagna in the first half, but the Saints continued to get drive from their back half.
Up forward, the visitors were well served by Justin Koschitzke, who beat opponent Antoni Grover and finished with two goals and 17 possessions in an impressive display.
Fremantle travels to face Carlton next week having lost consecutive matches for the first time this season.
Fremantle 2.1 4.5 7.6 10.7 (67)
St Kilda 4.2 8.6 11.7 12.13 (85)
GOALS
Fremantle: Morabito 2, Ballantyne 2, Barlow, Bradley, Fyfe, Pavlich, Duffield, Hasleby
St Kilda: Milne 4, Koschitzke 2, Schneider 2 McQualter, Gardiner, Jones, Gilbert
BEST
Fremantle: Ballantyne, Barlow, McPhee, Mundy, Sandilands, Tarrant
St Kilda: Goddard, Milne, Fisher, Gilbert, Dal Santo, Koschitzke, Ray
INJURIES
Fremantle: Palmer (ankle) replaced in selected side by Hasleby, van Berlo (ankle)
St Kilda: Clarke (hamstring)
Reports: Justin Koschitzke (St Kilda) for striking Ryan Crowley
Umpires: Margetts, Rosebury, Findlay
Official crowd: 37,569 at Subiaco Oval