I used to think that too, but actually no. The FROM clause is the one place where the UDF doesn't execute once per row.
Remember that a UDF in the FROM clause, even using CROSS APPLY, is a table-defined function. Therefore, it is more set-based in nature than other functions and will not evaluate per each individual record, whereas a SUM() function or an AVG() function will evaluate every time a record is passed into the database engine.
Does that help?