loess can be a time-consuming algorithm. From a
plotting perspective, though, the expensive half is usually not the model fit
but the prediction step (y values corresponding to each x).
type_loess() mitigates this in two ways.
First, the fitted model is evaluated on an equally-spaced grid of n points
spanning the data range of each group, rather than at every observation. On
large data this skips a great deal of redundant work---dozens of observations
can crowd into a single pixel, so evaluating the curve at each of them costs
time without revealing anything---while n points remain ample to trace a
smooth curve. The model is still fitted on the full dataset, so the estimates
are unchanged. It's only the points along x at which they are read off that
differ. (If the x-axis is logarithmic, the grid is spaced evenly in log(x),
so that the curve is traced evenly across the plot.)
Second, once prediction is cheap the fit itself becomes the bottleneck, and
here lowess is substituted for loess() wherever the
two are equivalent: unweighted local linear fits, without standard errors, on
a non-logarithmic x-axis. That path smooths millions of observations in
seconds. Standard errors, quadratic fits and weighted fits all fall back to
loess(), as does a logarithmic x-axis, where lowess() interpolates too
coarsely through the compressed decades.
Note that se = TRUE carries a hard ceiling of its own:
predict.loess's workspace grows quadratically in the
number of observations---regardless of how many points you predict at---and
fails outright at around 38,000. Confidence intervals are thus unavailable at
the sizes where the lowess() path matters most, and se = FALSE is
required to draw a smooth over very large data.